d5b1987bba1d80b1b4a37f865dfde9c3c7ca0a71
10 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d5b1987bba |
feat(platform): full institutional roadmap — exam security, live sessions, handwritten, personalized AI plans, Turnitin, lesson polish
Backend (encoach_lms_api):
- New models: encoach.exam.security.event, encoach.live.session,
encoach.live.session.participant, encoach.handwritten.submission.
- Extended: encoach.exam.custom (security_level, single_attempt,
suspicious_event_threshold), encoach.course.plan (is_personalized,
personalized_for_id, weakness_summary), encoach.entity (turnitin_*).
- New controllers / 24 endpoints:
* exam_security: POST /api/exam/security/event,
GET /api/exam/single-attempt-check,
GET /api/teacher/exam/<id>/security/events,
GET /api/teacher/exam/attempt/<id>/security/events,
GET /api/teacher/exam/<id>/live.
* live_sessions: full CRUD + /notify, /join, /leave, /end,
/recording, /remove-participant, /attendance, /ics
(RFC-5545 iCalendar with VALARM + ATTENDEE/ORGANIZER, attached to
invite emails so Gmail/Outlook/Apple Mail prompt to add).
* personalized_plan: GET/POST /api/student/personalized-plan
(CEFR / weeks / focus / grammar_focus payloads).
* handwritten: student upload + AI grading (pytesseract OCR +
OpenAI scoring) + teacher review override.
* reports_export: CSV + PDF export for student-performance and
record reports.
* turnitin: per-entity settings (admin), test connection, submit
text. Real upload stubbed pending institutional API key.
- Manifest: depends now lists encoach_scoring, encoach_exam_template,
encoach_ai_course so security/live-session models load cleanly.
- teacher_insights.py: fixed assignment traversal via op.batch.course_id,
res.users mapping, and capped rate_completed at 100% (unique
student/exam pairs).
- reports.py: branch_id / subject_id / gender filters wired into the
Reports stack.
Frontend:
- New services: examSecurity, liveSession, personalizedPlan,
handwritten, turnitin, reportsExport.
- New pages: LiveSessionsPage, LiveSessionRoom (Jitsi IframeAPI embed
with host bar — Mute all / Cams off / per-row Ask-to-unmute /
Remove + log audit reason, kickParticipant after backend audit POST),
TurnitinSettings (admin), TeacherTestSessionConsole, AddToCalendar
per-card .ics button.
- New components: PersonalizedPlanCard (Quick generate + Customize
dialog: CEFR, weeks, focus, 9-checkbox grammar), AITutorAvatar,
HandwrittenSubmissionPanel, ImageLightbox, InfographicBlock
(six-tone callout with key-based auto-detect — did_you_know,
key_takeaway, tip, objective, common_mistakes, etc.), ExportButtons.
- useExamSecurity hook: tab/blur, copy/paste/cut, fullscreen exit,
suspicious shortcuts; debounced auto-post + auto-lock callback.
- StudentCourseDetail / TeacherCourseInsights: discussion now
embedded as a per-course tab.
- StudentCourses: unified My Courses + My Course Plan with
is_mandatory color-coding + Accredited Core / Supplementary
sections (always rendered, with empty states).
- MaterialBookView: special-cases image keys into ImageLightbox,
routes infographic-style keys into colored InfographicBlock cards,
splits long strings into paragraphs, rounded-2xl shadow-sm wrapper.
- MaterialViewer: ImageViewer now uses lightbox, ArticleViewer is
now a real <article class="prose">.
- Layout shells: Live Sessions in Student/Teacher sidebars, Turnitin
in Admin sidebar; EN + AR i18n keys.
- App.tsx: lazy routes for /live, /live/:id,
/teacher/exam/:assignmentId/console, /admin/turnitin.
- Visual identity refresh: warm cream bg, white sidebar with charcoal
active pills, dark CTA buttons, bright orange accents,
rounded-2xl cards.
Verification:
- All 12 new endpoints smoke-tested via curl (200 + sane payloads).
- /api/live-sessions/<id>/ics returns valid 23-line VCALENDAR.
- Frontend tsc --noEmit clean.
- Odoo restarted successfully (registry loaded in 0.77s, no errors).
- docs/PROJECT_SUMMARY.md updated with both today's polish + the
full Phase 2/3/4 rollout for the record.
Status: 27/29 institutional requirements fully wired. Turnitin
upload + LMS-side breakout/poll persistence remain partial (see
PROJECT_SUMMARY for details).
Made-with: Cursor
|
||
|
|
35ccc0dfb2 |
feat(platform): ship AI fallback stack and entity-scoped course planning
Unifies the new LangGraph-driven course-plan/media flow with robust provider fallbacks, admin AI provider settings, editable book-style materials, and strict entity isolation across LMS/course-plan APIs. Adds admin-only entity membership management in the Entities UI so users can switch linked entities directly from the platform. Made-with: Cursor |
||
|
|
e2aa8031ff |
feat(ai): LangGraph as core runtime + AI Agents/Tools console + full-demo seed
Core AI runtime - New encoach.ai.agent + encoach.ai.tool models with M2M tool binding, graph topology (simple|plan_review_revise|rag|react), model + fallback, temperature, max_tokens, response_format, max_revisions, quality checks and system prompt fields. - services/agent_runtime.py compiles a langgraph.StateGraph per agent and caches the build per (key, write_date). Emits a structured trace (output, tool_calls, retrieval_hits, revisions, quality_issues, ms, model_used, fallback_used) and auto-falls-back on rate-limit/5xx. - services/agent_tools.py registers 11 tool handlers wrapping existing services: resources.search, rubric.fetch, outcomes.fetch, student.profile, quality.cefr_check, quality.ai_detect, quality.content_gate, course_plan.save (mutates), course_plan.save_materials (mutates), scoring.grade_writing, scoring.grade_speaking. - 7 default agents seeded via data/agents_defaults.xml: course_planner, course_week_materials, exam_generator, exercise_generator, lms_tutor, writing_grader, speaking_grader. - Feature flag encoach_ai.use_langgraph_runtime (default True). - encoach_ai_course pipeline now routes through AgentRuntime when on, legacy SDK path kept as fallback. Admin UI - /admin/ai/prompts is now a tabbed Agents | Tools | Prompts console. - AIAgentsPanel: card grid + config dialog (model/temp/graph/tools/ system prompt) + built-in Test Runner showing live trace. - AIToolsPanel: registry table with category badges, mutates flag, schema viewer, edit dialog. - New /api/ai/agents* and /api/ai/tools* controller (list/get/update/ test, list-tools, toggle-tool). - Sidebar label nav.aiPrompts -> nav.aiAgents (AI Agents and Tools). - EN + AR (RTL) translations for ~80 new keys. Smart Wizard pages - /admin/quick-setup hub + CourseWizard, CoursePlanWizard, RubricWizard, ExamStructureWizard step-by-step flows. - /admin/course-plans list + detail pages. - /teacher/quick-setup mirror. Full demo seed + 8-role E2E - seed_full_demo.py adds the 5 missing user_types (approver, corporate, mastercorporate, agent, developer), activates a 2-stage exam-approval workflow with one pending request, creates a GE1-aligned 12-week B1 course plan with 6 detailed Week-1 materials (reading 400w, writing, listening 4-min script, speaking, grammar present simple vs continuous, vocabulary), and inserts sample ai.log + ai.feedback rows. - reset_demo_passwords.py forces every demo login back to canonical passwords (admin123/teacher123/student123/approver123/corporate123/ master123/agent123/dev123). - e2e_full_scenario.py: 46/46 PASS read-only API smoke across all 8 roles, including a live LangGraph round-trip on writing_grader. - e2e_approval_chain.py: 6/6 PASS mutation E2E - approver approves stage 1, admin approves stage 2, linked encoach.exam.custom flips to status=published, verified via psql. Docs - docs/PROJECT_SUMMARY.md updated to 2026-04-25: new Latest events bullets, refreshed credentials table, full sections 22 (LangGraph runtime) and 23 (full demo seed + 8-role E2E). - docs/ENCOACH_FULL_DEMO_QA_REPORT.md added with credentials, per-endpoint PASS/FAIL, mutation chain proof, LangGraph live output. - backend/GE1 Course Outline_ Fall AY25-26.pdf vendored as the reference outline the GE1 plan/materials are aligned to. Dependencies - requirements.txt: langgraph>=0.2.0, langchain-core>=0.3.0. - encoach_ai/__manifest__.py: external_dependencies updated. Made-with: Cursor |
||
|
|
75ee0f1fe0 |
fix(ui): actionable 413/504/401 toasts + VPS nginx deploy template
Production QA reported "Submit failed 413" on /generation and plain "Upload failed" (no detail) on resource upload. Root cause is the outer reverse-proxy nginx on the VPS — still on default `client_max_body_size 1m` — rejecting requests before they reach Odoo. The inner docker-nginx and Odoo limits were already raised in earlier commits; only the VPS proxy was left unpatched. UI side - Add `describeApiError(err, fallback, context)` helper in lib/api-client.ts. Maps common HTTP codes to human-readable, actionable toast descriptions (413 → "ask ops to raise nginx client_max_body_size", 504 → "server took too long, retry", 502 → "Odoo is restarting", 401 → "sign in again", 4xx/5xx → server error body + status code). - Use it in GenerationPage submit, ResourceManager upload, TeacherLibrary upload, CustomExamCreate save/publish. Replaces four slightly-different ad-hoc mappings with one source of truth. Deploy side - Add deploy/nginx-vps.conf.example: full TLS reverse-proxy template with the body/timeout knobs that must match Odoo's limit_request (128 MB) and limit_time_real (900 s). - Add docs/DEPLOY_413_504_FIX.md: step-by-step remediation guide for the team lead covering the 3 layers that can block large bodies (outer nginx, Cloudflare, Odoo worker) and how to verify each. Made-with: Cursor |
||
|
|
a554ef5d42 |
fix(qa): approval queue, rubric UX, structure enforcement, upload/publish limits
Addresses the QA notes on the end-to-end approval flow. Highlights:
Backend
- encoach_ai/generation_submit: create encoach.approval.request on submit so
submitted exams actually reach the approver queue (previously only the
workflow id was stored on the exam, leaving approvers with an empty inbox).
Initial exam status flips to pending_approval instead of draft.
- encoach_exam_template/approval_workflows:
* /api/approval-users filters out students (user_type='student',
op_student_id set, share=True) so the approver dropdown only lists staff.
* _ser_request enriches requests with target_name / target_status and the
current stage approver for UI badges.
* list_requests supports mine=1 / requester=1 so approvers only see queue
items awaiting their action.
* approve_request / reject_request now transition the underlying
encoach.exam.custom to published / rejected on final approval.
- encoach.exam.custom.status: add pending_approval and rejected states to
match the approval workflow transitions.
Frontend UX
- GenerationPage: rubric field shows "Auto-graded — no rubric" for Listening
and Reading (rubrics only apply to Writing / Speaking). Divider dropdowns
now carry explicit help text explaining None / Line / Space / Page Break
and where to write prompts. Selecting an official exam structure
auto-populates the required tasks/sections/parts, the delete button is
hidden for essential tasks, and submit is blocked if the user dropped
below the structure's required count.
- RubricsPage: "Add Criterion" is now a dropdown with IELTS-specific
presets (Task Achievement, Coherence & Cohesion, Fluency & Coherence, …)
keyed off the selected skill, plus a "Custom (blank row)" fallback.
- AdminCourses: added tooltips and helper copy clarifying Difficulty vs
CEFR Level in the Create Course dialog.
- CustomExamCreate: validate the whole form before Save/Publish, surface
backend error messages (413/504/401) instead of a generic toast, read the
exam id from the correct response field, and avoid marking Publish as
failed when only the optional Save-as-Template step errors.
- ResourceManager / TeacherLibrary: upload toast now shows a concrete
reason (HTTP 413 / 504 / 401) instead of a generic "Upload failed".
Config (504 / 413 / resource upload fixes)
- odoo.conf + odoo-docker.conf: raise limit_time_cpu to 600s,
limit_time_real to 900s, limit_request to 128 MB, and memory caps so
/api/exam/generation/submit and multipart resource uploads stop hitting
504 / 413 during QA.
- frontend/Dockerfile (nginx): add client_max_body_size 128m, bump
proxy_read_timeout / proxy_send_timeout to 900s, and disable request
buffering so large AI/resource payloads stream through the proxy.
Made-with: Cursor
|
||
|
|
e1f059069f |
feat(i18n,rtl): full Arabic localization + RTL sweep across all layouts
Frontend - i18n: install tailwindcss-rtl, Cairo font, RTL-aware direction in index.css. - Language toggle: localize aria-label / menu label, persist choice, update document dir synchronously. - Sidebar: add `side` prop so the drawer pins to the right in RTL; wire up AdminLmsLayout, RoleLayout (student/teacher) and AppSidebar to pass side = i18n.dir() === 'rtl' ? 'right' : 'left'. - AdminLmsLayout: convert every nav item from hard-coded title to titleKey, translate group labels (incl. the collapsible Training), breadcrumbs, user menu (Profile / Settings / Logout), help button and toggle aria labels; replace physical mr-/right- utilities with logical me-/end-. - AI components (AiTipBanner, AiInsightsPanel, AiAlertBanner, AiSearchBar, AiAssistantDrawer): apply dir="auto" at the container level, localize titles, loading / error / empty states. - Dashboards (admin / student / teacher): wrap numeric values in <bdi>, localize dates via ar-EG, fix flex direction for KPI and assignment cards. - UI primitives (breadcrumb, calendar, carousel, dropdown-menu, menubar, context-menu, pagination, sidebar): flip chevrons in RTL via a scoped CSS rule, swap pl-/pr-/ml-/mr- for ps-/pe-/ms-/me-. - Add logical-direction helpers and bidirectional isolation classes. Locales - Expand en.ts and ar.ts with full `nav`, `sidebarGroup`, `breadcrumb`, `userMenu`, `chrome`, `ai`, and dashboard key sets; keep key parity. API client - `api-client.ts` reads the active language from localStorage/i18n and sends `Accept-Language` on every request so the backend can localize AI output. Backend (encoach_ai) - openai_service: add _LANGUAGE_NAMES, normalize_language, language-aware system prompt injection for every OpenAI call. - coach_service + controllers (coach_controller, ai_controller): thread the requested language from headers / user locale down to OpenAIService. - ai_feedback: fix latent registry error by pointing course_id at op.course instead of the non-existent encoach.course. Other - .gitignore: ignore runtime odoo logs and local caches. Made-with: Cursor |
||
|
|
e70a2854f4 |
feat(frontend): Phase 2/3 hardening release
Roadmap P0
- Ship /logo.svg fallback and rewire asset references (superseded later by
the project-manager PNG in a separate commit).
Roadmap P1
- Response envelope alignment ({items,total,page,size}) across services
and query hooks.
- Approval/ticket UX updates tied to the new backend rollback semantics.
Roadmap P2
- React.lazy + Vite manualChunks to split vendor-radix/charts/icons/forms
from the main bundle and cut initial JS.
- Fix the 181 tsc errors (PaginationParams class + per-service generics).
- Auto-refresh flow for JWT refresh tokens wired into api-client.ts.
Roadmap P3
- i18n: i18next + language detector, en/ar locales, RTL auto-switch,
LanguageToggle component in RoleLayout and AdminLmsLayout.
- GDPR: PrivacyCenter page for data export and right-to-erasure, backed
by gdpr.service.ts; logout via AuthContext after erasure.
- Human-in-the-loop exam review UI: admin ExamReviewQueue + ExamReviewDetail
pages, useExamReview hooks, exam-review.service.ts.
- AI quality loop: AIPromptEditor (versioning + render preview),
AIFeedbackButtons for students, AIFeedbackTriage admin page, dedicated
services, hooks, and types.
- Dark mode: ThemeProvider + ThemeToggle + chart color tokens.
- Accessibility: DialogDescription on every DialogContent; alert-dialog
and sheet updates.
- Retire dead pages: ExamPage marketing, Index, ProfilePage import.
- Playwright e2e scaffolding: playwright.config.ts + e2e/login.spec.ts
smoke tests, npm scripts test:e2e / test:e2e:install.
Made-with: Cursor
|
||
|
|
98b9837a54 |
feat: institutional + support + training admin sections (backend + frontend)
Ship three fully-wired admin areas end-to-end with APIs, seeds, tests and docs. Backend (new `encoach_lms_api` addon + existing addons): - Institutional: academic years/terms, departments, admission registers & admissions, courses/batches, lessons, fees (terms + student fees + invoicing with income-account auto-wiring), gradebook (assignments/grades), library, facilities (encoach.asset), student leave, result templates + marksheets (incl. delete-with-cascade). - Support: `encoach.ticket` model + CRUD/assignee routes; payment records derived from `op.student.fees.details` and `account.move`; platform settings backed by `encoach.code` and `ir.config_parameter` (packages + grading config). - Training: `encoach.vocab.item` + `encoach.grammar.rule` (plus progress models) with CRUD, pagination, search/level filters, and upsert-style progress endpoints. Odoo 19 compatibility: `_sql_constraints` replaced with `@api.constrains`; `ValidationError`/`UserError` mapped to HTTP 400. Frontend: - Rewire institutional admin pages (Academic Year Manager, Admissions, Courses, Lessons, Fees, Gradebook, Library, Facilities, Student Leave, Marksheets, Taxonomy, Resources) to real APIs with React Query invalidation and dialogs. - New typed services: `payments.service.ts`, `platformSettings.service.ts`, `training.service.ts`. Updated `fees/gradebook/lms/courseware/taxonomy/ resources/student-progress/generation` services + related types. - Rewrite `VocabularyPage`, `GrammarPage`, `PaymentRecordPage`, `SettingsPage`, `TicketsPage` to consume live data with search/filter/progress/CRUD flows. - New shared components: `TaxonomyCascade`, `MaterialViewer`, `teacher/TeacherLibrary`. - Favicons/branding assets and misc. UX polish across teacher/student pages. Tooling & QA: - Seeders: `seed_demo.py`, `seed_demo_data.py`, `seed_institutional.py` (idempotent, covers institutional + support + training fixtures incl. income-account wiring). - API write-flow test suites: `test_write_flows.py` (institutional), `test_support_flows.py` (support), `test_training_flows.py` (training), `test_ai_full.py`. All suites pass end-to-end. - Docs: add `docs/PROJECT_SUMMARY.md` with per-section scope, artifacts and QA. - `.gitignore`: ignore `pgdata_bak_*/`, `frontend/.vite/`, `frontend/dist/`, `frontend/node_modules/`. Made-with: Cursor |
||
|
|
82ec3debcc |
feat: QA fixes, new APIs (assignments, rubrics, custom exams), Generation page enhancements
- Fix ELAI video generation (correct render endpoint, script splitting for 60s limit) - Fix speaking script generation error handling and empty response display - Add custom exam list API (GET /api/exam/custom/list) - Add assignments REST API (list, create, get) - Add rubrics REST API (list, create) - Enhance Generation page: dynamic exam structures, auto-module selection, preview dialog, audio player - Improve submit feedback with exam ID and status in toast notifications - Fix ExamsListPage to show both custom exams and exam sessions - Connect RubricsPage to backend API with fallback data - Add Dockerfile, docker-compose.yml, requirements.txt for deployment - Fix placement, grading, scoring, and auth controllers - Add ErrorBoundary component for frontend resilience - Add QA report and credentials documentation Made-with: Cursor |
||
|
|
f1c4953a63 |
feat(v3): restructure project + add complete frontend
- Restructure: move backend from new_project/ to backend/ - Add full React/TypeScript frontend (37 pages, 17 services, 16 type defs, 11 query hooks) - Add docs/ with SRS specs, user stories, and workflow documentation - Update .gitignore for new directory layout Workflows implemented: WF1 User Signup, WF2 Placement Test, WF3 Exam Configuration, WF4 General English Exam, WF5 Course Generation, WF6 Entity Student Onboarding, AI Course Generation, Adaptive Learning Engine UI, White-Label Branding, Score Release Made-with: Cursor |