feat: complete all 12 missing spec features from EnCoach v3.0 audit
- Add student_progress, course_section models and module_resources M2M - Activate encoach_resources module with security, views, and ielts_certified field - Add password strength indicator JS on registration page - Rewrite onboarding wizard step 4 as placement test prompt with skip option - Dynamic goal list fetched from exam templates in DB with fallback - B1 default CEFR level assigned when placement test is skipped - Teacher review dashboard with 2 API endpoints for AI content approval - IELTS examiner review interface with review_status, examiner_notes fields - Content source gate: mandatory review for AI, spot-check for certified - Resource-to-learning-style matching in adaptive engine - Daily cron job for teacher no-progress alerts via mail.activity - Entity student placement redirect on dashboard access - Fix Odoo 19 compat: search view groups, ir.cron fields, OWL xml templates Made-with: Cursor
This commit is contained in:
@@ -198,16 +198,39 @@ class EncoachSignupController(http.Controller):
|
||||
@jwt_required
|
||||
def onboarding_goals(self, **kw):
|
||||
try:
|
||||
goals = [
|
||||
{'id': 'ielts', 'name': 'IELTS Preparation',
|
||||
'icon': 'mdi-book-education'},
|
||||
{'id': 'general_english', 'name': 'General English',
|
||||
'icon': 'mdi-translate'},
|
||||
{'id': 'math', 'name': 'Mathematics',
|
||||
'icon': 'mdi-calculator-variant'},
|
||||
{'id': 'it', 'name': 'Information Technology',
|
||||
'icon': 'mdi-laptop'},
|
||||
]
|
||||
# Dynamic goals from exam templates in DB
|
||||
Template = request.env['encoach.exam.template'].sudo()
|
||||
templates = Template.search([('active', '=', True)])
|
||||
seen = set()
|
||||
goals = []
|
||||
icon_map = {
|
||||
'ielts': 'fa-language',
|
||||
'general_english': 'fa-comments',
|
||||
'general english': 'fa-comments',
|
||||
'academic': 'fa-graduation-cap',
|
||||
'math': 'fa-calculator',
|
||||
'mathematics': 'fa-calculator',
|
||||
'it': 'fa-laptop',
|
||||
'information technology': 'fa-laptop',
|
||||
}
|
||||
for tpl in templates:
|
||||
subj = tpl.subject_id
|
||||
if subj and subj.name and subj.name.lower() not in seen:
|
||||
seen.add(subj.name.lower())
|
||||
goal_id = subj.name.lower().replace(' ', '_')
|
||||
goals.append({
|
||||
'id': goal_id,
|
||||
'name': subj.name,
|
||||
'icon': icon_map.get(goal_id, icon_map.get(subj.name.lower(), 'fa-book')),
|
||||
})
|
||||
# Fallback if no templates found
|
||||
if not goals:
|
||||
goals = [
|
||||
{'id': 'ielts', 'name': 'IELTS Preparation', 'icon': 'fa-language'},
|
||||
{'id': 'general_english', 'name': 'General English', 'icon': 'fa-comments'},
|
||||
{'id': 'math', 'name': 'Mathematics', 'icon': 'fa-calculator'},
|
||||
{'id': 'it', 'name': 'Information Technology', 'icon': 'fa-laptop'},
|
||||
]
|
||||
return _json_response({'goals': goals})
|
||||
|
||||
except Exception as e:
|
||||
@@ -229,6 +252,8 @@ class EncoachSignupController(http.Controller):
|
||||
if not learning_goal:
|
||||
return _error_response('learning_goal is required', 400)
|
||||
|
||||
skip_placement = body.get('skip_placement', False)
|
||||
|
||||
profile_vals = {
|
||||
'user_id': user.id,
|
||||
'learning_goal': learning_goal,
|
||||
@@ -238,6 +263,10 @@ class EncoachSignupController(http.Controller):
|
||||
'exam_date': body.get('exam_date'),
|
||||
}
|
||||
|
||||
# Assign B1 default level when placement test is skipped
|
||||
if skip_placement:
|
||||
profile_vals['cefr_level'] = 'b1'
|
||||
|
||||
Profile = request.env['encoach.student.profile'].sudo()
|
||||
profile = Profile.search([('user_id', '=', user.id)], limit=1)
|
||||
if profile:
|
||||
@@ -253,6 +282,7 @@ class EncoachSignupController(http.Controller):
|
||||
return _json_response({
|
||||
'message': 'Onboarding complete',
|
||||
'profile_id': profile.id,
|
||||
'skip_placement': skip_placement,
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user