Wire the three admin Reports pages (/admin/student-performance, /admin/stats-corporate, /admin/record) to a new encoach_lms_api/controllers/reports.py that aggregates from encoach.student.attempt. * /api/reports/student-performance: per-student band averages + CEFR, with entity / level / search filters. * /api/reports/stats-corporate: by_module bar, N-month trend line, CEFR distribution pie, entity comparison bar, threshold + entity filters and meta.attempts_considered for UI. * /api/reports/record: paginated attempt history with entity / user / period filters, EX-### exam codes, duration derived from start/end. * /api/reports/filters: shared picker returning only entities / students that actually have attempts. Frontend: new reports.service.ts, all three pages rewritten to hit these endpoints; Recharts graphs now read live data, CSV export added on Student Performance and Record. Seeding: seed_reports.py completes any in_progress attempts and backfills 6 months of historical attempts across 3 entities so the trend / distribution / KPI panels have meaningful data. Idempotent. Tests: test_reports_flows.py (25/25 PASS) covers shape, filters, pagination. Regressions still green: Configuration 24/24, Support 29/29, Training 26/26. Browser-verified on localhost:8080 with admin login — all 4 tabs in Stats Corporate render, Student Performance shows real students + KPIs, Record shows 28 attempts with filter + CSV export working. Docs: new §20 in PROJECT_SUMMARY.md documenting scope, artifacts, seeding, test results, and gotchas (encoach.exam.custom uses `title` not `name`; encoach.entity requires `code`; in_progress attempts are excluded from aggregates). Made-with: Cursor
5.8 KiB
5.8 KiB