feat: initial backend codebase — EnCoach v3

Complete Odoo 19 backend with 25 custom addons:
- encoach_core: user/entity/role management
- encoach_api: REST API + JWT auth
- encoach_ai: OpenAI integration, AI settings, generation
- encoach_ai_course: AI-powered English & IELTS course generation
- encoach_exam_template/session: exam creation, structures, sessions
- encoach_scoring: AI auto-grading + manual approval
- encoach_vector: pgvector RAG integration
- encoach_adaptive: adaptive learning engine
- encoach_placement: placement testing
- encoach_taxonomy/resources: content taxonomy & resource management
- Plus 14 more modules for courses, branding, portal, etc.

Includes docs: user guide, generation report, developer workflow.

Made-with: Cursor
This commit is contained in:
Yamen Ahmad
2026-04-11 15:44:20 +04:00
commit 982d4bca30
371 changed files with 35211 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_cat_session_form" model="ir.ui.view">
<field name="name">encoach.cat.session.form</field>
<field name="model">encoach.cat.session</field>
<field name="arch" type="xml">
<form string="CAT Session">
<header>
<field name="status" widget="statusbar" statusbar_visible="active,completed"/>
</header>
<sheet>
<group>
<group>
<field name="student_id"/>
<field name="subject_id"/>
<field name="current_section"/>
</group>
<group>
<field name="started_at"/>
<field name="completed_at"/>
<field name="current_theta"/>
<field name="current_sem"/>
<field name="questions_answered"/>
</group>
</group>
<notebook>
<page string="Autosave Data" name="autosave">
<field name="autosave_data"/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="view_cat_session_list" model="ir.ui.view">
<field name="name">encoach.cat.session.list</field>
<field name="model">encoach.cat.session</field>
<field name="arch" type="xml">
<list string="CAT Sessions">
<field name="student_id"/>
<field name="status" widget="badge" decoration-info="status == 'active'" decoration-success="status == 'completed'" decoration-danger="status == 'abandoned'"/>
<field name="current_theta"/>
<field name="current_sem"/>
<field name="questions_answered"/>
<field name="started_at"/>
</list>
</field>
</record>
<record id="view_cat_session_search" model="ir.ui.view">
<field name="name">encoach.cat.session.search</field>
<field name="model">encoach.cat.session</field>
<field name="arch" type="xml">
<search string="Search CAT Sessions">
<field name="student_id"/>
<separator/>
<filter string="Active" name="active" domain="[('status', '=', 'active')]"/>
<filter string="Completed" name="completed" domain="[('status', '=', 'completed')]"/>
<filter string="Abandoned" name="abandoned" domain="[('status', '=', 'abandoned')]"/>
<separator/>
<filter string="Student" name="group_student" context="{'group_by': 'student_id'}"/>
</search>
</field>
</record>
<record id="action_cat_session" model="ir.actions.act_window">
<field name="name">Placements</field>
<field name="res_model">encoach.cat.session</field>
<field name="view_mode">list,form</field>
</record>
</odoo>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<menuitem id="menu_placements"
name="Placements"
parent="encoach_core.menu_encoach_students"
action="encoach_placement.action_cat_session"
sequence="20"/>
<menuitem id="menu_student_abilities"
name="Student Abilities"
parent="encoach_core.menu_encoach_students"
action="encoach_placement.action_student_ability"
sequence="30"/>
</odoo>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_student_ability_form" model="ir.ui.view">
<field name="name">encoach.student.ability.model.form</field>
<field name="model">encoach.student.ability.model</field>
<field name="arch" type="xml">
<form string="Student Ability">
<sheet>
<group>
<group>
<field name="student_id"/>
<field name="subject_id"/>
<field name="skill"/>
</group>
<group>
<field name="theta"/>
<field name="sem"/>
<field name="last_updated"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_student_ability_list" model="ir.ui.view">
<field name="name">encoach.student.ability.model.list</field>
<field name="model">encoach.student.ability.model</field>
<field name="arch" type="xml">
<list string="Student Abilities">
<field name="student_id"/>
<field name="skill"/>
<field name="theta"/>
<field name="sem"/>
<field name="last_updated"/>
</list>
</field>
</record>
<record id="view_student_ability_search" model="ir.ui.view">
<field name="name">encoach.student.ability.model.search</field>
<field name="model">encoach.student.ability.model</field>
<field name="arch" type="xml">
<search string="Search Student Abilities">
<field name="student_id"/>
<separator/>
<filter string="Listening" name="listening" domain="[('skill', '=', 'listening')]"/>
<filter string="Reading" name="reading" domain="[('skill', '=', 'reading')]"/>
<filter string="Writing" name="writing" domain="[('skill', '=', 'writing')]"/>
<filter string="Speaking" name="speaking" domain="[('skill', '=', 'speaking')]"/>
<filter string="Grammar" name="grammar" domain="[('skill', '=', 'grammar')]"/>
<filter string="Vocabulary" name="vocabulary" domain="[('skill', '=', 'vocabulary')]"/>
<separator/>
<filter string="Student" name="group_student" context="{'group_by': 'student_id'}"/>
<filter string="Subject" name="group_subject" context="{'group_by': 'subject_id'}"/>
</search>
</field>
</record>
<record id="action_student_ability" model="ir.actions.act_window">
<field name="name">Student Abilities</field>
<field name="res_model">encoach.student.ability.model</field>
<field name="view_mode">list,form</field>
</record>
</odoo>