Practice Flow - Result Impact Contracts
DomainsDOL EnglishUX2.635 words13 min read
Practice Flow - Result Impact Contracts (LM and Vocabulary)
Phần tiêu đề “Practice Flow - Result Impact Contracts (LM and Vocabulary)”Purpose
Phần tiêu đề “Purpose”- Vấn đề: Kết quả bài tập tác động nhiều module nên cần contract nhất quán để tránh lệch dữ liệu.
- Đối tượng chính: Team định nghĩa dữ liệu sync sau khi user hoàn thành bài tập.
- Tín hiệu thành công: Result từ mọi nguồn entry đều sync ổn định sang LM/Vocabulary và giữ đúng metadata recommendation.
Alignment note
Phần tiêu đề “Alignment note”- File này chỉ giữ sync contract sau
Resultcủa owner flowLuyện tập. - Nó không tạo thêm destination mới;
Learning ManagementvàVocabulary Managementvẫn là owner surfaces riêng khi user đi xem sâu sau sync.
Elements / Scope
Phần tiêu đề “Elements / Scope”- Result contract tối thiểu:
attempt_idai_scoring_job_idsource_context(self_study|course)programassessment_form_idexercise_identitlement_tier(free|pro|pro_max)completion_statusai_scoring_status(pending|ready|not_applicable)ai_credit_charge_state(not_charged|charged_once|refunded)ai_credit_refund_reason(system_failure|manual_adjustment|none)locked_sections[]score_summaryattempt_score_profile_idattempt_score_valuegoal_program_idgoal_assessment_formgoal_skill_idgoal_priority(primary|secondary)primary_goal_idsecondary_goal_idgoal_scale_profile_idgoal_target_valuegoal_version_id_at_submissiongoal_comparison_mode(direct|normalized|not_comparable)goal_scale_mapping_policy(whitelist_only)goal_comparable_attempts_30_active_daysgoal_gap_visibility_eligible(true|false)submitted_at
- Recommendation metadata (new baseline):
recommendation_priority(habit_first)recommendation_set_size(3..7)recommendation_default_size(5)recommendation_low_inventory_min(3)recommendation_default_mix(2_habit_2_target_1_explore)recommendation_reason_labelrecommendation_primary_reason_code(recovery_critical|goal_aligned|habit_continuity|freshness|trending_fallback)recommendation_primary_reason_priority_order(recovery_critical -> goal_aligned -> habit_continuity -> freshness -> trending_fallback)recommendation_confidence_level(high|medium|low)recommendation_low_confidence_cap_per_set(1_when_inventory_allows)recommendation_low_confidence_position(near_end|none)recommendation_ignore_streakrecommendation_ignore_definition(no_click | click_no_submit)recommendation_ignore_eval_timing(end_of_session)recommendation_adaptation_order(difficulty -> format -> skill)recommendation_strategy_versionrecommendation_topic_idrecommendation_format_idrecommendation_freshness_flag(true|false)recommendation_freshness_reason(not_attempted_14d|new_format_same_skill|none)recommendation_topic_repetition_cap_per_set(2)recommendation_feedback_scope(cluster_like_dislike)recommendation_dislike_persistence(next_clusters)recommendation_feedback_reset_ignore(false)recommendation_refresh_without_action_streakrecommendation_refresh_without_action_threshold(2)recommendation_alt_skill_forced_next_set(true|false)recommendation_available_now(true|false)recommendation_locked_teaser(true|false)recommendation_locked_teaser_position(end_of_set|none)recommendation_minimum_eligible_plan(pro|pro_max|none)recommendation_lock_reason(advanced_ai_required|credit_required|entitlement_scope_limited|none)reactivation_intent_stage(lost_streak | inactive_1w | inactive_1m | inactive_1y | inactive_q3_repeat | none)reactivation_seed_program_idreactivation_seed_skill_idreactivation_seed_applied(true|false)reactivation_seed_profile(quick_win_last_skill | quick_win_plus_trending_new | none)reactivation_seed_confidence_preference(high_or_medium_preferred)reactivation_seed_ttl(first_set_in_session)manual_controls_applied(skill | difficulty | duration)manual_controls_mode(soft_priority)manual_controls_scope(session_cross_surface)no_match_policy(nearest_ladder_with_notice)vocab_today_focus_cap(20)vocab_quick_start_size(5)vocab_overload_pause_threshold(40)vocab_overload_resume_threshold(30)vocab_unfinished_penalty_policy(none)locked_ai_popup_repeat_policy(every_tap)locked_ai_popup_reopen_cooldown_seconds(1..2)locked_ai_popup_default_preselected_tier(minimum_eligible)retained_credit_lock_visibility_surfaces(result | billing_subscription)
- Impact targets:
Learning Management(always-on sync)Vocabulary Management(conditional sync)
Logic
Phần tiêu đề “Logic”- Rule 1: Mọi result hợp lệ phải sync sang LM.
- Rule 2: Chỉ result có
vocab_suggestion_payloadhợp lệ mới sync sang Vocabulary. - Rule 2a:
vocab_suggestion_payloadphải qua dedupe trước khi vào queue Vocabulary. - Rule 2b: Vocabulary Today Focus chỉ nhận tối đa 20 mục/ngày và có quick-start subset mặc định 5 mục.
- Rule 2c: Nếu backlog cần ôn của Vocabulary > 40, payload mới vẫn sync vào inbox nhưng không đẩy vào Today Focus.
- Rule 2d: Khi backlog <= 30, intake mới được phép quay lại Today Focus.
- Rule 2e: User chưa hoàn tất Today Focus trong ngày không bị phạt; queue được rebuild vào ngày sau theo policy ưu tiên.
- Rule 3: Sync thất bại tạm thời phải được đánh dấu trạng thái và retry nền.
- Rule 4:
source_contextphải được giữ nguyên xuyên pipeline để phân tích đúng nguồn bài học. - Rule 5: Result surface là shared UI; section lock/unlock dựa vào
entitlement_tier. - Rule 6: Khi user nâng cấp thành công trong context attempt/result, server phải trả trạng thái entitlement mới để client reload đúng section vừa unlock.
- Rule 7: Tất cả attempt đã nộp đều được tính vào learning metrics, không phụ thuộc tier.
- Rule 8: Nếu
recommendation_ignore_streak >= 3, engine phải chuyển strategy ở lần render kế tiếp. - Rule 9: Recommendation list refresh ở
on_submitvà khi user gọimanual_refresh. - Rule 10: Nếu user dislike rồi rời màn không nộp bài mới, vẫn cộng
ignore +1. - Rule 11: Free Writing/Speaking được phép xem basic score; AI detail sections giữ lock-state.
- Rule 12: Top-up balance được giữ, nhưng usage lock khi outside entitlement context.
- Rule 13: AI credit cho một bài/result chỉ được charge một lần theo
ai_scoring_job_id; reopen result không charge lại. - Rule 14: Nếu AI scoring thất bại do lỗi hệ thống sau khi đã charge, hệ thống phải auto-refund credit.
- Rule 15: Nếu entitlement/credit đổi trạng thái giữa attempt, user vẫn được submit; result hiển thị lock-state ở section AI không còn quyền.
- Rule 16: Nếu user downgrade
pro_max -> prokhi còn AI credit, giữ nguyên số dư; usage lock cho feature vượt entitlement hiện tại. - Rule 17: Popup lock-AI mở theo mỗi tap nhưng cần áp anti-spam cooldown 1-2 giây giữa các lần reopen.
- Rule 18: Trạng thái credit giữ lại nhưng usage-lock phải hiển thị rõ ở cả Result và Billing/Subscription.
- Rule 19: Nếu popup có cả
ProvàPro Max, default preselect phải là gói tối thiểu đủ mở feature; user có thể đổi trước khi xác nhận. - Rule 20: Goal-gap calculation chỉ chạy khi
goal_comparison_mode = direct | normalized; nếunot_comparable, pipeline chỉ emit trend/progress signals và bỏ qua numeric goal-gap. - Rule 21:
normalizedmode chỉ hợp lệ khi mapping nằm trong whitelist được duyệt. - Rule 22: Numeric goal-gap chỉ được emit khi
goal_comparable_attempts_30_active_days >= 3; nếu không đạt thì emit trend/progress-only. - Rule 23: Nếu goal comparison
not_comparablehoặc low-confidence, recommendation fallback ưu tiên cùngassessment_form, sau đó cùngskillnếu inventory đủ. - Rule 24: Mỗi attempt phải giữ
goal_version_id_at_submissionđể truy vết đúng historical context. - Rule 25:
assessment_form_idphải là canonical form ID hợp lệ và map được tớiprogram + skill + score_profile_id. - Rule 26: mỗi recommendation set phải có tối thiểu 1 item
recommendation_freshness_flag = truekhi inventory cho phép. - Rule 27: không quá 2 item cùng
recommendation_topic_idtrong một set; nếu inventory thấp thì fallback theo nearest-ladder + notice ngắn. - Rule 28: nếu
recommendation_refresh_without_action_streak >= 2, set kế tiếp phải có tối thiểu 1 item khác skill (recommendation_alt_skill_forced_next_set = true). - Rule 29: freshness reason phải rõ ràng theo enum (
not_attempted_14d | new_format_same_skill | none) để giải thích item 1 dòng nhất quán. - Rule 30: nếu
reactivation_intent_stage != none, set đầu tiên của session phải cố gắng ápreactivation_seed_applied = truevới tối thiểu 1 quick-win item khi inventory cho phép. - Rule 31:
reactivation_seed_appliedchỉ hợp lệ ở set đầu tiên của session (reactivation_seed_ttl = first_set_in_session); sau đó phải vềfalse. - Rule 32: nếu inventory không đủ seed item, emit fallback theo baseline (
trending_14d + easy_start_bias) và đánh dấureactivation_seed_applied = false. - Rule 33: recommendation composer phải ưu tiên
recommendation_available_now = true; khi inventory đủ,recommendation_locked_teaser = truetối đa 1 item/set. - Rule 34: nếu có locked teaser, item đó phải đứng cuối set (
recommendation_locked_teaser_position = end_of_set) và kèmrecommendation_minimum_eligible_plan + recommendation_lock_reason. - Rule 35: nếu available-now inventory thiếu, engine nới nearest-ladder trước; chỉ sau đó mới tăng locked items và emit shortage notice event.
- Rule 36: mỗi recommendation item chỉ được emit đúng 1
recommendation_primary_reason_codetheo priority đã chốt; không emit multi-primary-reason cho cùng item. - Rule 37: mỗi set phải giữ
recommendation_low_confidence_cap_per_set = 1khi inventory đủ; item low-confidence phải ở vị trí gần cuối set. - Rule 38: với recommendation seed/rescue, composer ưu tiên item confidence
high | medium; chỉ dùnglowkhi inventory không đủ.
UI / Behavior
Phần tiêu đề “UI / Behavior”- Result UI hiển thị trạng thái hoàn thành và phản hồi điểm chính.
- Với AI-scored exercise: luôn có state
loading AItrước khi có kết quả final. - Với free tier ở AI sections: hiển thị lock-state + entry nâng cấp.
- Entry nâng cấp từ section bị khoá:
- Pro-eligible feature -> popup
Pro+Pro Maxvà chờ user chọn, - Pro Max-only feature -> popup chỉ
Pro Max. - popup mở lại ở mỗi lần tap vào section lock (không suppress theo màn).
- popup reopen có cooldown ngắn 1-2 giây để tránh spam click.
- Pro-eligible feature -> popup
- Mid-attempt entitlement drop:
- không chặn submit,
- lock-state chỉ xuất hiện ở result sections không còn quyền,
- giữ entry nâng cấp/top-up từ section lock.
- Recommendation item hiển thị lý do 1 dòng để user hiểu vì sao được gợi ý.
- Nếu có gợi ý từ vựng, user thấy CTA sang Vocabulary suggestion list.
- Nếu không có gợi ý từ vựng, user vẫn đi tiếp qua CTA học tiếp hoặc xem LM detail.
Data model / API touchpoints
Phần tiêu đề “Data model / API touchpoints”result_eventphát sau submit thành công.lm_sync_eventđược enqueue ngay sauresult_event.vocab_suggestion_eventchỉ enqueue khi payload hợp lệ.recommendation_render_eventphát khi list gợi ý hiển thị.recommendation_refresh_eventphát khi auto/manual refresh.recommendation_ignore_eventphát khi user bỏ qua item/list.recommendation_click_eventphát khi user click item gợi ý.recommendation_attempt_start_eventphát khi user bắt đầu attempt từ item gợi ý.recommendation_freshness_guardrail_applied_eventphát khi set áp freshness quota/topic cap.recommendation_refresh_without_action_eventphát khi user manual refresh không kèm click/attempt.recommendation_diversification_forced_eventphát khi set kế tiếp bị ép thêm item khác skill.recommendation_confidence_guardrail_applied_eventphát khi composer áp cap/position cho low-confidence items.reactivation_recommendation_seed_applied_eventphát khi seed handoff được áp cho set đầu tiên.reactivation_recommendation_seed_fallback_eventphát khi seed handoff không áp được vì inventory thiếu.recommendation_locked_teaser_render_eventphát khi render lock teaser item ở cuối set.recommendation_available_now_shortage_notice_eventphát khi set thiếu available-now và phải nới theo ladder/locked fallback.goal_comparison_ineligible_eventphát khi result không thể so sánh trực tiếp với goal scale.goal_gap_hidden_low_confidence_eventphát khi có goal nhưng không đủ mẫu comparable để hiển thị numeric gap.ai_credit_charged_eventphát khi charge thành công theoai_scoring_job_id.ai_credit_refunded_eventphát khi auto-refund vì lỗi hệ thống.mid_attempt_entitlement_drop_eventphát khi entitlement/credit thay đổi trong lúc attempt.- Trạng thái sync tối thiểu:
queued,done,failed_retrying. - KPI emission tối thiểu:
recommendation_to_attempt_rate = recommendation_attempt_start_event / recommendation_render_event.locked_feature_upgrade_conversion = checkout_success_from_locked_entry / locked_ai_entry_click.
Dependencies / Integration
Phần tiêu đề “Dependencies / Integration”Learning Management: cập nhật history, metrics, analysis inputs.Vocabulary Management: nhận suggestion list từ kết quả bài tập.Course Management: giữ liên kết result nếu nguồn là course.
References
Phần tiêu đề “References”./PRA_00_Overview.md./PRA_Result_Flow.md./PRA_Entry_Routing_Contracts.md../Learning Management/LM_00_Overview.md../Vocabulary Management/VOC_00_Overview.md
Change log
Phần tiêu đề “Change log”- 2026-02-22: Bổ sung payload/rule/event contracts cho recommendation confidence + primary reason determinism:
recommendation_primary_reason_code,recommendation_confidence_level, cap low-confidence, và event guardrail áp dụng. - 2026-02-22: Bổ sung fields/rules/events cho entitlement-aware recommendation composition: available-now flag, lock-teaser metadata/position, minimum-eligible-plan label và shortage notice event.
- 2026-02-22: Bổ sung metadata/rules/events cho reactivation-intent recommendation handoff: stage/seed context, one-time first-set TTL và fallback event khi thiếu inventory.
- 2026-02-22: Bổ sung contract metadata/rules cho recommendation freshness và light diversification: freshness item, topic cap, refresh-without-action streak, cùng các events theo dõi guardrail áp dụng.
- 2026-02-21: Bổ sung canonical
assessment_form_idvào result contract và rule map hợp lệ để đồng bộ Goal/Recommendation/Metrics trên một taxonomy ổn định. - 2026-02-21: Refine goal engine contracts: thêm
goal_skill_id,goal_priority,goal_version_id_at_submission, whitelist mapping policy, confidence gate (>=3 comparable attempts/30 active days) và fallback recommendation theo cùng assessment form khi goal-gap không đủ điều kiện. - 2026-02-21: Bổ sung contract score profile cho so sánh mục tiêu theo
program + assessment form(goal_scale_profile_id,attempt_score_profile_id,goal_comparison_mode) và eventgoal_comparison_ineligible_event. - 2026-02-21: Bổ sung baseline Vocabulary queue governance tại điểm sync result: dedupe, cap 20 mục/ngày, quick-start 5 mục, overload governor 40/30 và non-punitive unfinished policy.
- 2026-02-21: Thêm contract
locked_ai_popup_default_preselected_tier = minimum_eligibleđể chuẩn hóa hành vi preselect trong popup nâng cấp. - 2026-02-20: Thêm contract lock-popup repeat mỗi tap ở result context và rule giữ credit khi downgrade
pro_max -> pro(usage lock ngoài entitlement). - 2026-02-19: Bổ sung contract fairness cho AI credit/result: charge-once theo scoring job, auto-refund khi lỗi hệ thống, và mid-attempt entitlement drop không chặn submit.
- 2026-02-18: Bổ sung KPI emission contract cho recommendation-to-attempt và locked-feature-upgrade conversion.
- 2026-02-18: Bổ sung recommendation metadata contract (habit-first, dynamic size, reason label, ignore streak, refresh events).
- 2026-02-17: Bổ sung entitlement-aware result contract, AI loading/lock states, unlock-after-upgrade contract, và rule tính metrics cho mọi bài đã nộp.
- 2026-02-07: Khởi tạo result impact contracts với rule always-sync LM và conditional-sync Vocabulary.