v4 #4

Merged
yamen merged 11 commits from v4 into main 2026-04-19 12:33:35 +02:00
Collaborator
No description provided.
yamen added 11 commits 2026-04-19 12:33:13 +02:00
- Backend: AI generation fallbacks when OpenAI not configured, full exam
  submission saving all params (difficulty, rubric, entity, grading system,
  approval workflow) and creating linked question records per section
- Backend: new exam session controller with get_session, autosave, submit,
  status, and results endpoints; student attempt/answer/score models
- Backend: new controllers for entities, approval workflows, exam schedules
- Frontend: exam session split-layout with passage panel, question types
  (MCQ, T/F/NG, gap-fill, writing, speaking), timer, and review dialog
- Frontend: results page with percentage score, per-answer breakdown table
- Frontend: generation page dynamic dropdowns, full payload submission
- Frontend: updated types for ExamSessionSection, ExamQuestion options

Made-with: Cursor
Ship three fully-wired admin areas end-to-end with APIs, seeds, tests and docs.

Backend (new `encoach_lms_api` addon + existing addons):
- Institutional: academic years/terms, departments, admission registers & admissions,
  courses/batches, lessons, fees (terms + student fees + invoicing with income-account
  auto-wiring), gradebook (assignments/grades), library, facilities (encoach.asset),
  student leave, result templates + marksheets (incl. delete-with-cascade).
- Support: `encoach.ticket` model + CRUD/assignee routes; payment records derived
  from `op.student.fees.details` and `account.move`; platform settings backed by
  `encoach.code` and `ir.config_parameter` (packages + grading config).
- Training: `encoach.vocab.item` + `encoach.grammar.rule` (plus progress models)
  with CRUD, pagination, search/level filters, and upsert-style progress endpoints.
  Odoo 19 compatibility: `_sql_constraints` replaced with `@api.constrains`;
  `ValidationError`/`UserError` mapped to HTTP 400.

Frontend:
- Rewire institutional admin pages (Academic Year Manager, Admissions, Courses,
  Lessons, Fees, Gradebook, Library, Facilities, Student Leave, Marksheets,
  Taxonomy, Resources) to real APIs with React Query invalidation and dialogs.
- New typed services: `payments.service.ts`, `platformSettings.service.ts`,
  `training.service.ts`. Updated `fees/gradebook/lms/courseware/taxonomy/
  resources/student-progress/generation` services + related types.
- Rewrite `VocabularyPage`, `GrammarPage`, `PaymentRecordPage`, `SettingsPage`,
  `TicketsPage` to consume live data with search/filter/progress/CRUD flows.
- New shared components: `TaxonomyCascade`, `MaterialViewer`, `teacher/TeacherLibrary`.
- Favicons/branding assets and misc. UX polish across teacher/student pages.

Tooling & QA:
- Seeders: `seed_demo.py`, `seed_demo_data.py`, `seed_institutional.py` (idempotent,
  covers institutional + support + training fixtures incl. income-account wiring).
- API write-flow test suites: `test_write_flows.py` (institutional),
  `test_support_flows.py` (support), `test_training_flows.py` (training),
  `test_ai_full.py`. All suites pass end-to-end.
- Docs: add `docs/PROJECT_SUMMARY.md` with per-section scope, artifacts and QA.
- `.gitignore`: ignore `pgdata_bak_*/`, `frontend/.vite/`, `frontend/dist/`,
  `frontend/node_modules/`.

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
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
Local remote renames (URLs unchanged):
  backend-v4  → origin-backend   (canonical backend)
  frontend-v4 → origin-frontend  (canonical frontend)
  origin      → mirror-monorepo  (secondary full-tree mirror)

The `v4` branch auto-updated to track `mirror-monorepo/v4`.

Docs:
- Header banner: new 2026-04-19 "remote rename" entry; release entry now
  references `mirror-monorepo/v4` instead of `origin/v4`.
- §6.2 remotes table updated with the new names (plus a rename-history note)
  and reordered so the two canonical repos lead.
- §6.3 feature workflow now uses `git pull/push mirror-monorepo v4`.
- §6.4 publish commands now use `origin-backend` / `origin-frontend`.

Made-with: Cursor
Audit of the admin Configuration section (FAQ Manager, Notification Rules,
Approval Config) surfaced three contract mismatches and one missing schema.

FAQ
  * Backend `encoach.faq.category.audience` / `encoach.faq.item.audience`
    rejected the `both` and `entity` values emitted by the FAQ Manager
    UI. Widened the Selection so the UI's full vocabulary round-trips.
  * FAQ item `video_url` was already accepted by the UI but silently
    dropped by the controller; now persisted via a new `video_url`
    field on `encoach.faq.item` and serialized on list/get responses.

Notification Rules
  * Added `days_before`, `frequency`, `channel`, `entity_id` to
    `encoach.notification.rule`. These are the exact fields the admin
    form collects; prior to this change they were serialized into the
    JSON body, ignored by the controller, and omitted from responses,
    leaving the Active switch permanently off and the table columns
    blank.
  * Controller now translates `active` <-> `is_active` both ways so the
    new frontend contract and legacy callers coexist. Missing required
    fields return HTTP 400 instead of 500.

Approval Workflows
  * The controller had been hand-rolling raw SQL against three tables
    (`encoach_approval_workflow`, `_stage`, `_request`) that no Odoo
    model declared, so the tables never existed. List() was guarded and
    returned empty; create() would 500 with "relation does not exist".
  * Introduced real ORM models in `encoach_exam_template/models/approval.py`
    plus access rights, which auto-provision the tables on -u.
  * Rewrote the controller to use ORM, added PATCH, and emitted both
    `items` and `results` in the list envelope so the frontend's
    PaginatedResponse reader and legacy callers both work. Step
    payloads now carry `max_days`, `auto_escalate`, and
    `notification_email` end to end.
  * Frontend `approvalsService` and `ApprovalWorkflowConfig` updated to
    send the full stage shape + `allow_bypass`, tolerate both envelope
    keys, and validate at least one approver before submit.

