Aller au contenu principal

DMV — Audit Readiness V1

Date : 2026-06-07
Auditeur : Analyse statique du code (Claude Code)
Périmètre : dmv-public, dmv-workspace, api Laravel, dmv-docs


1. Résumé exécutif

L'écosystème DMV est techniquement solide dans son architecture : API Laravel bien structurée en modules, deux Next.js distincts (public statique + workspace SPA), séparation Supabase anon / Sanctum token bien maîtrisée, design system cohérent.

La préoccupation principale pour le go-live est la sécurité : le workspace acteur ne vérifie pas côté client que l'utilisateur connecté est propriétaire de l'acteur dont il accède à l'espace. Cette vérification existe bien côté API Laravel (ActeurPolicy), mais le frontend n'empêche pas un utilisateur authentifié de naviguer librement dans l'interface de n'importe quel acteur, ce qui crée une expérience trompeuse et un potentiel de confusion.

Plusieurs modules sont partiels mais non bloquants pour un lancement pilote (paiement, stats avancées, mur contributeur). Le socle cœur (annuaire, fiches, auth, espace acteur, espace mairie) est fonctionnel.

Verdict préliminaire : No-Go strict, mais Go conditionnel si 3 points P0 sont corrigés.


2. Score global V1 (%)

DomaineScore estimé
Annuaire & fiches publiques90 %
Auth (inscription/connexion/reset)88 %
Espace acteur (workspace)80 %
Espace mairie (workspace)82 %
Mur de ville (home)75 %
Mon espace contributeur70 %
Favoris85 %
Stats65 %
Offres / tarifs70 %
Sécurité API85 %
Sécurité frontend55 %
Déploiement / infra80 %
Global76 %

3. Tableau des modules

ModuleStatutRemarque
Mur de ville (home)PartielFlag feature_tabs conditionnel, OK fonctionnellement
Annuaire localOKRecherche, filtres, carte, tri coeff_annuaire, badges ouvert/fermé
Fiches acteurs (public)OKLogo, bannière, horaires, JSON-LD, bouton favori, revendiquer
Auth (connexion/inscription/reset)OKMagic link, password, OAuth Google/Facebook, reset complet
Mon espace contributeurPartielMur personnel feature-flaggé, favoris OK, profil OK
Espace acteur — tableau de bordOKScore complétude, publications récentes, accès rapides
Espace acteur — profilOKLogo, bannière, horaires, tags, documents, couleurs, SEO
Espace acteur — publications CRUD+AIOKCréation, édition, suppression, assistant IA intégré
Espace acteur — statsPartielStats basiques OK, graphiques dans le temps absents
Espace acteur — avantages / boostsOKBoosts, défis, récompenses affichés et utilisables
Espace acteur — offreOKLecture plan, limites, lien vers tarifs, "bientôt" pour paiement
Espace acteur — paramètresPartielDéconnexion OK, membres/notifs/abonnement "à venir"
Espace mairie — vue d'ensembleOKNavigation 6 sections
Espace mairie — profilOKVisuels, identité, coordonnées, réseaux, horaires, thème
Espace mairie — élusOKCRUD élus complet
Espace mairie — collectesOKCRUD collectes
Espace mairie — infos pratiquesOKCRUD infos
Espace mairie — publicationsOKCRUD + pagination
Espace mairie — servicesOKCRUD services
FavorisOKToggle, liste avec dernière pub, état vide, unfollow
Mise en avant / sponsorisationOKen_avant + coeff_annuaire pris en compte
Tarifs / offresPartielAffichage complet, paiement non ouvert (modal "bientôt")
API Laravel — IdentityOKexchange, me, update, logout
API Laravel — ActorOKCRUD + tags + documents + XP + claims
API Laravel — PublicationOKCRUD + types + report + moderate
API Laravel — MairieOKAlertes, services, élus, collectes, infos, publications
API Laravel — AIOKgenerate, improve, variants, tags, quota
API Laravel — AnalyticsOKacteur, commune, global, push
API Laravel — MonetizationOKplans, souscriptions, boosts, webhook Stripe
API Laravel — AdminOKDashboard, users, acteurs, publications, claims, etc.
Déploiement CF PagesPartielWorker OK, _redirects OK, env vars hardcodées workspace
Sécurité — accès non-propriétaireBloquantLe workspace acteur n'a pas de gate côté client
Sécurité — clé DB dans .env.localP1SUPABASE_DB_PASSWORD présent dans .env.local public
Charte — couleur violetP14 occurrences de classes violet-* interdites

