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

- .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
This commit is contained in:
Yamen Ahmad
2026-04-19 14:16:47 +04:00
parent e70a2854f4
commit 93c530eef2
10 changed files with 744 additions and 100 deletions

267
README.md
View File

@@ -1,123 +1,190 @@
# EnCoach Backend v2 — Odoo 19 Adaptive Learning Platform
# EnCoach Adaptive AI Learning Platform
The Odoo 19 backend for the **EnCoach** adaptive learning and institutional LMS platform. Provides ~377 REST API endpoints serving a React 18 SPA frontend.
EnCoach is a smart learning environment for individual and collaborative learning,
fully integrated with AI and equipped with intelligent, professional-grade
exercises, assessments, and e-exams.
## System Overview
This repository hosts the full stack:
| Component | Detail |
|-----------|--------|
| **Framework** | Odoo 19 Community Edition |
| **Language** | Python 3.12+ |
| **Database** | PostgreSQL 16 |
| **LMS Foundation** | OpenEduCat Community (14 modules, ported to v19) |
| **Custom Modules** | 27 `encoach_*` modules |
| **AI/ML** | OpenAI GPT-4o, Whisper (local), AWS Polly, ELAI, GPTZero, FAISS |
| **Authentication** | JWT (PyJWT) |
| **Deployment** | Docker Compose |
- **Backend** — Odoo 19 + ~30 `encoach_*` modules (Python 3.12, PostgreSQL 16)
- **Frontend** — React 18 + Vite + TypeScript single-page app
- **AI layer** — OpenAI + pgvector RAG, quality-gate validation, IELTS validator
- **Ops** — Docker Compose, JWT auth with refresh tokens, Prometheus-compatible
metrics, dynamic OpenAPI 3.0 spec
## Module Architecture
> **Canonical trees:** `backend/` (all server code) and `frontend/` (all client
> code). The legacy `new_project/` directory is deprecated — see
> [`new_project/DEPRECATED.md`](new_project/DEPRECATED.md).
```
new_project/
custom_addons/ # 27 custom EnCoach modules
encoach_api/ # REST API controllers (~120 routes)
encoach_lms_api/ # OpenEduCat bridge API (~209 routes)
encoach_adaptive_api/ # Adaptive learning API (~41 routes)
encoach_resources/ # Resource library API (~7 routes)
encoach_core/ # Users, entities, roles, permissions
encoach_taxonomy/ # Subject > Domain > Topic taxonomy
encoach_adaptive/ # Proficiency, learning plans, mastery
encoach_adaptive_ai/ # AI for diagnostics, coaching, content
encoach_exam/ # AI-powered exam engine
encoach_ai/ # OpenAI service wrapper
encoach_ai_generation/ # AI exam content generation
encoach_ai_grading/ # AI grading (writing, speaking, math, IT)
encoach_ai_media/ # TTS (Polly), STT (Whisper), ELAI avatars
encoach_courseware/ # Chapters, materials, AI workbench
encoach_communication/ # Discussion boards, announcements, messaging
encoach_notification/ # Notification engine, rules, preferences
encoach_faq/ # FAQ categories and items
encoach_approval/ # Approval workflows, stages
encoach_assignment/ # Exam-wrapper assignments
encoach_classroom/ # Virtual classroom groups
encoach_stats/ # Session tracking, statistics
encoach_training/ # Training tips, walkthroughs, FAISS
encoach_subscription/ # Packages, Stripe/PayPal/Paymob
encoach_registration/ # User registration, batch import
encoach_ticket/ # Support tickets
encoach_sis/ # UTAS SIS integration
encoach_branding/ # Whitelabeling
openeducat_erp-19.0/ # 14 OpenEduCat community modules
openeducat_core/ # Courses, batches, students, faculty
openeducat_timetable/ # Timetable sessions
openeducat_attendance/ # Attendance management
openeducat_exam/ # Institutional exams, marksheets
openeducat_assignment/ # Course assignments, submissions
openeducat_admission/ # Admission registers, applications
openeducat_classroom/ # Physical classrooms
openeducat_facility/ # Facilities and assets
openeducat_fees/ # Fee plans, student fees
openeducat_library/ # Library media, movements, cards
openeducat_activity/ # Student activities
openeducat_parent/ # Parent-student relationships
openeducat_erp/ # ERP connector
theme_web_openeducat/ # Web theme
```
---
## Staging
## 1. Quickstart
| Service | URL |
|---------|-----|
| **Odoo Backend** | `http://5.189.151.117:8069` |
| **React Frontend** | `http://5.189.151.117:3000` |
## Branching Workflow
This repo is connected to the staging server via a Git post-receive hook.
**All deployment is automatic after code review approval.**
1. Never push directly to `main` -- branch protection will block it.
2. Push your changes to a feature branch (e.g. `feature/full-backend-v1`).
3. Open a Pull Request on Gitea targeting `main`.
4. Request review from **devops (Talal)**.
5. Once approved and merged, the staging server rebuilds and redeploys automatically.
The `.env` file is **not committed**. It lives only on the staging server at `/opt/encoach/backend-v2/.env`.
## Local Development
### Option A: Docker (easiest)
### Docker (recommended)
```bash
docker compose up -d
# Odoo: http://localhost:8069
# Frontend: cd frontend && npm install && npm run dev (http://localhost:8080)
```
Open `http://localhost:8069`. First run: create a new database.
Create a new Odoo database on first visit, then install the `encoach_api`
module to pull in every `encoach_*` dependency.
Stop: `docker compose down`
### Source
### Option B: Source (venv + PostgreSQL)
**Prerequisites:** macOS, Homebrew, Python 3.11+, PostgreSQL 15+
Prerequisites: Python 3.12, PostgreSQL 16, Node 20, npm 10.
```bash
brew install postgresql@15 wkhtmltopdf
brew services start postgresql@15
createuser -s $(whoami)
# Backend
./setup.sh # creates venv, installs requirements.txt
./run.sh # starts Odoo on :8069
chmod +x setup.sh
./setup.sh
./run.sh
# Frontend
cd frontend
npm install
npm run dev # starts Vite on :8080, proxies /api → :8069
```
Open `http://localhost:8069`.
See [`MANUAL-RUN.md`](MANUAL-RUN.md) for a step-by-step walkthrough and
[`CONNECT-POSTGRES.md`](CONNECT-POSTGRES.md) for database wiring.
See [MANUAL-RUN.md](MANUAL-RUN.md) for step-by-step commands.
---
## Related Documents
## 2. Repository layout
```
odoo19/
├── backend/
│ └── custom_addons/
│ ├── encoach_api/ REST base + JWT + OpenAPI + metrics
│ ├── encoach_core/ Users, entities, roles, permissions
│ ├── encoach_taxonomy/ Subject → Domain → Topic
│ ├── encoach_ai/ OpenAI wrapper, cefr_mapper, validator
│ ├── encoach_ai_course/ AI course/exam generation pipelines
│ ├── encoach_ai_grading/ AI grading (writing/speaking/math/IT)
│ ├── encoach_ai_media/ TTS (Polly), STT (Whisper), ELAI
│ ├── encoach_vector/ pgvector store + RAG embeddings
│ ├── encoach_exam_template/ Canonical exam + student attempt models
│ ├── encoach_scoring/ Score computation, CEFR mapping
│ ├── encoach_quality_gate/ Automated content-quality checks
│ ├── encoach_ielts_validation/ IELTS-specific validators
│ ├── encoach_adaptive/ Adaptive engine, style matcher
│ ├── encoach_lms_api/ OpenEduCat bridge + LMS endpoints
│ ├── encoach_branding/ White-label config per entity
│ └── … (other encoach_* modules)
├── frontend/
│ ├── src/
│ │ ├── pages/ Route pages (React.lazy code-split)
│ │ ├── components/ Shared UI (shadcn/ui + custom)
│ │ ├── services/ Thin API wrappers over fetch
│ │ ├── hooks/queries/ React Query hooks + keys
│ │ ├── lib/api-client.ts Fetch + auto JWT refresh
│ │ └── types/ Shared DTO types
│ └── vite.config.ts manualChunks: react, query, charts, radix…
├── docs/
│ ├── PROJECT_SUMMARY.md Release notes & architecture history
│ ├── adr/ Architecture Decision Records
│ └── ENCOACH_*.md SRS, workflows, user stories
├── docker-compose.yml
├── Dockerfile
├── requirements.txt Python deps (pgvector, textstat, etc.)
└── README.md You are here
```
---
## 3. Architecture at a glance
```
┌────────────────────┐ HTTPS/JWT ┌────────────────────┐
│ React SPA (Vite) │ ───────────────► │ Odoo 19 + FastAPI-style │
│ - React Query │ ◄─────────────── │ controllers (encoach_*) │
│ - next-themes │ X-Request-Id └──────┬─────────────┘
│ - shadcn/ui │ │
└────────────────────┘ ▼
┌──────────────┐
│ PostgreSQL │
│ + pgvector │
└──────┬───────┘
┌──────────────┐
│ OpenAI, │
│ Whisper, │
│ Polly… │
└──────────────┘
```
Every request carries an `X-Request-Id` and emits structured JSON logs.
Prometheus-compatible counters are exposed at `/api/metrics`, and the live
OpenAPI 3.0 spec is at `/api/openapi.json`.
---
## 4. Key conventions
- **Canonical response envelope** — list endpoints return
`{ items: T[], total, page, size, data: T[] }` (see `encoach_api.controllers.base.paginated_envelope`).
- **CEFR mapping** — only `encoach_ai.services.cefr_mapper` is canonical. Do
not reintroduce local `band_to_cefr` copies.
- **JWT tokens** — short-lived access tokens (1h) + revocable refresh tokens
(7d). Only `access` tokens are accepted as Bearer credentials; refresh tokens
must go through `/api/auth/refresh`. See [`docs/adr/0002-jwt-refresh-token-flow.md`](docs/adr/0002-jwt-refresh-token-flow.md).
- **RAG metadata** — vector embeddings carry `course_id`, `subject_id`,
`entity_id`, `taxonomy`, `content_hash`. Chunking kicks in above 2 000 chars.
- **Frontend pagination** — `PaginatedResponse<T>` exposes both `items` and
`data`. Read from `items` in new code.
- **Frontend theming** — tokens live in `frontend/src/index.css` (`:root` and
`.dark`). Always use `hsl(var(--token))` instead of raw hex.
---
## 5. Health, observability, docs
| Endpoint | Purpose |
|---|---|
| `GET /api/health` | Liveness (always 200 when server is up) |
| `GET /api/health/ready` | Readiness (DB + required config) |
| `GET /api/openapi.json` | Dynamic OpenAPI 3.0 spec generated from `@http.route` |
| `GET /api/metrics` | Prometheus-format counters per route |
---
## 6. Deployment
Staging and production both use Docker Compose. The staging server rebuilds
automatically from `main`; never force-push. See
[`INSTALL-ODOO-SUMMARY.md`](INSTALL-ODOO-SUMMARY.md) for bootstrap notes.
| Service | Staging URL |
|---|---|
| Odoo backend | `http://5.189.151.117:8069` |
| React frontend | `http://5.189.151.117:3000` |
The `.env` file is **never** committed. On staging it lives at
`/opt/encoach/backend-v2/.env`.
---
## 7. Further reading
| Document | Description |
|----------|-------------|
| `ENCOACH_ODOO19_BACKEND_SRS.md` | Backend SRS v3.0 (definitive) |
| `ENCOACH_UNIFIED_SRS.md` | Unified frontend + backend SRS v2.0 |
| `ENCOACH_PRODUCT_DESCRIPTION.md` | Non-technical product description |
|---|---|
| [`docs/PROJECT_SUMMARY.md`](docs/PROJECT_SUMMARY.md) | Release notes + architecture history |
| [`docs/adr/`](docs/adr/) | Architecture Decision Records (why we built it this way) |
| [`docs/ENCOACH_UNIFIED_SRS.md`](docs/ENCOACH_UNIFIED_SRS.md) | Unified frontend + backend SRS |
| [`docs/ENCOACH_ODOO19_BACKEND_SRS.md`](docs/ENCOACH_ODOO19_BACKEND_SRS.md) | Backend SRS v3.0 |
| [`docs/ENCOACH_WORKFLOWS_BACKEND_SRS.md`](docs/ENCOACH_WORKFLOWS_BACKEND_SRS.md) | Backend workflows |
| [`docs/ENCOACH_WORKFLOWS_FRONTEND_SRS.md`](docs/ENCOACH_WORKFLOWS_FRONTEND_SRS.md) | Frontend workflows |
---
## 8. Contributing
1. Branch from `main` — never push direct. Branch protection enforces it.
2. Run `npx tsc --noEmit -p tsconfig.app.json` (frontend) and the module smoke
tests before opening a PR.
3. Every architectural decision should be captured as an ADR under
[`docs/adr/`](docs/adr/). Copy `0000-template.md` to start one.
4. Open the PR against `main` and request review from devops (Talal).