Seed plugin `demo-ce-seed` :
- Nouveau descriptor dans registry (category visual).
- src/lib/plugins/seeds/demo-ce.ts : seedDemoCe() + archiveDemoCe().
Crée org « Comité ESA Kourou (démo) » approved=true + 2 CE_MANAGERs
+ 3 CE_MEMBERs (password "demo") + 2 carbets co-gérés
(OrganizationCarbetMembership) + 1 RentalProvider org-scoped +
4 items (hamac, moustiquaire, kayak, réchaud).
- Idempotent : check existence par slug/email avant create. Upsert
pour users.
- Disable : soft-archive carbets (status=ARCHIVED), delete
RentalProvider démo (best-effort si pas de booking), delete users
démo (cascade memberships) + delete org.
- Branchement hooks onEnable/onDisable dans plugins/hooks.ts.
Permet de visualiser le module CE end-to-end sans signup manuel :
admin active le plugin → l'org démo et son écosystème apparaissent
sur le site (badge « Géré par le CE Comité ESA Kourou (démo) » sur
les fiches carbet, items rental dans le catalogue /materiel).
ce-invites.ts refactor :
- Exporte hashToken (déjà sha256, désormais documenté).
- Extrait isInviteValid(row, now=Date) : helper pur testable. La
fonction getOrgInviteByToken le réutilise.
tests/lib/ce-invites.test.ts (9 cas) :
- hashToken : déterminisme, format sha256 64-hex, inputs différents,
pas de fuite du plain.
- isInviteValid : non consommé+non expiré → vrai ; consommé → faux ;
expiré → faux ; les 2 raisons → faux ; injection now pour tests
temporels.
Total tests : 83/83 ✓ (74 précédents + 9 nouveaux).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Schema:
- Organization gagne le workflow d'approbation (approved + approvedAt +
approvedBy + contactEmail). Backfill : toutes les orgs existantes
(CMCK) → approved=true via migration.
- Nouveau OrganizationCarbetMembership (manyToMany Org↔Carbet) pour la
co-gestion CE : un Carbet a un ownerId (créateur initial) + 0..n
memberships ; chaque CE_MANAGER d'une org liée peut gérer le carbet
en plus de l'owner. Pour un hôte individuel = pas de membership.
- RentalProvider.organizationId (nullable, SetNull on delete) : un CE
peut posséder son provider ; les CE_MANAGERs membres de l'org y ont
accès en plus du manager nominal.
Plugin ce-management ajouté au registry (catégorie business, off par
défaut). Quand off : signup CE caché + dashboard /espace-ce 404.
Admin organizations :
- Tab statut (Toutes / À valider [count] / Validées) avec compteur des
organisations pending dans l'en-tête.
- Badge statut sur la liste et la page détail.
- Bouton « Valider l'organisation » sur le détail (action
approveOrganizationAction → flip approved=true + approvedAt + audit
log organization.approve). Idempotent : un re-appel sur une org déjà
validée ne re-loggue pas.
- Détail montre les compteurs carbetMemberships + rentalProviders.
Migration appliquée à la DB prod (CMCK backfill validé).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Registry : ajoute 2 plugins :
- theme-aquarelle (carnet naturaliste XIXᵉ, mutual exclusion avec theme-guyane)
- image-gallery-aquarelle-seed (14 aquarelles → MinIO + Media carbets démo)
Hooks :
- theme-guyane et theme-aquarelle se désactivent mutuellement au toggle ON
via disableOtherTheme()
CSS (globals.css) :
- body[data-theme=aquarelle] : background papier teinté #faf5e9 + texture
grain papier inline SVG + radial gradients ocres/canopy délavés
- Surcharges automatiques des borders zinc/gray vers sépia délavé
Layout :
- PT_Serif (au lieu de Cormorant) en theme aquarelle, plus dense et encrée
- data-theme = aquarelle prioritaire sur guyane si les deux sont enabled
(défensif — le hook garantit normalement la mutual exclusion)
Hero :
- 2 versions dans le composant : guyane (existant, SVG CarbetRiver) et
aquarelle (image MinIO 01-hero-fleuve-maroni.jpg en fond, voile crème,
texte sépia, CTAs carrés sans rounded, hairlines, ornement de planche)
- Branchement via getActiveTheme()
- aquarelleUrl() helper qui construit l'URL MinIO publique
Partie 2/2 (PR ultérieure) : upload des 14 images dans MinIO + hook
image-gallery-aquarelle-seed + variantes aquarelle des autres composants
(CarbetCard, ExperiencesSection, HowItWorksSection, CESection, Footer).