Schema delta applied via `./run.sh -u encoach_exam_template,encoach_lms_api`.
Verified with new `test_config_flows.py`: 24/24 passing. Regression runs
on `test_support_flows.py` (29/29) and `test_training_flows.py` (26/26)
remain green.

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
- Replace public/logo-icon.png with the approved EnCoach wordmark
  (icon + "EnCoach" + tagline "Unlock your potential with AI powered platform").
- Login page shows the full branded logo at h-36 and drops the duplicate
  text heading since the wordmark is now baked into the asset.
- Student/Teacher/Admin sidebars show a small rounded icon when collapsed
  and the full wordmark at h-14 when expanded, removing the previous
  duplicated "EnCoach" text span.
- og:image in index.html already points at /logo-icon.png so social cards
  pick up the new branding automatically.

Made-with: Cursor
Roadmap P0 — platform safety & ops
- Merge duplicate encoach.student.attempt/answer models into encoach_scoring
  and drop the stale encoach_exam_template copies.
- Remove duplicate /api/exam/* routes; canonicalize on one controller tree.
- Gate raw-SQL seeds in seed_demo_data.py behind an explicit env flag.
- Add /api/health and /api/health/ready (DB + LLM reachability) endpoints.
- Fix docker-compose + ship odoo-docker.conf for container-local runs.
- Enforce OpenAI request_timeout=30s and @jwt_required on all AI/coach routes.
- Promote canonical cefr_mapper to encoach_ai.services.cefr_mapper.
- JWT cache TTL=30s + invalidation hook on user mutation.

Roadmap P1 — exam correctness & data provenance
- Wire QualityChecker + IeltsValidator into exam submit with a
  pending_review gate (encoach_ai.services.question_validator).
- Populate RAG metadata (course_id, subject_id, entity_id, taxonomy) on
  encoach_vector embeddings and add a chunking pipeline (>2000 chars).
- Add provenance fields on encoach.question (model, prompt_hash, log_id)
  and validate LLM output with schema before DB insert.
- Unify response envelope to {items,total,page,size}.
- Approval reject rollback with savepoint atomicity.
- Ticket notifications on status/assignee change.

Roadmap P2 — performance & observability
- Reports: replace Python loops with SQL read_group aggregations.
- X-Request-ID middleware + structured JSON logs.
- In-process/Prometheus counters and openapi.py controller exporting a
  spec by scanning @http.route decorators.
- Paymob real checkout + HMAC-SHA512 webhook verification, backed by a
  new encoach.paymob.order model and ir.config_parameter credentials.
- JWT refresh tokens + revocation table.
- Composite DB indexes on hot report/ticket/attempt paths.

Roadmap P3 — human-in-the-loop & compliance
- Human-in-the-loop exam review workflow (pending_review → publish) with
  new review controller and status transitions.
- encoach.ai.prompt model + versioning + admin editor endpoints (one
  active version per key, render-preview dry run).
- Student feedback loop → encoach.ai.feedback (upsert per user/subject,
  admin triage + resolve endpoints).
- GDPR export (/api/gdpr/export) and right-to-erasure (/api/gdpr/delete)
  with anonymization, tombstone record, and admin-self-erasure guard.
- HttpCase smoke tests for /api/health and /api/health/ready.

Made-with: Cursor
Roadmap P0
- Ship /logo.svg fallback and rewire asset references (superseded later by
  the project-manager PNG in a separate commit).

Roadmap P1
- Response envelope alignment ({items,total,page,size}) across services
  and query hooks.
- Approval/ticket UX updates tied to the new backend rollback semantics.

Roadmap P2
- React.lazy + Vite manualChunks to split vendor-radix/charts/icons/forms
  from the main bundle and cut initial JS.
- Fix the 181 tsc errors (PaginationParams class + per-service generics).
- Auto-refresh flow for JWT refresh tokens wired into api-client.ts.

Roadmap P3
- i18n: i18next + language detector, en/ar locales, RTL auto-switch,
  LanguageToggle component in RoleLayout and AdminLmsLayout.
- GDPR: PrivacyCenter page for data export and right-to-erasure, backed
  by gdpr.service.ts; logout via AuthContext after erasure.
- Human-in-the-loop exam review UI: admin ExamReviewQueue + ExamReviewDetail
  pages, useExamReview hooks, exam-review.service.ts.
- AI quality loop: AIPromptEditor (versioning + render preview),
  AIFeedbackButtons for students, AIFeedbackTriage admin page, dedicated
  services, hooks, and types.
- Dark mode: ThemeProvider + ThemeToggle + chart color tokens.
- Accessibility: DialogDescription on every DialogContent; alert-dialog
  and sheet updates.
- Retire dead pages: ExamPage marketing, Index, ProfilePage import.
- Playwright e2e scaffolding: playwright.config.ts + e2e/login.spec.ts
  smoke tests, npm scripts test:e2e / test:e2e:install.

Made-with: Cursor
chore(ci,docs): GitHub Actions, ADRs, README overhaul, §21 Hardening Release
Some checks failed
CI / Frontend — lint + build + e2e (pull_request) Has been cancelled
CI / Backend — Odoo HttpCase (pull_request) Has been cancelled
93c530eef2
- .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
yamen merged commit 7024197c7b into main 2026-04-19 12:33:35 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: devops/encoach_backend_new_v2#4