Introduce plan and content categories across programs and exam-prep catalog roots, wire category-aware checkout and access checks, and keep learner gating temporarily bypassed until data migration is ready.
Co-authored-by: Cursor <cursoragent@cursor.com>
Remove lesson completion from learner progress percentages, access completion snapshots, and LMS rollups while keeping generated SQLC and Swagger artifacts in sync.
Co-authored-by: Cursor <cursoragent@cursor.com>
Record playback heartbeats via POST /api/v1/videos/engagement/heartbeat and expose completion, replay, and drop-off rates on the analytics dashboard.
Co-authored-by: Cursor <cursoragent@cursor.com>
Expose user counts by education_level, occupation, learning_goal, and language_challange on GET /api/v1/analytics/dashboard.
Co-authored-by: Cursor <cursoragent@cursor.com>
Introduces invite, verify, accept, resend, and revoke flows using team_members and invitation tokens, sends the branded invitation template, and requires account activation before team login.
Co-authored-by: Cursor <cursoragent@cursor.com>
Migration 000065 adds nullable gender text column; persona API and Postman expose it alongside profile_picture.
Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce lms_personas table, repoint practice persona_id FKs off users, validate persona refs on LMS and exam-prep practice flows, personas.* RBAC permissions, and OpenAPI docs.
Co-authored-by: Cursor <cursoragent@cursor.com>
Migration 000062 adds lessons.publish_status (DRAFT default for new rows; existing rows published). Editors see all lessons; learners see published-only lists and GET by id. Sequential prerequisites and completion counts ignore drafts. Course lesson_count counts published lessons only. Swagger documents publish_status on create/update bodies.
Co-authored-by: Cursor <cursoragent@cursor.com>
Support all-time, year, year+month, and custom from/to query params with filtered metrics and time-series charts.
Co-authored-by: Cursor <cursoragent@cursor.com>