Commit Graph

739 Commits

Author SHA1 Message Date
86ab4e53d4 Fix practice completion lookup for progress endpoint.
Prioritize resolving lms_practices.id before falling back to question_set.id to avoid false 404 responses caused by cross-table ID collisions.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 03:36:39 -07:00
c711df68b9 Fix practice completion lookup for progress endpoint.
Accept either question-set IDs or LMS practice IDs and recognize LMS owner types so valid practice completions no longer return practice-not-found responses.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 02:57:05 -07:00
eae87b40b5 Add practice completion progress endpoint.
Expose POST /progress/practices/:id/complete so practice completions are recorded through the existing CompletePractice flow and included in learner progress tracking.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 11:20:33 -07:00
7e75d79dc8 Pass Firebase project_id explicitly from service account JSON.
Parse FCM_SERVICE_ACCOUNT_KEY, validate project_id, and provide firebase.Config{ProjectID} during FCM client initialization to prevent missing-project-id messaging failures.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 11:02:01 -07:00
4509fe2dc0 Initialize FCM client lazily during push send.
Add ensureFCMClient() so push APIs retry FCM initialization at request time and return actionable initialization errors when the service account key is empty or invalid.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 10:58:42 -07:00
23322c69cc Remove stale commented env_file lines from compose app service.
Clean up docker-compose by dropping commented env_file entries that were only used during temporary runtime-env debugging.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 10:28:12 -07:00
6f1cb24c63 Add runtime config debug logging for test push flow.
Log DB_URL alongside FCM_SERVICE_ACCOUNT_KEY during test-push requests and keep compose env-file wiring aligned with current local debug setup.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 10:25:53 -07:00
cd0ae19d03 Log FCM env value on test-push requests.
Add request-time logging in the test push endpoint so FCM_SERVICE_ACCOUNT_KEY can be verified during each API call, not only at service startup.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 09:56:45 -07:00
75353f8bdd Log FCM service account env value at startup.
Add a notification-service startup log to print FCM_SERVICE_ACCOUNT_KEY for runtime verification during push notification troubleshooting.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 09:54:22 -07:00
b2a72c2f6e Fix device registration error mapping for invalid user IDs.
Validate device registration input and translate devices_user_fk violations into a clear bad-request response so invalid auth contexts no longer return opaque 500 errors.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 08:32:42 -07:00
6a4fe68628 Add full FAQ management APIs and integration assets.
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>
2026-05-11 07:58:17 -07:00
bc2357374b Add practice-existence flags and refresh API contracts.
Expose has_practice booleans for LMS and pre-exam hierarchy entities, wire SQL/repository mappings, and regenerate SQLC/Swagger artifacts. Also update the Resend sender display name for outbound emails.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-08 11:57:11 -07:00
9da9eb77e5 fix dynamic builder runtime mapping for option responses
Allow builder-native response kinds like OPTION to resolve to DYNAMIC so schema-driven definition creation succeeds.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-08 10:56:41 -07:00
3d1b3ad9b8 dynamic question type builder completion 2026-05-08 10:12:02 -07:00
9a17f0b3c4 use descriptive top-level message for direct payments
Keep provider-specific details in data.message and return a stable, human-readable top-level success message for /payments/direct responses.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-07 09:26:07 -07:00
0983589e36 extend full-payload direct proxy flow to MPESA
Align MPESA direct payment with TELEBIRR_USSD by routing it through the provider's full checkout payload proxy endpoint for consistent gateway behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-07 09:21:43 -07:00
21ce61b910 telebirr-ussd direct payment fix 2026-05-07 09:08:43 -07:00
f906862676 partly implemented dynamic question builder + payment routes fix 2026-05-07 08:10:21 -07:00
73370633ce temporarily disabled subscription check 2026-05-06 05:10:36 -07:00
b62d89574e Include nested lesson and practice counts in exam-prep modules list response.
Return per-module lesson and practice aggregates under unit modules listing so clients can render module depth without additional queries.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-05 07:05:35 -07:00
16c3f6b613 Include nested module, lesson, and practice counts in exam-prep units list response.
Expose per-unit aggregate counts under catalog-course units listing so clients can display unit depth without extra chained requests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-05 06:35:13 -07:00
4124f98160 Include nested content counts in exam-prep catalog list response.
Add units, modules, and lessons aggregate counts per catalog course so clients can render hierarchy depth without extra API calls.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-05 06:13:01 -07:00
10954d88b0 subscription management fix + duolingo hierarchy implementation 2026-05-04 10:44:18 -07:00
eba2b87ed6 Use initial assessment description as normalized level.
Made-with: Cursor
2026-04-29 08:12:09 -07:00
60290e5c34 Swap module sort_order on conflict during update.
When updating a module sort_order to an occupied position in the same course, perform an atomic swap in a transaction instead of failing with a unique constraint error.

Made-with: Cursor
2026-04-29 03:36:45 -07:00
8430b82687 Fix partial question-set updates preserving existing values.
When PUT payload omits title, status, or shuffle_questions, reuse current persisted values so updates do not write invalid empty status values.

