Files
encoach_be_odoo19/ENCOACH_SUMMARY.md
Talal Sharabi f5b627256f EnCoach Odoo 19 custom modules
Full backend implementation with custom Odoo modules:
- encoach_api: Core API, user management, JWT auth
- encoach_exam: Exam generation (reading, writing, listening, speaking)
- encoach_evaluate: AI-powered evaluation (writing, speaking)
- encoach_training: Training tips and walkthrough
- encoach_storage: File storage management
- encoach_payment: Stripe, PayPal, Paymob integration
- encoach_mail: Email notifications

Made-with: Cursor
2026-03-14 16:46:46 +04:00

346 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# EnCoach Odoo 19 Project Summary
## Overview
The **EnCoach IELTS platform** (originally Node.js / MongoDB / Firebase) has been migrated into **15 custom Odoo 19 modules** that replicate all business logic inside Odoo Community Edition.
---
## Module Map
| Module | Purpose |
|--------|---------|
| `encoach_core` | Users, entities (orgs), roles, permissions, registration codes, invites |
| `encoach_exam` | Exam builder with parts/exercises/questions (JSON), approval workflows |
| `encoach_classroom` | Student groups / classrooms |
| `encoach_assignment` | Assignments with start / release / archive lifecycle |
| `encoach_stats` | Exam sessions and score statistics |
| `encoach_evaluation` | AI-powered writing & speaking evaluation jobs |
| `encoach_ai` | Core AI services (OpenAI, prompt management) |
| `encoach_ai_grading` | Multi-answer grading, GPTZero plagiarism checks |
| `encoach_ai_generation` | AI exam content generation (reading / writing / speaking / listening) |
| `encoach_ai_media` | AWS Polly audio, ELAI video avatars, Whisper transcription |
| `encoach_training` | Personalised training plans, tips (FAISS semantic search), walkthroughs |
| `encoach_subscription` | Packages, payments (Stripe / PayPal / Paymob), discount codes |
| `encoach_registration` | Registration code management service |
| `encoach_ticket` | Support ticket system |
| `encoach_api` | REST API layer (67 endpoints) with JWT authentication |
---
## How to Run
### Prerequisites
- Python 3.12 (via Miniconda)
- PostgreSQL (local, via Conda)
### Start PostgreSQL
```bash
cd /Users/yamenahmad/projects2026/odoo/odoo19
.conda-envs/odoo19/bin/pg_ctl -D pgdata -l pg.log start
```
### Start Odoo
```bash
cd /Users/yamenahmad/projects2026/odoo/odoo19/odoo
../.conda-envs/odoo19/bin/python odoo-bin -c ../odoo.conf -d encoach
```
### Fresh Install (drop + recreate)
```bash
.conda-envs/odoo19/bin/dropdb -h localhost -U yamenahmad encoach
.conda-envs/odoo19/bin/createdb -h localhost -U yamenahmad encoach
cd odoo
../.conda-envs/odoo19/bin/python odoo-bin -c ../odoo.conf -d encoach -i encoach_api --stop-after-init
```
After fresh install, set the admin password:
```bash
cd odoo
../.conda-envs/odoo19/bin/python odoo-bin shell -c ../odoo.conf -d encoach <<'EOF'
user = env['res.users'].browse(2)
user.password = 'admin'
env.cr.commit()
EOF
```
---
## Access the System
### Odoo Backend (Admin UI)
| | |
|--|--|
| **URL** | http://127.0.0.1:8069/web |
| **Login** | `admin` |
| **Password** | `admin` |
The **EnCoach** top-level menu contains: Users & Entities, Exams, Classroom, AI & Grading, Training, Subscriptions, Support, Configuration.
### REST API (for the frontend)
| | |
|--|--|
| **Base URL** | http://127.0.0.1:8069 |
| **Auth** | JWT Bearer token (obtained via `/api/login`) |
| **Format** | JSON request / response |
---
## API Collection (67 Endpoints)
### Auth (4)
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/register` | Register new user |
| POST | `/api/login` | Login returns JWT token |
| POST | `/api/logout` | Logout |
| POST | `/api/reset` | Reset password |
| POST | `/api/reset/sendVerification` | Send reset verification |
### Users (6)
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/user` | Get current user (from JWT) |
| POST / PATCH | `/api/users/update` | Update profile |
| GET | `/api/users/list` | List / search users |
| GET | `/api/users/<id>` | Get user by ID |
| POST | `/api/users/controller` | User admin actions |
| GET | `/api/users/balance` | Get user balance |
### Registration Codes (3)
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/code/<code>` | Validate registration code |
| POST | `/api/batch_users` | Batch-create users |
| POST | `/api/make_user` | Create single user |
### Exams (7)
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/exam` | List exams (filter by `?module=`) |
| POST | `/api/exam/<module>` | Create exam |
| GET | `/api/exam/<module>/<id>` | Get exam |
| PATCH | `/api/exam/<module>/<id>` | Update exam |
| DELETE | `/api/exam/<module>/<id>` | Delete exam |
| POST | `/api/exam/<module>/import/` | Import exam from file |
| GET | `/api/exam/avatars` | List exam avatars |
### Classrooms (4)
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/groups` | List groups |
| POST | `/api/groups` | Create group |
| PATCH | `/api/groups/<id>` | Update group |
| DELETE | `/api/groups/<id>` | Delete group |
### Assignments (8)
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/assignments` | List assignments |
| POST | `/api/assignments` | Create assignment |
| PATCH | `/api/assignments/<id>` | Update assignment |
| DELETE | `/api/assignments/<id>` | Delete assignment |
| POST | `/api/assignments/<id>/start` | Start assignment |
| POST | `/api/assignments/<id>/release` | Release results |
| POST | `/api/assignments/<id>/archive` | Archive |
| POST | `/api/assignments/<id>/unarchive` | Unarchive |
### Sessions & Stats (4)
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/sessions` | Save exam session |
| DELETE | `/api/sessions/<id>` | Delete session |
| POST | `/api/stats` | Save statistics |
| GET | `/api/stats/<id>` | Get stat by ID |
| POST | `/api/statistical` | Query / aggregate stats |
### AI Evaluation (4)
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/evaluate/writing` | Evaluate writing answer |
| POST | `/api/evaluate/speaking` | Evaluate speaking (audio) |
| POST | `/api/evaluate/interactiveSpeaking` | Evaluate interactive speaking |
| GET | `/api/evaluate/status` | Poll evaluation job status |
### AI Generation (7)
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/exam/reading/<passage>` | Generate reading passage |
| POST | `/api/exam/reading/` | Generate reading exercises |
| GET | `/api/exam/listening/<section>` | Generate listening dialog |
| POST | `/api/exam/listening/` | Generate listening exercises |
| GET | `/api/exam/writing/<task>` | Generate writing task |
| GET | `/api/exam/speaking/<task>` | Generate speaking task |
| POST | `/api/exam/level/` | Generate level-test exercises |
### AI Media (7)
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/exam/listening/media` | Generate listening MP3 (AWS Polly) |
| POST | `/api/exam/listening/transcribe` | Transcribe audio to dialog |
| POST | `/api/exam/listening/instructions` | Generate instructions MP3 |
| POST | `/api/exam/speaking/media` | Start AI avatar video generation |
| GET | `/api/exam/speaking/media/<vid>` | Poll video generation status |
| GET | `/api/exam/speaking/avatars` | List speaking avatars |
| POST | `/api/transcribe` | Transcribe audio file (Whisper) |
### Training (4)
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/training` | Generate personalised training plan |
| GET | `/api/training/<id>` | Get training by ID |
| POST | `/api/training/tips` | Get contextual tips |
| GET | `/api/training/walkthrough` | Get walkthrough |
### Subscriptions & Payments (5)
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/packages` | List subscription packages |
| POST | `/api/stripe` | Create Stripe checkout session |
| POST | `/api/paypal` | Create PayPal order |
| POST | `/api/paypal/approve` | Capture / approve PayPal order |
| POST | `/api/paymob` | Create PayMob payment intention |
### Tickets (4)
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/tickets` | List support tickets |
| POST | `/api/tickets` | Create ticket |
| PATCH | `/api/tickets/<id>` | Update ticket |
| DELETE | `/api/tickets/<id>` | Delete ticket |
### Storage (2)
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/storage` | Upload file |
| POST | `/api/storage/delete` | Delete file |
### Grading (2)
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/grading/multiple` | Grade multiple short-answer exercises |
| POST | `/api/exam/grade/summary` | Generate grading summary |
---
## Quick Test
```bash
# 1. Register a user
curl -s http://127.0.0.1:8069/api/register \
-H "Content-Type: application/json" \
-d '{"email":"test@test.com","password":"Pass1234","name":"Test User","type":"student"}'
# 2. Login get JWT token
TOKEN=$(curl -s http://127.0.0.1:8069/api/login \
-H "Content-Type: application/json" \
-d '{"credential":"test@test.com","password":"Pass1234"}' \
| python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")
# 3. Get current user (authenticated)
curl -s http://127.0.0.1:8069/api/user \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
# 4. List exams
curl -s "http://127.0.0.1:8069/api/exam?module=reading" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
# 5. Create a ticket
curl -s http://127.0.0.1:8069/api/tickets \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"subject":"Test ticket","description":"Just testing","type":"feedback"}'
# 6. List packages
curl -s http://127.0.0.1:8069/api/packages \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
```
---
## File Structure
```
addons_extra/
├── encoach_core/
│ ├── __manifest__.py
│ ├── models/ # entity, role, permission, code, invite, res_users, user_entity_rel
│ ├── security/ # security.xml (groups), ir.model.access.csv
│ ├── data/ # constants.xml, assign_admin_group.xml
│ ├── views/ # menu.xml + views for every model
│ └── scripts/ # migrate_mongodb.py, migrate_firebase_auth.py, rebuild_faiss.py, import_avatars.py
├── encoach_exam/
│ ├── models/ # exam.py, approval_workflow.py
│ └── views/
├── encoach_classroom/
│ ├── models/ # group.py
│ └── views/
├── encoach_assignment/
│ ├── models/ # assignment.py
│ └── views/
├── encoach_stats/
│ ├── models/ # session.py, stat.py
│ └── views/
├── encoach_evaluation/
│ ├── models/ # evaluation.py, ai_job.py
│ └── views/
├── encoach_ai/
│ └── services/ # openai_service.py, prompt_service.py
├── encoach_ai_grading/
│ └── services/ # grading_service.py, gptzero_service.py
├── encoach_ai_generation/
│ └── services/ # reading, listening, writing, speaking, level generators
├── encoach_ai_media/
│ ├── models/ # elai_avatar.py
│ ├── services/ # polly_service.py, elai_service.py, whisper_service.py
│ └── views/
├── encoach_training/
│ ├── models/ # training.py, tip.py, walkthrough.py
│ ├── services/ # training_service.py, faiss_service.py
│ └── views/
├── encoach_subscription/
│ ├── models/ # package.py, payment.py, discount.py
│ ├── services/ # stripe_service.py, paypal_service.py, paymob_service.py
│ └── views/
├── encoach_registration/
│ └── services/ # code_service.py
├── encoach_ticket/
│ ├── models/ # ticket.py
│ └── views/
└── encoach_api/
└── controllers/ # 16 controller files (auth, users, exams, classrooms, etc.)
```
---
## Key Technical Decisions
- **JSON fields** (`fields.Json`) used extensively for complex nested data (exam parts, scores, solutions) to match existing MongoDB document shapes.
- **JWT authentication** via `PyJWT` for stateless API auth, stored secret in `ir.config_parameter`.
- **Odoo 19 changes**: `group_ids` (not `groups_id`), no `category_id` on `res.groups`, `models.Constraint` instead of `_sql_constraints`.
- **Security**: Each model has ACL rules for Student (read-only), Teacher (read/write), Admin (full CRUD), and `base.group_system` (Odoo admin full CRUD).
- **Admin user** is automatically added to the EnCoach Developer group (which implies Admin and Teacher) on install.