# GAB-227 · SmartSelectTeacherOverride — « Override professeur IDOR-proof »

**Archétype / renderer_key :** `text_cta` (cartographie) · **module :** EdTechSmartSelect
**Critère validé :** changer le JSON change le rendu sans modifier le HTML. check.py 12/12.

## Pack (structure officielle par-GAB)
```
GAB-227/
  renderer.html            ← moteur teacher override (ne pas modifier par instance)
  instance.example.json    ← SOURCE DE VÉRITÉ (contenu réel, à plat)
  schema.contract.json     ← contrat de validation
  README-contract.md       ← ce fichier
```

## Champs requis (instance, à plat)
`gab_id` · `override_id` · `teacher_name` · `teacher_initials` · `teacher_meta` · `content_title` · `content_description` · `override_type` · `reason_body` · `primary_cta{label,action}`

Optionnels : `title`, `security_chain[]{step,status}`, `security_banner_title`, `security_banner_body`, `teacher_badge_label`, `content_ref`, `content_ref_label`, `reason_title`, `no_alt_warning`.

## Ce qui vient du JSON vs HTML
- **JSON** : initiales avatar, nom/meta du prof, badge, type d'override, titre/description de la ressource, ref contenu, texte reason, warning no-alt, libellé du CTA, chaîne de sécurité.
- **HTML** : layout card, chaîne sécurité (rendue si présente), avatar circulaire, content-box, reason-block, bouton CTA structurel, fallback BLOCKED.

## Archétype
GAB-227 est un gabarit **XL P1 sécurité** de SmartSelect. Il affiche une décision pédagogique de priorité absolue d'un professeur, vérifiée serveur-side selon 4 conditions cumulatives IDOR-proof. Contrairement aux gabarits SmartSelect 221-226, il n'offre **pas de skip ni de fallback adaptatif** : la décision prof prime sur toute logique d'algorithme.

## Garde-fous (child_safety / sécurité)
- `override_id` obligatoire et unique : empêche l'affichage d'une override non tracée.
- `teacher_initials` : 2 majuscules (acronyme), jamais de nom complet en clair dans l'avatar.
- `security_chain` : si présente, le dernier step DOIT avoir `status: "danger"` (= rappel visuel que `accepter client teacher_id` = IDOR interdit).
- **BLOCKED** si `override_id`, `teacher_name`, `content_title` ou `primary_cta` absents.

## QA à vérifier
1. Modifier `content_title`/`reason_body` → rendu change sans toucher au HTML (critère d'or).
2. `teacher_name` absent → BLOCKED propre.
3. `security_chain` absente → bannière masquée, carte OK.
4. Instance externe injectée via `ENGINE.init(ext)` → rendu change.
5. Responsive 375/768/1024 — chaîne sécurité en flex-wrap sur mobile.

## external_refs / dependencies
- **GAB-224** : prend le relais si la ressource prof est indisponible (rare).
- **EdTechAuth V2 — `verifyUserMatch`** : audit P0 lié, vérifie `teacher_id` JWT + `owns(class_id)` + `user ∈ class` + `access(ref)` avant tout affichage de cet écran côté serveur.

## Source
`INDEX-300-smartselect-GAB-226-230-PLAYABLE.html` (stage `data-tpl="227"`, commentaire `<!-- GAB-227 TeacherOverride -->`).