Made-with: Cursor
2026-04-29 03:02:13 -07:00
cdb0fa1bb3 Enforce strict initial assessment set validation.
Require INITIAL_ASSESSMENT titles to follow the Level Test A1/A2/B1/B2 format and ensure passing_score is always present on create and update.

Made-with: Cursor
2026-04-29 02:47:21 -07:00
9027b65011 Require lesson and practice completion for LMS rollups.
Update lesson and practice completion flows to cascade module/course/program progress only when both lesson completion and related published practice completion criteria are met, and align progress counters with the new rule.

Made-with: Cursor
2026-04-28 09:56:53 -07:00
8c116f4a0b GET question sets API fix 2026-04-28 09:41:09 -07:00
87bf2ed609 data loss fix 2026-04-28 09:30:48 -07:00
9cfd6c524e Allow INITIAL_ASSESSMENT question sets without owner_type and owner_id
Made-with: Cursor
2026-04-27 10:46:33 -07:00
0d02eb1a24 add MinIO media URL refresh endpoint
Add POST /api/v1/files/refresh-url to issue fresh presigned URLs from object keys, minio:// references, or stale presigned URLs so clients can refresh media links before render.

Made-with: Cursor
2026-04-27 05:25:16 -07:00
78f231f222 fix OTP verification by submitted code
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
2026-04-25 05:07:19 -07:00
526426d9f9 course practice count fix 2026-04-25 02:41:34 -07:00
5857fce9a0 count data for course 2026-04-25 02:36:52 -07:00
7e26f15bed early otp expiration fix 2026-04-25 00:16:05 -07:00
bc68326a66 fix: return sample_answer_voice_prompt and audio_correct_answer_text in question set items list
Extend GetQuestionSetItems and GetPublishedQuestionsInSet queries to match
paginated fields; map audio answer join in repository instead of nils.

Made-with: Cursor
2026-04-24 03:11:47 -07:00
33d34f0dd2 fix: map default CEFR courses to Beginner/Intermediate/Advanced programs
Seed A1-A2, B1-B2, and C1-C2 only on their matching programs; add migration
000050 for existing databases. Document mapping in domain.

Made-with: Cursor
2026-04-24 01:14:50 -07:00
5b53929d92 learning progress implementation 2026-04-23 03:58:27 -07:00
dc788c04cb updated swagger 2026-04-23 02:11:20 -07:00
6c672c4b20 static data for Courses 2026-04-23 02:07:32 -07:00
9db9c9899a module+lesson+practice implementations 2026-04-23 01:59:20 -07:00
152478a96c added program 2026-04-23 00:59:01 -07:00
9154dec067 fix: course-management practice detail without sub_module_practices row
- resolveCourseManagementPractice falls back to SUB_MODULE PRACTICE question_sets
- Synthetic practice uses id 0 and question_set_id for orphan sets
- Align GET practice and /detail with resolver; sync question_count after load

Made-with: Cursor
2026-04-21 09:59:41 -07:00
5fbca53534 fix: resolve practice by question set id; set Response flags on question-sets by-owner
- GetSubModulePracticeByID matches sub_module_practices.id or question_set_id
- Prefer primary id when both could match (ORDER BY + LIMIT 1)
- Set Success/StatusCode on practice GET/detail and GetQuestionSetsByOwner

Made-with: Cursor
2026-04-21 09:55:11 -07:00
6839d1aa0d fix: sub-module practices list excludes non-PRACTICE sets and bad Response flags
- Drop question_sets.set_type = PRACTICE filter so sub_module_practices rows list correctly
- Set Success and StatusCode on GET sub-modules/:id/practices response
- Return empty JSON array instead of null for no practices

Made-with: Cursor
2026-04-21 09:31:22 -07:00
72d1a0c3ed feat: list sub-categories by course category ID
- GET /api/v1/course-management/categories/:categoryId/sub-categories

- SQL GetCourseSubCategoriesByCategoryID; swagger refresh

Made-with: Cursor
2026-04-20 08:32:19 -07:00
de95c4d0d2 feat: practice detail API, inactive purge tracking, and related plumbing
- Add GET /api/v1/course-management/practices/:practiceId/detail with full question items

- Add migration 000040 for sub-module content inactive purge tracking

- Hierarchy queries, sqlc gen, config/app purge job, swagger refresh

Made-with: Cursor
2026-04-20 08:24:59 -07:00
90baa582be fix: load sub-module lesson by ID regardless of active flag
Course-management GET/PUT used GetSubModuleLessonByID with is_active=TRUE,
which returned no row for inactive lessons. Align with other ByID lookups
and allow admins to view and edit inactive lessons.

Made-with: Cursor
2026-04-20 00:48:13 -07:00
bbd919ca12 feat: optional include_inactive for sub-module lessons list
GET .../sub-modules/:id/lessons?include_inactive=true returns all lessons;
default remains active-only.

Made-with: Cursor
2026-04-18 03:25:28 -07:00