Prompt file imported from YanBerdin/rougecardinalcompany (
.github/prompts/plan-TASK069-auditPublicCompagnieViolations.prompt.md). Copyright stays with the author.
Plan : Audit conformité public/compagnie (TASK069)
Statut : ✅ COMPLÉTÉ — 2026-03-02
Branche :refactor/public-compagnie-audit-violations
Lint : 0 erreurs | Build : exit code 0
TL;DR — Refactorer le monolithe CompagnieView.tsx (242L) en 6 composants de section avec un SECTION_RENDERERS map, corriger 3 violations WCAG (titres, alt text, landmarks), nettoyer le dead code (hooks.ts, fonctions Legacy, commentaires morts), déplacer le fallback dans la couche DAL, et aligner l'architecture (force-dynamic). 17 violations identifiées, 8 phases, ~20 fichiers impactés.
Le pattern SECTION_RENDERERS est nouveau dans le projet (aucune implémentation existante). Il est préféré aux sous-dossiers par section (pattern Home) car les sections compagnie sont pilotées dynamiquement par la DB via un sections.map() — un mapping statique type→composant est plus adapté qu'une arborescence Container/View par section.
Steps
Phase 1 — Nettoyage dead code (4 actions)
- Supprimer
hooks.tsentièrement (102L, 100% commenté) et retirer l'export commenté dansindex.tsL4 - Supprimer le bloc commenté
LucideIconMapdansCompagnieView.tsxL2-L15 (~14 lignes mortes) et l'importLucideIconsinutilisé - Supprimer
fetchCompagnieValuesLegacyetfetchTeamMembersLegacydanslib/dal/compagnie.tsL116-L131 (0 consommateurs confirmés) - Supprimer le commentaire TODO périmé dans
app/(marketing)/compagnie/page.tsxL20 ("retirer les délais artificiels") et le bloc Zod commenté danscomponents/features/public-site/compagnie/data/presentation.tsL8-L21
Phase 2 — Inversion de dépendance : fallback
- Créer
lib/dal/fallback/compagnie-presentation-fallback.ts— déplacer le contenu dedata/presentation.ts(exportcompagniePresentationFallback) dans ce nouveau fichier, en nettoyant le commentaire deprecated et le Zod schema commenté - Mettre à jour l'import dans
lib/dal/compagnie-presentation.tsL7 : remplacer@/components/features/public-site/compagnie/data/presentationpar@/lib/dal/fallback/compagnie-presentation-fallback - Supprimer
components/features/public-site/compagnie/data/presentation.tset le dossierdata/s'il est vide - Corriger les 3 casts
as unknown as PresentationSection[]danscompagnie-presentation.tsL103, L111, L129 — soit typer correctement le fallback avec le typePresentationSection[]directement, soit utiliser un type guard
Phase 3 — Extraction des 6 composants de section
-
Créer le dossier
components/features/public-site/compagnie/sections/avec 6 fichiers :SectionHero.tsx— extrait des lignes ~L32-L56 deCompagnieViewSectionHistory.tsx— extrait des lignes ~L58-L91SectionQuote.tsx— extrait des lignes ~L93-L119SectionValues.tsx— extrait des lignes ~L121-L161SectionTeam.tsx— extrait des lignes ~L163-L208SectionMission.tsx— extrait des lignes ~L210-L234index.ts— barrel exports des 6 composants
Chaque composant reçoit en props
{ section: PresentationSection }+ les données spécifiques (values,team) si nécessaire. Chaque fichier doit être < 30 lignes. -
Créer le
SECTION_RENDERERSmap dansCompagnieView.tsxrefactoré :const SECTION_RENDERERS: Record<string, ComponentType<SectionProps>> = { hero: SectionHero, history: SectionHistory, quote: SectionQuote, values: SectionValues, team: SectionTeam, mission: SectionMission, };Le
.map()devient : récupérer le renderer viaSECTION_RENDERERS[section.kind], rendrenullsi inconnu.CompagnieView.tsxdevrait passer sous 50 lignes (map, renderers import, wrapper div).
Phase 4 — Corrections accessibilité WCAG 2.2 AA
-
Hiérarchie titres (WCAG 1.3.1) — Dans chaque composant de section extrait :
SectionHero: garder<h1>(titre principal de la page)- Toutes les autres sections : remplacer
<h3>par<h2>(sous-titres directs du h1) - Si des sous-titres existent dans les sections values/team, utiliser
<h3>
-
Alt text pour images (WCAG 1.1.1) — Dans
SectionHistoryetSectionTeam:- Remplacer
style={{ backgroundImage: url(...) }}par<Image>denext/image(ou<img>avecaltdescriptif) - Pour history :
alt={section.title}ou description contextuelle - Pour team :
alt={member.name}(nom du membre comme alt text) - Utiliser
object-cover+fillou dimensions explicites pour le layout
- Remplacer
-
Landmarks (WCAG 1.3.1 / 4.1.2) — Dans chaque composant de section :
- Ajouter un
idunique dérivé du titre de section (ex:id={section.kind}) - Ajouter
aria-labelledbypointant vers le heading de la section - Pattern :
<section aria-labelledby={headingId}>+<h2 id={headingId}>
- Ajouter un
Phase 5 — TypeScript strict + constantes
-
Return types explicites — Ajouter
JSX.ElementouReact.ReactElementcomme return type sur :CompagnieViewdans le fichier refactoréCompagnieContainerdansCompagnieContainer.tsx- Les 6 nouveaux composants de section
-
Extraire magic numbers en constantes — Créer un fichier
constants.ts(ou ajouter danstypes.ts) :DEFAULT_ITEMS_LIMIT = 12(utilisé dansCompagnieContainer.tsxL9-10 pourfetchCompagnieValues(12)etfetchTeamMembers(12))ANIMATION_DELAY_STEP = 0.1etANIMATION_BASE_DELAY = "0.2s"(utilisés dans les sections extraites)FALLBACK_MEMBER_IMAGE = "/logo-florian.png"(Container L13)
Phase 6 — Architecture page.tsx
- Remplacer ISR par force-dynamic dans
app/(marketing)/compagnie/page.tsxL8 :- Supprimer
export const revalidate = 60 - Ajouter
export const dynamic = 'force-dynamic'etexport const revalidate = 0 - Cohérent avec les autres pages marketing utilisant
createClient()Supabase (le copilot-instructions.md liste déjà cette page comme nécessitant force-dynamic)
- Supprimer
Phase 7 — DAL cleanup
- Réduire
fetchCompagniePresentationSectionsdanslib/dal/compagnie-presentation.tsL84-L133 sous 30 lignes : extraire la logique de fallback dans un helper privéhandleFetchError()ougetDefaultSections() - Vérifier que
fetchTeamMembersdanslib/dal/compagnie.tsL71-L101 reste ≤ 30L après nettoyage des fonctions legacy (actuellement ~31L, marge limite)
Phase 8 — Vérifications finales
- Mettre à jour
components/features/public-site/compagnie/index.ts: ajouter l'export du barrelsections/index.ts, supprimer toute ligne commentée restante - Vérifier
pnpm lintetpnpm buildpassent sans erreur - Vérifier le rendu visuel de la page
/compagnie(aucune régression d'affichage)
Verification
pnpm lint— 0 erreurs/warningspnpm build— build réussi sans erreur- Vérification manuelle
/compagnie— les 6 sections s'affichent correctement, responsive OK - Accessibility Insights ou extension axe DevTools : 0 violations heading hierarchy, 0 missing alt, landmarks correctement identifiés
- Vérifier que
CompagnieView.tsxrefactoré est < 60 lignes - Vérifier que chaque composant
sections/*.tsxest < 30 lignes grep -r "as unknown as" lib/dal/compagnie-presentation.ts→ 0 résultatgrep -r "hooks.ts" components/features/public-site/compagnie/→ 0 résultat
Decisions
- SECTION_RENDERERS map plutôt que sous-dossiers Container/View par section (pattern Home) : les sections compagnie sont pilotées par DB via
.map(), pas composées manuellement — un mapping statique est plus simple et cohérent next/imageplutôt que<img>pour remplacer lesbackground-imageCSS : bénéficie de l'optimisation automatique Next.js et du lazy loading- Fallback dans
lib/dal/fallback/: nouveau dossier dans la couche DAL, respecte l'inversion de dépendance sans restructuration majeure force-dynamicau lieu de ISR : alignement avec la directive du copilot-instructions.md et les autres pages marketing Supabase SSRReactElementcomme return type plutôt queJSX.Element: recommandé par les guidelines TypeScript React modernes