Appearance
Analytics Service API
Current Endpoints
GET /healthzGET /readyzGET /v1GET /v1/analytics/resultsPUT /v1/analytics/results/{attemptId}/snapshotGET /v1/analytics/weak-topicsGET /v1/analytics/exams/{examId}/summaryGET /v1/analytics/classrooms/{classroomId}/summaryGET /v1/analytics/students/{studentId}/summaryPOST /v1/analytics/eventsGET /v1/analytics/events
Native Analytics Foundation
Phase 9 starts analytics-service with event ingestion and small result projections. Public /api/analytics*, /api/students*, /api/parents*, /api/exams/*/analytics, and classroom report routes remain legacy-proxied until gateway adapters can hydrate user/classroom/exam/question details and enforce the current role checks.
Legacy evidence:
apps/api/src/modules/analytics/analytics.controller.ts:14-139maps analytics result, weak-topic, exam, classroom, student, parent, and export routes.apps/api/src/modules/analytics/analytics.service.ts:7-51delegates all analytics reads toAppDataService.apps/api/src/modules/app-data/app-data.exams-analytics.ts:173-355implementsanalyticsResultsandweakTopicsfrom graded attempts, answers, exams, classroom assignments, subjects, topics, and chapters.apps/api/src/modules/app-data/app-data.progress-overview.ts:4-317implements classroom progress, parent child listing, student progress, and parent progress by joining attempts, classroom membership, learning progress, notifications, assignments, and result visibility rules.apps/api/src/modules/progress/progress.controller.ts:11-49records lesson/video/material progress.apps/api/src/modules/app-data/app-data.learning-progress.ts:20-154clamps progress, maps status, auto-completes video at 95 percent, and upserts material views.apps/api/prisma/schema.prisma:868-923defines classroom lesson/material/video progress tables.apps/api/prisma/schema.prisma:1080-1210defines course progress, material view, video progress, andStudentMastery.apps/api/prisma/schema.prisma:2448-2534definesExamAttempt,ExamAttemptQuestion,ExamAnswer, andExamEvent.apps/web/app/teacher/analytics/page.tsx:52-53consumes/analytics/results?limit=80and/analytics/weak-topics.apps/web/app/teacher/results/page.tsx:232-261consumes filtered analytics result and weak-topic endpoints.apps/web/app/parent/dashboard/page.tsx:70-75andapps/web/app/parent/children/[id]/progress/page.tsx:28-33consume parent progress endpoints.
Native contract:
PUT /v1/analytics/results/{attemptId}/snapshotupserts an already-hydrated attempt result projection from attempt-service/gateway/backfill. Analytics-service stores references and display snapshots only; it does not query exam, attempt, user, classroom, or question databases.GET /v1/analytics/resultssupportsclassroomId,examId,subjectId,gradeLevel,topic,from,to,page, andlimit. Page defaults to1, limit defaults to20, and limit is clamped to1..100.- Result rows preserve the frontend-facing legacy shape:
attemptId,student, optionalclassroom,exam,score,correctCount,wrongCount,durationSeconds,status,submittedAt, andweakTopics. GET /v1/analytics/weak-topicsmirrors the legacy derivation from the first 100 matching analytics results: each topic in a result row incrementswrongCountandattemptCount;accuracyismax(0, 1 - wrongCount / attemptCount);shouldAlertis true whenwrongCount >= 2oraccuracy < 0.6.- Summary endpoints compute
attemptCount,averageScore,correctCount,wrongCount, and weak topics from the service-owned result projection. POST /v1/analytics/eventsrecords service-local audit/analytics events. These are not admin audit logs and do not replace admin-service ownership.- Actor/RBAC checks stay at gateway adapters for public cutover. Native endpoints accept
X-Actor-*headers for future adapters but P9-002 treats result snapshots as internal service data.
Database:
services/analytics-service/migrations/000002_analytics_foundation.sqlcreatesanalytics_attempt_resultsandanalytics_events.- Cross-service ids such as
organization_id,student_id,classroom_id,exam_id, andsubject_idare stored as public ids only. StudentMasteryremains a later rebuild/projection slice; P9-002 does not claim course mastery parity.
Gateway route rehearsal:
The default gateway route table keeps /api/analytics*, /api/exams*, /api/classrooms*, /api/students*, and /api/parents* traffic on legacy.
Use deploy/gateway/routes.analytics-read-native-example.json for Compose or deploy/gateway/routes.analytics-read-native-localhost-example.json for local go run rehearsal. The non-default table rewrites only:
GET /api/analytics/resultsto/v1/analytics/results.GET /api/analytics/weak-topicsto/v1/analytics/weak-topics.
Both routes require gateway auth, global ADMIN/TEACHER role checks, and an organization id. Snapshot/event writes, exam/classroom/student/parent analytics, classroom export, and all broad analytics/exam/classroom/student/ parent route families remain legacy-proxied until the missing adapters are explicit.
Rollback:
- Keep
/api/analytics*,/api/students*,/api/parents*,/api/exams/*/results,/api/exams/*/analytics,/api/classrooms/*/analytics, and/api/classrooms/*/report/exportrouted to legacy. - Disable gateway callers for
/v1/analytics*. - Drop analytics-service local tables with the migration down step if local test data must be reset.
Non-goals for P9-002:
- Public gateway cutover.
- Parent progress full parity.
- Classroom report export.
- Course mastery/recommendation.
- Direct joins to exam, attempt, question-bank, user, classroom, notification, or school service databases.