- .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
191 lines
8.3 KiB
Markdown
191 lines
8.3 KiB
Markdown
# EnCoach — Adaptive AI Learning Platform
|
|
|
|
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.
|
|
|
|
This repository hosts the full stack:
|
|
|
|
- **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
|
|
|
|
> **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).
|
|
|
|
---
|
|
|
|
## 1. Quickstart
|
|
|
|
### Docker (recommended)
|
|
|
|
```bash
|
|
docker compose up -d
|
|
# Odoo: http://localhost:8069
|
|
# Frontend: cd frontend && npm install && npm run dev (http://localhost:8080)
|
|
```
|
|
|
|
Create a new Odoo database on first visit, then install the `encoach_api`
|
|
module to pull in every `encoach_*` dependency.
|
|
|
|
### Source
|
|
|
|
Prerequisites: Python 3.12, PostgreSQL 16, Node 20, npm 10.
|
|
|
|
```bash
|
|
# Backend
|
|
./setup.sh # creates venv, installs requirements.txt
|
|
./run.sh # starts Odoo on :8069
|
|
|
|
# Frontend
|
|
cd frontend
|
|
npm install
|
|
npm run dev # starts Vite on :8080, proxies /api → :8069
|
|
```
|
|
|
|
See [`MANUAL-RUN.md`](MANUAL-RUN.md) for a step-by-step walkthrough and
|
|
[`CONNECT-POSTGRES.md`](CONNECT-POSTGRES.md) for database wiring.
|
|
|
|
---
|
|
|
|
## 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 |
|
|
|---|---|
|
|
| [`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).
|