feat(backend): Phase 2/3 hardening release
Roadmap P0 — platform safety & ops
- Merge duplicate encoach.student.attempt/answer models into encoach_scoring
and drop the stale encoach_exam_template copies.
- Remove duplicate /api/exam/* routes; canonicalize on one controller tree.
- Gate raw-SQL seeds in seed_demo_data.py behind an explicit env flag.
- Add /api/health and /api/health/ready (DB + LLM reachability) endpoints.
- Fix docker-compose + ship odoo-docker.conf for container-local runs.
- Enforce OpenAI request_timeout=30s and @jwt_required on all AI/coach routes.
- Promote canonical cefr_mapper to encoach_ai.services.cefr_mapper.
- JWT cache TTL=30s + invalidation hook on user mutation.
Roadmap P1 — exam correctness & data provenance
- Wire QualityChecker + IeltsValidator into exam submit with a
pending_review gate (encoach_ai.services.question_validator).
- Populate RAG metadata (course_id, subject_id, entity_id, taxonomy) on
encoach_vector embeddings and add a chunking pipeline (>2000 chars).
- Add provenance fields on encoach.question (model, prompt_hash, log_id)
and validate LLM output with schema before DB insert.
- Unify response envelope to {items,total,page,size}.
- Approval reject rollback with savepoint atomicity.
- Ticket notifications on status/assignee change.
Roadmap P2 — performance & observability
- Reports: replace Python loops with SQL read_group aggregations.
- X-Request-ID middleware + structured JSON logs.
- In-process/Prometheus counters and openapi.py controller exporting a
spec by scanning @http.route decorators.
- Paymob real checkout + HMAC-SHA512 webhook verification, backed by a
new encoach.paymob.order model and ir.config_parameter credentials.
- JWT refresh tokens + revocation table.
- Composite DB indexes on hot report/ticket/attempt paths.
Roadmap P3 — human-in-the-loop & compliance
- Human-in-the-loop exam review workflow (pending_review → publish) with
new review controller and status transitions.
- encoach.ai.prompt model + versioning + admin editor endpoints (one
active version per key, render-preview dry run).
- Student feedback loop → encoach.ai.feedback (upsert per user/subject,
admin triage + resolve endpoints).
- GDPR export (/api/gdpr/export) and right-to-erasure (/api/gdpr/delete)
with anonymization, tombstone record, and admin-self-erasure guard.
- HttpCase smoke tests for /api/health and /api/health/ready.
Made-with: Cursor
This commit is contained in:
@@ -1,10 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Comprehensive demo data seeder for EnCoach platform."""
|
||||
"""Legacy raw-SQL demo data seeder for EnCoach platform.
|
||||
|
||||
⚠️ DANGER ⚠️ — this script talks to Postgres directly with a hardcoded DB user
|
||||
and bypasses all Odoo ORM validation, constraints, and record rules. It exists
|
||||
only for historical/bootstrapping reasons and MUST NOT be run against any
|
||||
shared or production database.
|
||||
|
||||
Running it requires:
|
||||
|
||||
1. ``ENCOACH_ALLOW_RAW_SEED=1`` in the environment (explicit opt-in).
|
||||
2. Connection parameters via environment variables, e.g.
|
||||
``PGDATABASE``, ``PGHOST``, ``PGUSER``, ``PGPASSWORD``.
|
||||
|
||||
The **preferred** seeder for a fresh dev environment is ``seed_institutional.py``
|
||||
(Odoo-shell, ORM-based, idempotent). See P0.6 in docs/PROJECT_SUMMARY.md §21.
|
||||
"""
|
||||
|
||||
import json
|
||||
import psycopg2
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
conn = psycopg2.connect(dbname='encoach_v2', host='localhost', port=5432, user='yamenahmad')
|
||||
if os.environ.get("ENCOACH_ALLOW_RAW_SEED") != "1":
|
||||
sys.stderr.write(
|
||||
"\nseed_demo_data.py refused to run: set ENCOACH_ALLOW_RAW_SEED=1 to "
|
||||
"explicitly opt in.\n"
|
||||
"This script writes raw SQL against PostgreSQL and bypasses the "
|
||||
"Odoo ORM — prefer seed_institutional.py for everyday seeding.\n"
|
||||
)
|
||||
sys.exit(2)
|
||||
|
||||
import psycopg2
|
||||
|
||||
conn = psycopg2.connect(
|
||||
dbname=os.environ.get("PGDATABASE", "encoach_v2"),
|
||||
host=os.environ.get("PGHOST", "localhost"),
|
||||
port=int(os.environ.get("PGPORT", "5432")),
|
||||
user=os.environ.get("PGUSER", os.environ.get("USER", "odoo")),
|
||||
password=os.environ.get("PGPASSWORD", ""),
|
||||
)
|
||||
conn.autocommit = True
|
||||
cur = conn.cursor()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user