# 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/` | 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/` | 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/` | Create exam | | GET | `/api/exam//` | Get exam | | PATCH | `/api/exam//` | Update exam | | DELETE | `/api/exam//` | Delete exam | | POST | `/api/exam//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/` | Update group | | DELETE | `/api/groups/` | Delete group | ### Assignments (8) | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/assignments` | List assignments | | POST | `/api/assignments` | Create assignment | | PATCH | `/api/assignments/` | Update assignment | | DELETE | `/api/assignments/` | Delete assignment | | POST | `/api/assignments//start` | Start assignment | | POST | `/api/assignments//release` | Release results | | POST | `/api/assignments//archive` | Archive | | POST | `/api/assignments//unarchive` | Unarchive | ### Sessions & Stats (4) | Method | Endpoint | Description | |--------|----------|-------------| | POST | `/api/sessions` | Save exam session | | DELETE | `/api/sessions/` | Delete session | | POST | `/api/stats` | Save statistics | | GET | `/api/stats/` | 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/` | Generate reading passage | | POST | `/api/exam/reading/` | Generate reading exercises | | GET | `/api/exam/listening/
` | Generate listening dialog | | POST | `/api/exam/listening/` | Generate listening exercises | | GET | `/api/exam/writing/` | Generate writing task | | GET | `/api/exam/speaking/` | 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/` | 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/` | 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/` | Update ticket | | DELETE | `/api/tickets/` | 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.