# 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` 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).