Builds the §24 product on top of the LangGraph runtime from §22:
Phase A (Sources / RAG)
- encoach.course.plan.source model (file | url | text)
- SourceIndexer extracts PDF (pypdf), DOCX (python-docx), HTML, plain
text and embeds chunks via the existing pgvector pipeline scoped to
plan_id, so resources.search only returns the plan's own corpus
- Endpoints: list/create/upload/reindex/delete + plan-scoped retrieval
Phase B (Deliverables)
- services.deliverables.compute_deliverables walks the plan, derives
{planned, generated, ready} per week from material + media state
- GET /api/ai/course-plan/<id>/deliverables drives the new wizard
preview step and the live progress strip on the detail page
Phase C (Multi-modal media)
- encoach.course.plan.media model + MediaService:
audio: AWS Polly (default) or ElevenLabs
image: OpenAI DALL-E 3, capped per plan via system parameter
video: local ffmpeg subprocess (image + audio -> MP4 1280x720)
- Three new agent tools (media.synthesize_audio / generate_image /
compose_video), wired into course_week_materials and a new
course_media_director agent
- Endpoints per material + week-level batch generator
Phase D (Assignments)
- encoach.course.plan.assignment supports mode='batch' (op.batch) or
mode='students' (res.users), with due_date + message + state
- REST endpoints to list / create / delete assignments
Phase E (Student view)
- /api/student/course-plans + /api/student/course-plans/<id>
enforce visibility via assignment.expand_user_ids()
- New /student/course-plans list + read-only drilldown rendering
audio/image/video tiles from /web/content/<attachment_id>
Cross-cutting
- encoach.ai.tool.category: + media (so the new tools register)
- encoach.embedding gains a plan_id filter for plan-scoped RAG
- Wizard adds Sources + Multimedia steps; AdminCoursePlanDetail
rewritten with DeliverablesStrip + SourcesCard + AssignmentsCard +
per-material MediaDrawer
- ~280 new EN + AR i18n keys (full RTL coverage)
- smoke_course_plan.py exercises every phase via odoo-bin shell;
last run: PASS A/B/D/E + DALL-E 3 image (753 KB), Polly audio
fails cleanly when AWS creds aren't configured (expected)
Documentation: §24 added to docs/PROJECT_SUMMARY.md with phase-by-phase
artefact list, endpoints, smoke test, ops notes, and gotchas.
Made-with: Cursor
Explains why /web/database/manager restores appear to succeed but the
live site keeps serving the old data (target DB name mismatch / Odoo
not restarted / dbfilter pinned), and ships a 6-step SSH-based
recovery procedure with safety-net backup, filestore handling, and
verification checklist tied to the known QA fixtures.
Made-with: Cursor
Production QA reported "Submit failed 413" on /generation and plain
"Upload failed" (no detail) on resource upload. Root cause is the
outer reverse-proxy nginx on the VPS — still on default
`client_max_body_size 1m` — rejecting requests before they reach
Odoo. The inner docker-nginx and Odoo limits were already raised in
earlier commits; only the VPS proxy was left unpatched.
UI side
- Add `describeApiError(err, fallback, context)` helper in
lib/api-client.ts. Maps common HTTP codes to human-readable,
actionable toast descriptions (413 → "ask ops to raise nginx
client_max_body_size", 504 → "server took too long, retry", 502
→ "Odoo is restarting", 401 → "sign in again", 4xx/5xx → server
error body + status code).
- Use it in GenerationPage submit, ResourceManager upload,
TeacherLibrary upload, CustomExamCreate save/publish. Replaces
four slightly-different ad-hoc mappings with one source of truth.
Deploy side
- Add deploy/nginx-vps.conf.example: full TLS reverse-proxy template
with the body/timeout knobs that must match Odoo's limit_request
(128 MB) and limit_time_real (900 s).
- Add docs/DEPLOY_413_504_FIX.md: step-by-step remediation guide for
the team lead covering the 3 layers that can block large bodies
(outer nginx, Cloudflare, Odoo worker) and how to verify each.
Made-with: Cursor
- docs/WORK_REPORT.md: recap of the Phase 0/1/2/3 hardening sprint —
what shipped per phase, branding update, repo migration to the new
full_encoach_platform repo, per-commit file-churn, verification
results (tsc, build, Playwright), known gaps, and an operator
checklist for production promotion.
- docs/USER_MANUAL.md: end-user guide for every role (Student, Teacher,
Admin, Corporate, Agent, Developer). Walks through every portal URL,
the AI coach / IELTS / adaptive flows, human-in-the-loop exam review,
AI prompt editor, feedback triage, GDPR Privacy Center, language +
theme toggles, and troubleshooting.
Made-with: Cursor
- .github/workflows/ci.yml: two jobs — frontend (tsc --noEmit, lint, build,
Playwright) and backend (Postgres 16 + odoo:19 --test-enable
--test-tags encoach_api) — catches regressions before merge.
- docs/adr/: start an Architecture Decision Record trail with
0001 canonical directory layout, 0002 JWT refresh flow,
0003 paginated response envelope, 0004 RAG metadata + chunking.
- docs/PROJECT_SUMMARY.md §21 Hardening Release: full recap of the AI
quality loop, compliance, Paymob, i18n, and CI work shipped in this
drop, plus new DB tables, REST routes, frontend routes, verification
results, and operator-facing configuration.
- README.md refreshed for the v4 split-repo doctrine and the new feature
surface.
- new_project/DEPRECATED.md: formal retirement notice pointing at
backend/ as the canonical tree.
Made-with: Cursor
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
Flip the source-of-truth model: the two split repos at git.albousalh.com are
now the authoritative origins for each half of the stack; this workspace
(`odoo19/`) is demoted to a developer working tree / full-stack monorepo
mirror.
- Header banner rewritten: canonical repos stated up front with links; mark
the monorepo mirror as secondary.
- §6 restructured into 6.1–6.8: layout diagram, reordered remotes table
(backend-v4 + frontend-v4 first), feature workflow that ends in publishing
to the canonical repos (monorepo push is now optional), mandatory
`git subtree split + push` commands for both halves, per-repo "what's
shipped / what's not", VPS team-lead quickstart, safety rules, creds.
Made-with: Cursor
- Header banner: add 2026-04-19 entry for the release to backend-v4 /
frontend-v4 split repos; state upfront that this monorepo is the single
source of truth.
- §6 rewritten: layout diagram, remotes table, feature-branch → commit →
publish workflow, exact `git subtree split` commands used to fast-forward
frontend-v4/main and backend-v4/main, notes on what each split repo does
and does not contain, and the safety rules for files that must never be
committed (pgdata backups, build caches, env files).
Made-with: Cursor
- Fix ELAI video generation (correct render endpoint, script splitting for 60s limit)
- Fix speaking script generation error handling and empty response display
- Add custom exam list API (GET /api/exam/custom/list)
- Add assignments REST API (list, create, get)
- Add rubrics REST API (list, create)
- Enhance Generation page: dynamic exam structures, auto-module selection, preview dialog, audio player
- Improve submit feedback with exam ID and status in toast notifications
- Fix ExamsListPage to show both custom exams and exam sessions
- Connect RubricsPage to backend API with fallback data
- Add Dockerfile, docker-compose.yml, requirements.txt for deployment
- Fix placement, grading, scoring, and auth controllers
- Add ErrorBoundary component for frontend resilience
- Add QA report and credentials documentation
Made-with: Cursor