EnCoach Frontend v1 - Production-ready with full API integration
- 59 pages (52 original + 7 new adaptive learning pages) - 14 AI components wired to real backend endpoints - Real JWT authentication with 7 user roles - 21 API service modules with TanStack Query hooks - 14 TypeScript type definition files - Entity-scoped permission system - Universal adaptive learning engine pages (subjects, diagnostic, proficiency, learning plan, topic) - Admin taxonomy and resource management pages - All mock data removed, all pages connected to Odoo 19 REST API docs/ contains: - ENCOACH_UNIFIED_SRS.md (master product SRS) - ODOO_BACKEND_SRS_v3.md (backend developer handoff) - ENCOACH_PRODUCT_DESCRIPTION.md (stakeholder document) - UTAS_MASTER_PLAN.md (project timeline) - Supporting architecture and analysis documents Made-with: Cursor
This commit is contained in:
249
docs/DEVELOPER_FEEDBACK.md
Normal file
249
docs/DEVELOPER_FEEDBACK.md
Normal file
@@ -0,0 +1,249 @@
|
||||
# EnCoach Odoo 19 -- Developer Feedback
|
||||
|
||||
**Date:** March 11, 2026
|
||||
**Status:** ALL ITEMS RESOLVED (March 13, 2026)
|
||||
**Reference:** ODOO_MIGRATION_SRS_v2.md
|
||||
|
||||
---
|
||||
|
||||
## Overall Assessment
|
||||
|
||||
The delivery covers approximately **85% of the SRS v2 requirements**. All 15 custom modules are present, the core AI/ML services are well-implemented, data models match the specification, and 67-72 API endpoints are wired up with proper JWT authentication and security groups. The code quality is solid -- clean structure, proper error handling, and good separation of concerns.
|
||||
|
||||
The items below still need to be implemented to reach full SRS compliance.
|
||||
|
||||
---
|
||||
|
||||
## 1. Payment Integration (Critical -- Not Implemented)
|
||||
|
||||
**SRS Reference:** Section 7
|
||||
|
||||
All three payment services are currently stubs that return `"not yet implemented"`. The SRS requires full integration with:
|
||||
|
||||
### 1.1 Stripe
|
||||
|
||||
**Files:** `encoach_subscription/services/stripe_service.py`
|
||||
|
||||
Required functionality:
|
||||
- Install and use the `stripe` Python SDK
|
||||
- `create_checkout_session()` -- Create a Stripe Checkout Session using `stripe.checkout.Session.create()` with:
|
||||
- `line_items` from the selected `encoach.package`
|
||||
- `success_url` and `cancel_url` from the request
|
||||
- `client_reference_id` = user ID
|
||||
- `customer_email` = user email
|
||||
- Apply discount if `discount_code` is provided (validate against `encoach.discount`)
|
||||
- Return `{ "sessionId": "cs_...", "url": "https://checkout.stripe.com/..." }`
|
||||
- **Webhook endpoint** (`POST /api/stripe/webhook`):
|
||||
- Verify signature using `stripe.Webhook.construct_event()` with `STRIPE_WEBHOOK_SECRET`
|
||||
- Handle `checkout.session.completed` event:
|
||||
- Find user by `client_reference_id`
|
||||
- Extend `subscription_expiration` by the package's `duration_days`
|
||||
- Create `encoach.subscription.payment` record
|
||||
- For corporate users, propagate subscription to entity members
|
||||
|
||||
### 1.2 PayPal
|
||||
|
||||
**Files:** `encoach_subscription/services/paypal_service.py`
|
||||
|
||||
Required functionality:
|
||||
- Use PayPal REST API (`httpx` or `requests`)
|
||||
- Obtain access token from `PAYPAL_ACCESS_TOKEN_URL` using `client_id` + `client_secret`
|
||||
- `create_order()` -- Create PayPal order via `POST /v2/checkout/orders`:
|
||||
- `intent: "CAPTURE"`
|
||||
- `purchase_units` with amount from package (minus discount)
|
||||
- Return `{ "orderId": "...", "approvalUrl": "https://paypal.com/..." }`
|
||||
- `capture_order()` -- Capture approved order via `POST /v2/checkout/orders/{id}/capture`:
|
||||
- On success, extend subscription and create payment record
|
||||
- Return `{ "ok": true }`
|
||||
|
||||
### 1.3 Paymob
|
||||
|
||||
**Files:** `encoach_subscription/services/paymob_service.py`
|
||||
|
||||
Required functionality:
|
||||
- Use Paymob API (`httpx` or `requests`)
|
||||
- `create_intention()` -- Create payment intention:
|
||||
- Authenticate with `PAYMOB_API_KEY`
|
||||
- Create order, then payment key
|
||||
- Return `{ "intentionId": "...", "clientSecret": "..." }`
|
||||
- `verify_transaction()` -- Verify webhook callback:
|
||||
- Validate HMAC using `PAYMOB_SECRET`
|
||||
- On success, extend subscription and create payment record
|
||||
- **Webhook endpoint** (`POST /api/paymob/webhook`):
|
||||
- Verify transaction authenticity
|
||||
- Update subscription on success
|
||||
|
||||
### 1.4 Subscription Extension Logic
|
||||
|
||||
After any successful payment (all providers), the system must:
|
||||
1. Calculate new expiration: `max(current_expiration, now()) + duration_days`
|
||||
2. Update `user.subscription_expiration`
|
||||
3. Create `encoach.subscription.payment` record with provider, amount, transaction ID
|
||||
4. For corporate users: propagate the new expiration to all entity members
|
||||
|
||||
---
|
||||
|
||||
## 2. Missing API Endpoints
|
||||
|
||||
**SRS Reference:** Section 4
|
||||
|
||||
The following endpoints are specified in the SRS but not present in the delivery:
|
||||
|
||||
### 2.1 Exam Variants (add to `encoach_api/controllers/generation.py` or `exams.py`)
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|----------|--------|-------------|
|
||||
| `POST /api/exam/writing/<task>/attachment` | POST | Academic writing Task 1 with image upload (multipart form with `file` + `difficulty`). Must send image to GPT-4o vision API for prompt generation. |
|
||||
| `GET /api/exam/level/` | GET | Return a pre-built level exam (no AI generation) |
|
||||
| `GET /api/exam/level/utas` | GET | Return a UTAS-format level exam |
|
||||
| `POST /api/exam/level/import/` | POST | Import level exam from uploaded file |
|
||||
| `POST /api/exam/level/custom/` | POST | Generate custom level exam from JSON specification |
|
||||
| `POST /api/exam/reading/import` | POST | Import reading exam from Word/Excel file |
|
||||
| `POST /api/exam/listening/import` | POST | Import listening exam from file |
|
||||
|
||||
### 2.2 Entity/Role/Permission Management (new controller files needed)
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|----------|--------|-------------|
|
||||
| `GET /api/entities` | GET | List entities (with pagination) |
|
||||
| `POST /api/entities` | POST | Create entity |
|
||||
| `PATCH /api/entities/<id>` | PATCH | Update entity |
|
||||
| `DELETE /api/entities/<id>` | DELETE | Delete entity |
|
||||
| `GET /api/roles` | GET | List roles (filter by entityID) |
|
||||
| `POST /api/roles` | POST | Create role |
|
||||
| `PATCH /api/roles/<id>` | PATCH | Update role |
|
||||
| `DELETE /api/roles/<id>` | DELETE | Delete role |
|
||||
| `GET /api/permissions` | GET | List permissions |
|
||||
|
||||
### 2.3 Other Missing Endpoints
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|----------|--------|-------------|
|
||||
| `GET /api/discounts` | GET | List discount codes |
|
||||
| `POST /api/discounts` | POST | Create discount code |
|
||||
| `PATCH /api/discounts/<id>` | PATCH | Update discount code |
|
||||
| `DELETE /api/discounts/<id>` | DELETE | Delete discount code |
|
||||
| `GET /api/approval-workflows` | GET | List approval workflows |
|
||||
| `POST /api/approval-workflows` | POST | Create approval workflow |
|
||||
| `PATCH /api/approval-workflows/<id>` | PATCH | Update approval workflow |
|
||||
| `DELETE /api/approval-workflows/<id>` | DELETE | Delete approval workflow |
|
||||
|
||||
---
|
||||
|
||||
## 3. Evaluation Status Endpoint Path
|
||||
|
||||
**SRS Reference:** Section 4.2
|
||||
|
||||
**Current:** `GET /api/evaluate/status?sessionId=...&exerciseId=...` (query params)
|
||||
**SRS specifies:** `GET /api/evaluate/<sessionId>/<exerciseId>` (path params)
|
||||
|
||||
The frontend SRS document (`ODOO_MIGRATION_FRONTEND_SRS.md`) references the path-param version. Please either:
|
||||
- (A) Change the endpoint to use path params to match the SRS, OR
|
||||
- (B) Confirm that query params are intentional so we can update the frontend SRS
|
||||
|
||||
---
|
||||
|
||||
## 4. Record-Level Security Rules (`ir.rule`)
|
||||
|
||||
**SRS Reference:** Section 5
|
||||
|
||||
The delivery has model-level ACL rules (`ir.model.access.csv`) for each module, which is good. However, record-level security rules (`ir.rule`) are also needed to ensure:
|
||||
|
||||
- **Students** can only read/write their own records (sessions, stats, evaluations, training, tickets)
|
||||
- **Teachers** can see records for students in their groups/assignments
|
||||
- **Corporate** users can see records within their entity
|
||||
- **Admin/Developer** users have unrestricted access
|
||||
|
||||
Example rules needed (add to each module's `security/` directory):
|
||||
|
||||
```xml
|
||||
<!-- encoach_stats/security/rules.xml -->
|
||||
<record id="rule_stat_student_own" model="ir.rule">
|
||||
<field name="name">Students see own stats</field>
|
||||
<field name="model_id" ref="model_encoach_stat"/>
|
||||
<field name="groups" eval="[(4, ref('encoach_core.group_encoach_student'))]"/>
|
||||
<field name="domain_force">[('user_id', '=', user.id)]</field>
|
||||
</record>
|
||||
```
|
||||
|
||||
Models that need record rules:
|
||||
- `encoach.session` -- students see own sessions only
|
||||
- `encoach.stat` -- students see own stats only
|
||||
- `encoach.evaluation` -- students see own evaluations only
|
||||
- `encoach.training` -- students see own training only
|
||||
- `encoach.ticket` -- students see own tickets, admins see all
|
||||
- `encoach.assignment` -- students see assignments they're assigned to
|
||||
- `encoach.exam` -- filtered by access field (public/private/entity)
|
||||
|
||||
---
|
||||
|
||||
## 5. Whisper Scaling
|
||||
|
||||
**SRS Reference:** Section 6.5
|
||||
|
||||
**Current:** Single lazy-loaded Whisper model instance in `whisper_service.py`
|
||||
**SRS specifies:** 4 model instances with `ThreadPoolExecutor(max_workers=4)` for parallel transcription
|
||||
|
||||
Update `encoach_ai_media/services/whisper_service.py` to:
|
||||
1. Load the configurable number of model instances (from `encoach.whisper_workers` system parameter, default 4)
|
||||
2. Use `concurrent.futures.ThreadPoolExecutor` to process transcription requests in parallel
|
||||
3. Round-robin or queue-based assignment of requests to model instances
|
||||
|
||||
This is important for production performance when multiple students submit speaking exams simultaneously.
|
||||
|
||||
---
|
||||
|
||||
## 6. FAISS Index Type
|
||||
|
||||
**SRS Reference:** Section 6.8
|
||||
|
||||
**Current:** `faiss.IndexFlatIP` (inner product)
|
||||
**SRS specifies:** `faiss.IndexFlatL2` (L2/Euclidean distance)
|
||||
|
||||
The current implementation normalizes vectors and uses inner product, which effectively gives cosine similarity. This works correctly, but it's a deviation from the SRS. If the original `ielts-be` training data was built with L2 distance, the results may differ slightly. Please verify which index type the original system used and align accordingly.
|
||||
|
||||
---
|
||||
|
||||
## 7. Payment Webhook Endpoints
|
||||
|
||||
**SRS Reference:** Section 7
|
||||
|
||||
In addition to the payment service implementations (Item 1 above), the following webhook controller routes need to be added to `encoach_api/controllers/subscriptions.py`:
|
||||
|
||||
```python
|
||||
@http.route('/api/stripe/webhook', type='http', auth='public', methods=['POST'], csrf=False, cors='*')
|
||||
def stripe_webhook(self, **kwargs):
|
||||
"""Handle Stripe webhook events (checkout.session.completed, etc.)."""
|
||||
...
|
||||
|
||||
@http.route('/api/paymob/webhook', type='http', auth='public', methods=['POST'], csrf=False, cors='*')
|
||||
def paymob_webhook(self, **kwargs):
|
||||
"""Handle Paymob transaction callbacks."""
|
||||
...
|
||||
```
|
||||
|
||||
These must be `auth='public'` (no JWT) since they're called by external services.
|
||||
|
||||
---
|
||||
|
||||
## Summary of Action Items
|
||||
|
||||
| # | Item | Priority | Status |
|
||||
|---|------|----------|--------|
|
||||
| 1 | Payment integration (Stripe/PayPal/Paymob) | **Critical** | RESOLVED |
|
||||
| 2 | Missing API endpoints (~20 endpoints) | **High** | RESOLVED |
|
||||
| 3 | Evaluation status endpoint path alignment | **Medium** | RESOLVED |
|
||||
| 4 | `ir.rule` record-level security rules | **High** | RESOLVED |
|
||||
| 5 | Whisper multi-instance scaling | **Medium** | RESOLVED |
|
||||
| 6 | FAISS index type verification | **Low** | RESOLVED |
|
||||
| 7 | Payment webhook endpoints | **Critical** | RESOLVED |
|
||||
|
||||
---
|
||||
|
||||
## Changes Already Applied
|
||||
|
||||
The following small fixes have been applied directly to the codebase:
|
||||
|
||||
1. **`encoach_ai_media/__manifest__.py`** -- Added missing `external_dependencies`: `numpy`, `openai-whisper`, `librosa`, `soundfile`, `httpx`
|
||||
2. **`encoach_training/__manifest__.py`** -- Added missing `external_dependencies`: `numpy`, `faiss-cpu`, `sentence-transformers`
|
||||
3. **`requirements.txt`** -- Created at project root with all Python dependencies and versions from SRS Section 6.10
|
||||
Reference in New Issue
Block a user