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
This commit is contained in:
Talal Sharabi
2026-03-14 16:46:46 +04:00
commit f5b627256f
168 changed files with 13428 additions and 0 deletions

345
ENCOACH_SUMMARY.md Normal file
View File

@@ -0,0 +1,345 @@
# 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.