Introduce admin CRUD and public version check APIs for Play Store/App Store releases with force or optional update policies, and update profile dropdown seed data for countries, regions, and learner profile fields.
Co-authored-by: Cursor <cursoragent@cursor.com>
Store options in field_options with public /field-options and admin CRUD; validate learner profile values on update.
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>
Adds CRUD and preview APIs, RBAC permissions, seeded system templates, and migrates OTP email/SMS to template rendering.
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>
Expose POST /admin/roles/:role/bulk-deactivate and bulk-reactivate for platform users and team_members, mirroring deactivate/reactivate semantics and optional team member exclusions.
Co-authored-by: Cursor <cursoragent@cursor.com>
Filtering matches user profile country/region (case-insensitive trim) and derived subscription state in SQL so pagination totals stay correct.
Co-authored-by: Cursor <cursoragent@cursor.com>
Implement public FAQ read endpoints and admin CRUD with RBAC, persistence, and migrations, then regenerate Swagger and add a complete Postman collection so frontend/admin teams can integrate and validate the feature end-to-end.
Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve false OTP already used/expired responses during registration by loading OTP rows using user_id plus submitted otp code and validating usage/expiry on the matched row.
Made-with: Cursor