4. Bugs P0 (bloquants go-live)

P0-1 — Absence de gate propriétaire dans le workspace acteur

Fichier : /Users/sylvain/dev/dmv/dmv-workspace/app/(workspace)/acteur/[slug]/acteur-layout-client.tsx (lignes 74-75)

Le layout récupère la liste userActeurs de l'utilisateur et trouve currentUserActeur, mais ne redirige jamais ni ne bloque si currentUserActeur est null (= l'utilisateur n'est pas propriétaire de cet acteur). N'importe quel utilisateur authentifié peut accéder à /mon-espace/acteur/[n'importe-quel-slug]/tableau-de-bord et voir l'interface de gestion de cet acteur.

La protection existe côté API (ActeurPolicy via $this->authorize('update', $acteur)), donc les modifications seront refusées avec 403. Mais l'interface s'affiche quand même, ce qui est une fuite d'information (nom, logo, publications, stats) et une expérience confuse.

Correction requise : après le Promise.all, si !currentUserActeur et que l'utilisateur n'est pas admin, afficher une page "Accès refusé" ou rediriger vers /connexion.

P0-2 — Env vars hardcodées dans next.config.ts (workspace)

Fichier : /Users/sylvain/dev/dmv/dmv-workspace/next.config.ts (lignes 23-25)

env: {
NEXT_PUBLIC_SUPABASE_URL: "https://odgqttcbofqphwdikwnv.supabase.co",
NEXT_PUBLIC_SUPABASE_ANON_KEY: "sb_publishable_M6ghpkFdfNoahNONvWKbRA_qzYLF6Vx",
NEXT_PUBLIC_API_URL: "https://api.dansmonvillage.fr/api/v1",
},

Ces valeurs sont hardcodées dans le code source versionné. La clé anon Supabase est NEXT_PUBLIC_* donc publique par nature, mais la hardcoder dans git empêche toute rotation sans redéploiement et expose l'URL de l'instance Supabase. Pour la V1 pilote, le risque est faible puisque la clé anon est limitée par RLS, mais c'est une mauvaise pratique à corriger avant tout accès élargi.

Note : dmv-public utilise des variables d'environnement correctement via process.env.NEXT_PUBLIC_* sans les hardcoder dans next.config.mjs.

P0-3 — Absence de rate limiting sur les routes d'auth et de mutation critiques

Fichier : /Users/sylvain/dev/dmv/api/app/Modules/Actor/Routes/api.php

Le throttle throttle:10,1 n'est appliqué qu'à la route /acteurs/{id}/xp. Les routes critiques comme POST /publications (création), POST /claims (public), POST /acteurs (création) et les routes AI (POST /ai/publication/generate) n'ont pas de rate limiting spécifique. Le rate limit global de Laravel (api middleware) protège partiellement, mais il faut des quotas spécifiques par route sensible.


5. Bugs P1 (importants, correctibles rapidement)

P1-1 — Violations de charte : couleur violet interdite

Fichiers et lignes :

  • /Users/sylvain/dev/dmv/dmv-public/app/[commune]/acteur/[slug]/ActorsClient.tsx:436 — badge catégorie border-violet-200 bg-violet-50 text-violet-700
  • /Users/sylvain/dev/dmv/dmv-public/app/components/MurVille.tsx:552 — badge acteur bg-violet-500/15 text-violet-100
  • /Users/sylvain/dev/dmv/dmv-workspace/app/(workspace)/acteur/[slug]/profil/page.tsx:402 — badge catégorie border-violet-200 bg-violet-50 text-violet-700
  • /Users/sylvain/dev/dmv/dmv-workspace/app/(workspace)/acteur/[slug]/profil/page.tsx:1024 — aperçu thème border-violet-200 bg-violet-50 text-violet-700

La règle du design system (CLAUDE.md) interdit explicitement text-violet-*, bg-violet-*, border-violet-*. Ces badges catégorie devraient utiliser blue-100/blue-700 ou neutral.

P1-2 — SUPABASE_DB_PASSWORD dans .env.local

Fichier : /Users/sylvain/dev/dmv/dmv-public/.env.local (ligne 9)

SUPABASE_DB_PASSWORD=pYtpeg-cisni0-remxom

Ce fichier est exclu de git (.gitignore inclut .env*), donc pas de fuite dans le dépôt. Mais la présence d'un mot de passe de base de données dans un fichier d'environnement frontend est une mauvaise pratique : le frontend n'a jamais besoin d'accès direct à la base Postgres. À supprimer.

P1-3 — Page /mon-espace/acteur référencée mais chemin dépend de l'ancienne architecture

Fichier : /Users/sylvain/dev/dmv/dmv-workspace/app/(workspace)/acteur/[slug]/offre/page.tsx:164

href={`${PUBLIC_SITE}/mon-espace/tarifs?slug=${slug}`}

Et dans /Users/sylvain/dev/dmv/dmv-public/app/mon-espace/tarifs/page.tsx:227 :

const backUrl = slugParam ? `/mon-espace/acteur?slug=${slugParam}&tab=abonnement` : null;

Le lien de retour pointe vers /mon-espace/acteur?slug=…&tab=abonnement qui semble être une ancienne route de l'app public (dmv-public/app/mon-espace/acteur/) — à vérifier que cette page existe et fonctionne.

P1-4 — Worker CF : hostname hardcodé dmv-mon-espace.pages.dev

Fichier : /Users/sylvain/dev/dmv/dmv-workspace/cloudflare/mon-espace-proxy-worker.js:13

const PAGES_HOSTNAME = "dmv-mon-espace.pages.dev";

Si le projet CF Pages est renommé, le Worker casse. À externaliser en variable d'environnement Worker (env.PAGES_HOSTNAME).

P1-5 — Absence de vérification propriétaire dans le workspace mairie

Fichier : /Users/sylvain/dev/dmv/dmv-workspace/app/(workspace)/mairie/[slug]/layout.tsx et mairie-guard.tsx

Même problème structurel que P0-1 pour le workspace acteur : si le garde mairie ne vérifie pas que l'utilisateur est commune.manager pour la commune en question, un utilisateur mairie d'une commune A pourrait voir l'interface de la commune B. À vérifier dans mairie-guard.tsx.

P1-6 — Paramètres acteur : fonctionnalités affichées "à venir" sans alternatives

Fichier : /Users/sylvain/dev/dmv/dmv-workspace/app/(workspace)/acteur/[slug]/parametres/page.tsx (lignes 46-63)

La page affiche "Membres", "Notifications", "Abonnement" comme badges "À venir" sans aucune fonctionnalité active hors la déconnexion. Pour V1, c'est acceptable mais peu engageant.

P1-7 — Publication modal : sélection type par nom fragile

Fichier : /Users/sylvain/dev/dmv/dmv-workspace/components/acteur/publications/publication-modal.tsx:85

setKind(publication?.type?.nom === "evenement" ? "evenement" : "actualite");

La logique de détection du type de publication repose sur la comparaison du nom textuel ("evenement", "actualite"). Si ces noms changent en base, le comportement casse silencieusement. Utiliser un type_id ou un champ code stable serait plus robuste.


6. Bugs P2 (mineurs, hors scope V1)

P2-1 — AnnuaireClient : setLoading(false) manquant sur le chemin noSearch

Fichier : /Users/sylvain/dev/dmv/dmv-public/app/[commune]/AnnuaireClient.tsx (lignes 240-247)

if (noSearch) {
if (myReqId !== reqIdRef.current) return;
const filtered = ...;
setItems(filtered);
setLoading(false); // ← présent, OK
return;
}

En relisant : setLoading(false) est bien appelé. Pas de bug ici.

P2-2 — Stats page : graphiques d'évolution absents

Fichier : /Users/sylvain/dev/dmv/dmv-workspace/app/(workspace)/acteur/[slug]/stats/page.tsx (lignes 148-155)

Un encart avec TrendingUp annonce explicitement que les graphiques d'évolution arrivent dans "une prochaine version". Acceptable pour V1 pilote, mais à noter pour les utilisateurs.

P2-3 — Seeders très limités

Fichier : /Users/sylvain/dev/dmv/api/database/seeders/DatabaseSeeder.php

Seuls BoostCatalogSeeder et RewardRuleSeeder sont appelés, plus un User::factory test. Pas de seed pour :

  • Communes de test
  • Acteurs de démonstration
  • Types de publications
  • Plans d'abonnement (subscription_plans — pourtant lus depuis Supabase)

Les données de test dépendent intégralement de Supabase, ce qui rend les tests Laravel sans Supabase impossibles.

P2-4 — Type ActeurKind incohérent entre frontend et DB

Fichier : /Users/sylvain/dev/dmv/dmv-workspace/types/index.ts (lignes 104-109)

export type ActeurKind = "association" | "commerce" | "artisan" | "service" | "mairie";

Mais la DB et le code utilisent "pro" | "association" | "public" (visible dans AnnuaireClient.tsx:33, [commune]/page.tsx:18). Ce type ActeurKind dans types/index.ts est obsolète et n'est pas utilisé pour Acteur.kind (qui est string). Risque de confusion pour les futurs contributeurs.

P2-5 — indigo utilisé dans mon-espace/page.tsx (onboarding)

Fichier : /Users/sylvain/dev/dmv/dmv-public/app/mon-espace/page.tsx (lignes 654, 659)

className="... bg-indigo-600 ... hover:bg-indigo-500"

La charte autorise blue/neutral/amber/red/green. L'indigo dans le bouton "Créer mon espace" n'est pas dans la palette officielle, mais c'est un écran d'onboarding rarement vu.

P2-6 — dynamicParams = false dans [slug]/layout.tsx du workspace

Fichier : /Users/sylvain/dev/dmv/dmv-workspace/app/(workspace)/acteur/[slug]/layout.tsx (lignes 3-6)

export function generateStaticParams() {
return [{ slug: "_" }];
}
export const dynamicParams = false;

Avec dynamicParams = false, seul le slug _ est pré-rendu statiquement. Tout autre slug retourne 404 en production unless la _redirects redirige vers _. La règle _redirects :

/acteur/:slug/* /acteur/_/:splat 200

gère cela correctement. Cohérent mais subtil — si la règle _redirects échoue pour une raison quelconque, toutes les pages acteur retournent 404.


7. Fonctionnalités V1 prêtes

  • Annuaire local : liste d'acteurs avec recherche full-text (RPC search_acteurs_public), filtres par type, tri sponsorisé (coeff_annuaire), badge ouvert/fermé, carte Leaflet avec pins, pagination, "Je ne trouve pas mon activité", bouton "Revendiquer"
  • Fiches acteurs publiques : logo, bannière, horaires, description, coordonnées, publications, bouton favori (authentifié), bouton revendiquer, JSON-LD Schema.org complet (LocalBusiness / NGO / GovernmentOrganization)
  • Authentification : magic link, mot de passe, Google OAuth, Facebook OAuth, inscription avec confirmation email, forgot password, reset password (flux PASSWORD_RECOVERY Supabase complet)
  • Mon espace contributeur : profil, favoris avec dernière publication, liste des acteurs gérés, mur feature-flaggé
  • Tableau de bord acteur : score de complétude de fiche, publications récentes, avantages disponibles
  • Édition profil acteur : logo upload, bannière upload, informations, SEO text, horaires multi-créneaux avec copie semaine/tous, tags avec drag&drop, documents (quota/upload XHR progressif), couleurs de thème (plan supérieur)
  • Publications acteur CRUD : création avec assistant IA (generate/improve/variants), édition, suppression, types actualité/événement
  • Stats acteur : vues, clics, partages, top sources, top devices (mois courant)
  • Avantages acteur : boosts disponibles, utilisation (featured_actor, featured_publication), défis, récompenses récentes
  • Offre acteur : lecture plan courant, fonctionnalités incluses, lien vers tarifs
  • Espace mairie : profil (6 composants), publications CRUD, élus CRUD, collectes CRUD, infos pratiques CRUD, services CRUD
  • Page tarifs : affichage plans depuis DB, toggle mensuel/annuel, promos, FAQ — paiement "bientôt disponible" (modal transparente)
  • API Laravel : 15 modules fonctionnels, routes protégées Sanctum + Policy, X-App-Source enforced, middleware admin, webhook Stripe structuré
  • Déploiement : Worker CF proxy /mon-espace/*, _redirects acteur et mairie, static export Next.js, font Ubuntu auto-hébergée

8. Fonctionnalités V1 incomplètes

FeatureManque
Workspace acteur — gate propriétairePas de redirect si non-owner côté frontend
Stats acteur — graphiques temporelsEncart placeholder "prochaine version"
Paramètres acteur — membres/notifsInterface "à venir" uniquement
Mur de ville (home)Conditionnel feature_tabs — désactivé par défaut
Mur contributeur personnelFeature-flaggé get_mur_contributeur_enabled
Publications workspace — image uploadÀ vérifier : l'upload image dans la modal publication workspace n'a pas été audité en détail
Paiement abonnementsNon ouvert (ComingSoonModal), Stripe structuré mais pas de flow client

9. Fonctionnalités hors scope V1 (bonus/partiel)

  • Achat de boosts : bouton "Acheter des boosts — bientôt disponible" (avantages/page.tsx:306)
  • Double publication Facebook : champ présent dans les plans, implémentation absente
  • Support prioritaire : feature plan sans implémentation
  • RBAC contextuel : NEXT_STEPS.md décrit un futur système de rôles granulaires
  • Versionnement API /api/v1/ : NEXT_STEPS.md note que le préfixe v1 n'est pas encore appliqué
  • Graphiques d'évolution stats : placeholder explicite
  • AssoSuite / PlayLoop / Chat : modules API présents mais frontend non audité
  • Module Community : présent dans l'API mais non branché au frontend

10. Risques sécurité

🔴 CRITIQUE — Absence de gate propriétaire frontend (workspace acteur)

Impact : Un utilisateur authentifié A peut naviguer sur /mon-espace/acteur/acteur-de-B/tableau-de-bord et voir le tableau de bord, les publications, les stats et les informations privées de B. Les mutations sont protégées par l'API (ActeurPolicy) mais les lectures Supabase dans le workspace profil page (ligne 179) utilisent directement le client Supabase sans filtrer sur user_acteurs. Un utilisateur malveillant peut lire les données d'un acteur dont il n'est pas propriétaire via le client Supabase.

Spécifiquement : profil/page.tsx:179 fait un supabase.from("acteurs").select(...) sans vérifier user_acteurs. La RLS Supabase est la dernière ligne de défense — si la RLS permet à tout utilisateur authentifié de lire tous les acteurs, alors les données sont lisibles.

🟡 MOYEN — Clés Supabase anon hardcodées dans next.config.ts

Niveau de risque réel : faible (c'est une clé publique), mais mauvaise pratique.

🟡 MOYEN — Pas de rate limiting sur routes critiques

Routes sans throttle : POST /claims (public), POST /publications (auth), POST /ai/publication/generate (auth). Un acteur malveillant authentifié pourrait spammer l'endpoint AI et générer des coûts.

🟡 MOYEN — SUPABASE_DB_PASSWORD dans .env.local frontend

Non commis (.gitignore), mais présence inexpliquée. Un frontend Next.js n'a jamais besoin d'accéder à la DB Postgres directement.

🟢 OK — Pas de service_role dans le frontend

Aucune occurrence de service_role dans les fichiers audités frontend. Bon signe.

🟢 OK — Sanctum token exchange

Le flux Supabase JWT → Sanctum token est correct : le frontend échange le JWT Supabase contre un token Sanctum via /auth/exchange, qui est ensuite utilisé pour toutes les mutations API. Le token est mis en cache en sessionStorage avec expiration.

🟢 OK — ActeurPolicy et PublicationPolicy

Les policies Laravel vérifient correctement la propriété via user_acteurs (acteurs) et l'auteur (publications). $this->authorize() est appelé sur les routes d'écriture.

🟢 OK — Admin middleware

EnsureUserIsAdmin vérifie users_roles.role = 'admin' avant tout accès /api/admin/*. Double vérification auth + rôle.

⚠️ ATTENTION — CORS Sanctum non configuré pour production

config/sanctum.php ne liste que localhost dans stateful. Pour un usage token-based (Sanctum Bearer), cela n'est pas bloquant, mais à documenter.


11. Risques UX

Charte couleur violée (4 occurrences)

Les classes violet-* apparaissent dans 4 endroits clés (badge catégorie, aperçu thème). Ces badges violets sont visibles par les utilisateurs finaux sur les fiches acteurs publiques et dans le workspace. Impact visuel modéré.

Espace acteur : accès sans ownership affiché

Un utilisateur non propriétaire qui arrive sur un espace acteur verra un tableau de bord complet sans message d'erreur clair. Les actions échoueront silencieusement (403 API) — expérience confuse.

Mur de ville désactivé par défaut

La page d'accueil (/) redirige vers HomeHero si feature_tabs.mur-ville est false. Les nouveaux utilisateurs verront une page d'accueil sans contenu dynamique. À documenter comme choix de déploiement progressif.

Mur contributeur non accessible par défaut

Le mur personnel du contributeur est contrôlé par get_mur_contributeur_enabled — si à false, l'utilisateur voit "Fonctionnalité bientôt disponible". La valeur par défaut de cette RPC n'a pas été auditée.

Paramètres acteur très vide

La page paramètres ne contient que l'email affiché et un bouton déconnexion. Pour un lancement V1, l'utilisateur s'attendrait à plus.

Chaque clic sur "Choisir [plan]" ouvre une modal expliquant que le paiement n'est pas encore ouvert. C'est honnête mais peut décevoir lors d'un demo ou lancement.


12. Risques déploiement

Worker CF hostname hardcodé

/Users/sylvain/dev/dmv/dmv-workspace/cloudflare/mon-espace-proxy-worker.js:13PAGES_HOSTNAME = "dmv-mon-espace.pages.dev" est hardcodé. Si le projet CF Pages est renommé ou migré, le proxy casse sans modification du Worker.

dynamicParams = false + _redirects dépendance critique

Le workspace Next.js ne génère statiquement que slug = "_". Toute la mécanique de routing dynamique repose sur la règle _redirects :

/acteur/:slug/* /acteur/_/:splat 200

Si cette règle n'est pas correctement appliquée en production CF Pages, toutes les pages acteur retournent 404.

dmv-public sans env vars dans next.config

dmv-public/next.config.mjs ne contient pas d'env vars hardcodées — elles doivent être définies dans CF Pages (settings Build). Le NEXT_PUBLIC_SUPABASE_* doit être configuré côté CF Pages. Si oublié, le site public ne charge aucun acteur.

API sans préfixe /v1/ officiel

NEXT_STEPS.md note que le préfixe /v1/ n'est pas encore appliqué uniformément via le routage Laravel. Le frontend pointe sur https://api.dansmonvillage.fr/api/v1 — si le routage Laravel n'expose pas correctement ce préfixe, toutes les requêtes échouent.

Stripe webhook URL

NEXT_STEPS.md mentionne que la route webhook Stripe est maintenant /api/v1/webhooks/stripe et doit être mise à jour dans le dashboard Stripe avant les tests paiement.


13. Données de test manquantes

DonnéeStatutImpact
Communes de testManquante (seeder)Tests Laravel isolés impossibles
Acteurs de démonstrationManquante (seeder)Demo uniquement via Supabase prod/staging
Types de publicationsManquante (seeder)Dépend de Supabase
Plans d'abonnementManquante (seeder)subscription_plans lus depuis Supabase directement
Boost catalogPrésent (BoostCatalogSeeder)OK
Règles de récompensePrésent (RewardRuleSeeder)OK
Utilisateur admin de testPrésent (test@example.com)Limité
Acteurs revendiquésManquanteTest du claim impossible en CI

Conséquence : l'intégralité des tests manuels dépend des données Supabase (prod ou staging). Il n'y a pas de jeu de données reproductible pour les tests Laravel.


14. Plan d'action priorisé

Sprint immédiat (avant go-live)

  1. [P0-1] Ajouter dans acteur-layout-client.tsx : si !currentUserActeur après chargement, afficher "Accès non autorisé" ou rediriger vers /connexion (10 lignes de code)
  2. [P0-1 bis] Vérifier mairie-guard.tsx pour le même pattern côté mairie
  3. [P1-1] Remplacer les 4 classes violet-* par blue-* dans ActorsClient.tsx, MurVille.tsx, profil/page.tsx
  4. [P0-2] Sortir les clés Supabase de next.config.ts workspace — les passer via variables d'env CF Pages (ou au minimum via .env.local non commis)
  5. [P1-2] Supprimer SUPABASE_DB_PASSWORD de .env.local dmv-public
  6. [P0-3] Ajouter throttle:60,1 sur POST /ai/publication/generate et POST /claims

Sprint court terme (post-lancement)

  1. [P1-4] Externaliser PAGES_HOSTNAME dans les variables Worker CF
  2. [P1-3] Vérifier la route /mon-espace/acteur?slug=…&tab=abonnement dans dmv-public
  3. [P2-4] Corriger le type ActeurKind dans types/index.ts
  4. Ajouter des seeders communes + acteurs de test pour CI

Moyen terme (V1.1)

  1. Graphiques d'évolution stats
  2. Paramètres acteur : gestion membres, notifications
  3. Paiement abonnements (flow Stripe)
  4. Versionnement API /api/v1/ unifié
  5. RBAC contextuel (municipal_manager, moderator)

15. Verdict : Go / No-Go V1

NO-GO strict — GO conditionnel après 3 corrections

Le code est de bonne facture et l'architecture est solide. Mais 3 corrections sont nécessaires avant tout accès réel d'utilisateurs :

  1. Gate propriétaire workspace acteur (P0-1) — risque de fuite de données et d'expérience brisée
  2. Env vars sorties du code versionné (P0-2) — bonne pratique minimale
  3. Rate limiting routes AI et claims (P0-3) — protection contre abus et coûts imprévus

Si ces 3 points sont corrigés, le reste de l'écosystème est prêt pour un lancement pilote (une commune, une poignée d'acteurs) avec les limitations connues et documentées (paiement désactivé, stats sans graphiques, paramètres acteur minimalistes, mur contributeur feature-flaggé).

Le score de 76 % reflète un produit solide pour une V1 pilote, pas un produit finalisé. Les lacunes sont connues, documentées (NEXT_STEPS.md, badges "à venir"), et non bloquantes pour l'usage cœur de l'annuaire et de l'espace acteur.


Audit réalisé par analyse statique du code — 2026-06-07
Fichiers couverts : ~35 fichiers TSX/PHP/JS lus intégralement + ~20 grepped