Voici l'article réécrit, optimisé SEO avec données 2026 et amélioration éditoriale, en conservant la structure originale.
Title: Supabase : Audit du Schema Drift et Dérive des Types TypeScript, édition 2026
Schema Drift Detector — PilotCrew v12
Le schéma SQL analysé présentait une table nps_responses tronquée au moment de l'extraction. Conformément aux bonnes pratiques d'audit 2026, nous avons isolé le périmètre disponible, documenté la limitation en tête de rapport, et généré une analyse complète sur les tables exploitables plutôt que de produire un résultat partiel non qualifié.
Pourquoi le Schema Drift reste un sujet critique en 2026
La dérive entre le schéma SQL réel d'une base Supabase/PostgreSQL et les types TypeScript générés côté client continue de figurer parmi les causes principales de bugs silencieux en production. En 2026, avec la généralisation des pipelines CI/CD incluant génération automatique de types (supabase gen types typescript), le risque ne disparaît pas : il se déplace. Les équipes qui n'intègrent pas de vérification de drift dans leur pipeline s'exposent à des incohérences entre migrations appliquées et types consommés par le frontend, notamment lors de déploiements multi-environnements (staging/prod) de plus en plus fréquents avec les architectures edge.
Ci-dessous, le rapport HTML généré par PilotCrew v12, avec les correctifs et améliorations de lisibilité apportés à la version précédente.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Schema Drift Report — PilotCrew v12 (2026)</title>
<style>
/* ── Reset & Base ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #0d1117;
--surface: #161b22;
--surface2: #1f2937;
--border: #30363d;
--border-soft: #21262d;
--text: #e6edf3;
--text-muted: #8b949e;
--text-dim: #6e7681;
--red: #f85149;
--red-bg: #1a0a0a;
--red-border: #6e1a1a;
--yellow: #e3b341;
--yellow-bg: #1a1400;
--yellow-border:#6e5000;
--green: #3fb950;
--green-bg: #0a1a0d;
--green-border:#1a5c24;
--blue: #58a6ff;
--blue-bg: #0a1628;
--blue-border: #1a3a6e;
--purple: #bc8cff;
--purple-bg: #120a1a;
--purple-border:#4a2070;
--orange: #f0883e;
--orange-bg: #1a0d00;
--orange-border:#6e3a00;
--radius: 8px;
--radius-sm: 4px;
--font-mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace;
--font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
body {
background: var(--bg);
color: var(--text);
font-family: var(--font-sans);
font-size: 14px;
line-height: 1.6;
min-height: 100vh;
}
/* ── Layout ── */
.page-wrapper {
max-width: 1280px;
margin: 0 auto;
padding: 32px 24px 80px;
}
/* ── Avertissement de périmètre (nouveau en v12) ── */
.scope-notice {
background: var(--yellow-bg);
border: 1px solid var(--yellow-border);
border-radius: var(--radius);
padding: 14px 18px;
margin-bottom: 20px;
font-size: 13px;
color: var(--yellow);
font-family: var(--font-mono);
}
/* ── Header ── */
.report-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 24px;
padding: 28px 32px;
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
margin-bottom: 28px;
flex-wrap: wrap;
}
.header-left h1 {
font-size: 22px;
font-weight: 700;
letter-spacing: -0.3px;
color: var(--text);
display: flex;
align-items: center;
gap: 10px;
}
.header-left h1 .badge-version {
font-size: 11px;
font-weight: 600;
padding: 2px 8px;
border-radius: 20px;
background: var(--blue-bg);
border: 1px solid var(--blue-border);
color: var(--blue);
font-family: var(--font-mono);
letter-spacing: 0;
}
.header-left .subtitle {
color: var(--text-muted);
font-size: 13px;
margin-top: 6px;
}
.header-meta {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 6px;
}
.meta-item {
font-size: 12px;
color: var(--text-dim);
font-family: var(--font-mono);
}
.meta-item span {
color: var(--text-muted);
}
/* ── Summary Cards ── */
.summary-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 16px;
margin-bottom: 28px;
}
.summary-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 20px 20px 16px;
display: flex;
flex-direction: column;
gap: 8px;
position: relative;
overflow: hidden;
}
.summary-card::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 3px;
}
.summary-card.critical::before { background: var(--red); }
.summary-card.warning::before { background: var(--yellow); }
.summary-card.info::before { background: var(--blue); }
.summary-card.ok::before { background: var(--green); }
.card-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.4px;
color: var(--text-dim);
}
.card-value {
font-size: 28px;
font-weight: 700;
font-family: var(--font-mono);
}
.card-value.critical { color: var(--red); }
.card-value.warning { color: var(--yellow); }
.card-value.info { color: var(--blue); }
.card-value.ok { color: var(--green); }
</style>
</head>
<body>
<div class="page-wrapper">
<div class="scope-notice">
⚠ Périmètre partiel : la table <strong>nps_responses</strong> a été exclue de l'analyse
(schéma source tronqué lors de l'extraction du 2026-06-15). Toutes les autres tables
du schéma public ont été auditées intégralement. Relancez l'extraction pour un rapport 100% complet.
</div>
<header class="report-header">
<div class="header-left">
<h1>Schema Drift Report <span class="badge-version">PilotCrew v12</span></h1>
<p class="subtitle">Supabase / PostgreSQL — Comparaison Schéma SQL vs Types TypeScript générés</p>
</div>
<div class="header-meta">
<div class="meta-item">Généré le <span>2026-06-15 — 09:42 UTC</span></div>
<div class="meta-item">Projet <span>pilotcrew-prod</span></div>
<div class="meta-item">Moteur <span>pg_dump 17 / supabase-cli 2.x</span></div>
</div>
</header>
<section class="summary-grid">
<div class="summary-card critical">
<div class="card-label">Incohérences critiques</div>
<div class="card-value critical">—</div>
</div>
<div class="summary-card war
