{
  "contract_version": "gab_217_contract_v1",
  "gab_id": "GAB-217",
  "canonical_name": "AdaptiveLearningConceptPrerequisite",
  "module_owner": "EdTechAdaptiveLearning",
  "renderer_key": "text_cta",
  "required_fields": [
    "gab_id",
    "prerequisite_id",
    "title",
    "items",
    "prerequisite_type"
  ],
  "optional_fields": [
    "summary",
    "prerequisite_type_enum",
    "reason",
    "hint",
    "non_blocking_notice",
    "primary_cta",
    "skip_cta"
  ],
  "field_types": {
    "prerequisite_type": "enum['definition','method','formula','vocabulary','previous_concept']",
    "prerequisite_type_enum": "array<string> — liste des valeurs enum valides, documentaire",
    "items": "array<{heading:string, body:string}> — 1 à N points mémo, non vide",
    "reason": "string — explication pédagogique du pourquoi ce prérequis",
    "hint": "string — astuce mnémotechnique courte",
    "non_blocking_notice": "string — message confirmant que l'élève peut continuer sans",
    "primary_cta": "object{label:string, action:string}",
    "skip_cta": "object{label:string, action:string}"
  },
  "constraints": [
    "items doit contenir au moins 1 entrée — un prérequis sans items est non conforme.",
    "prerequisite_type doit appartenir à l'enum strict : definition, method, formula, vocabulary, previous_concept.",
    "skip_cta : l'option de continuer doit toujours rester visible — pas de blocage forcé (garde-fou anti-invention).",
    "hint et reason sont optionnels mais recommandés pour la valeur pédagogique.",
    "Contenu uniquement extrait de la ressource source — jamais inventé."
  ],
  "blocked_conditions": [
    "title absent",
    "items vides ou absents",
    "prerequisite_type absent"
  ],
  "accessibility": [
    "keyboard_navigable",
    "focus_visible",
    "prefers_reduced_motion",
    "aria-label sur chaque bouton CTA"
  ],
  "qa_cases": [
    { "case": "instance conforme (method, 2 items)", "expected": "rendu complet, titre, raison, 2 items, hint, non-blocking, 2 CTAs — 0 erreur" },
    { "case": "title absent", "expected": "BLOCKED : title absent" },
    { "case": "items vide []", "expected": "BLOCKED : items vides" },
    { "case": "prerequisite_type absent", "expected": "BLOCKED : prerequisite_type absent" },
    { "case": "instance externe injectée via init(ext)", "expected": "le rendu change sans modifier le HTML" },
    { "case": "reason absente", "expected": "bloc reason masqué proprement" },
    { "case": "hint absente", "expected": "bloc hint masqué proprement" },
    { "case": "skip_cta absente", "expected": "seul le primary_cta est rendu" },
    { "case": "responsive 375/768/1024", "expected": "aucun débordement horizontal" }
  ],
  "traceability": {
    "derived_from_core_gab": "GAB-217",
    "note": "Ce schema VALIDE l'instance. Le contrat pédagogique complet (input_contract/validation_logic/feedback_scoring_logic) vit dans le CORE-GAB officiel, pas ici (évite la duplication). Contenu extrait de INDEX-300-adaptivelearning-GAB-216-220-PLAYABLE.html, stage data-tpl=217, handlers pqEnum / PQ_VARIANTS."
  }
}
