karbe/src/lib/plugins/registry.ts
Ubuntu 18d19538d3
All checks were successful
CI / test (pull_request) Successful in 2m40s
feat(ce): Sprint P — seed démo CE + tests invites + cleanup helper
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>
2026-06-03 03:13:14 +00:00

167 lines
6 KiB
TypeScript

/**
* Plugin Karbé — registry statique des plugins disponibles.
*
* Chaque plugin déclaré ici sera synchronisé en DB au démarrage (insertion si absent,
* sans toucher au flag `enabled` existant). L'état (enabled / config) est piloté
* depuis /admin/plugins. Le code des plugins est TOUJOURS présent dans le bundle ;
* l'activation au runtime conditionne juste l'exposition des pages, routes et composants.
*/
export type PluginCategory = "core" | "visual" | "business" | "content" | "i18n";
export interface PluginDescriptor {
key: string;
name: string;
description: string;
category: PluginCategory;
version: string;
}
export const PLUGINS: PluginDescriptor[] = [
// Visuels
{
key: "theme-guyane",
name: "Thème Guyane",
description:
"Palette tropicale (vert canopée, eau Maroni, ocre latérite, bois karbé) + typographies display + tokens Tailwind.",
category: "visual",
version: "0.1.0",
},
{
key: "theme-aquarelle",
name: "Thème Aquarelle (carnet naturaliste)",
description:
"Direction artistique « carnet de voyage XIXᵉ » : papier teinté crème, traits sépia fins, aquarelles ocres+verts délavés, typographie display PT Serif. Active automatiquement les illustrations aquarelle si présentes. Mutuellement exclusif avec theme-guyane.",
category: "visual",
version: "0.1.0",
},
{
key: "landing-hero",
name: "Hero d'accueil",
description:
"Refonte de la page d'accueil avec hero plein écran, claim, CTA double Découvrir/Proposer.",
category: "visual",
version: "0.1.0",
},
{
key: "landing-sections",
name: "Sections d'accueil",
description:
"Sections « 2 expériences », « Comment ça marche », « Pour comités d'entreprise », « Témoignages », footer riche.",
category: "visual",
version: "0.1.0",
},
{
key: "image-gallery-seed",
name: "Galerie d'images seed",
description:
"8 images photo-réalistes générées (carbets, intérieurs, pirogue) stockées dans MinIO. Illustrations vectorielles pour les sections.",
category: "visual",
version: "0.1.0",
},
{
key: "image-gallery-aquarelle-seed",
name: "Galerie aquarelles seed",
description:
"14 illustrations aquarelle (6 planches naturalistes carbets, 7 scènes carnet de voyage, 1 ornement palmier) stockées dans MinIO/karbe-medias/seed/aquarelle/. Création des Media liés aux 6 carbets démo. Désactivation : suppression des Media seedés (les fichiers MinIO restent).",
category: "visual",
version: "0.1.0",
},
{
key: "demo-carbets-seed",
name: "Carbets de démo",
description:
"5-8 carbets d'exemple avec photos, GPS réels, types d'accès variés. Désactivation = soft-delete via tag.",
category: "visual",
version: "0.1.0",
},
// Métier
{
key: "access-type",
name: "Type d'accès route/fleuve",
description:
"Distinction ROAD_AND_RIVER vs RIVER_ONLY (badge, filtre recherche, fiche enrichie). Migration soft.",
category: "business",
version: "0.1.0",
},
{
key: "seasonality",
name: "Saisonnalité",
description:
"Saison sèche / pluies / étiage. Bandeau d'alerte, dispo conditionnelle, filtre « ouvert maintenant ».",
category: "business",
version: "0.1.0",
},
{
key: "pirogue-providers",
name: "Prestataires pirogue",
description:
"Partenaires pirogue + mode transport sur Carbet (OWNER_PROVIDES / SELF_ARRANGE / PARTNER_PROVIDER).",
category: "business",
version: "0.1.0",
},
{
key: "min-stay",
name: "Durée min/max séjour",
description:
"Contraintes nuits min/max, capacité min, règles week-end CE vs semaine public mappées dans Availability.",
category: "business",
version: "0.1.0",
},
{
key: "gear-rental",
name: "Location matériel (sous-marketplace)",
description:
"Catalogue matériel (hamac, moustiquaire, pirogue, kayak…) loué par System D et prestataires tiers. Inclut panier, checkout Stripe, espace prestataire, recommandations carbet. Si désactivé : /materiel, /espace-prestataire et /mes-locations renvoient 404; liens header masqués.",
category: "business",
version: "0.1.0",
},
{
key: "ce-management",
name: "Gestion des Comités d'Entreprise",
description:
"Permet à un CE de s'inscrire (validation admin), publier ses carbets en co-gestion (OrganizationCarbetMembership), et activer un RentalProvider org-scoped pour louer son matériel. Dashboard /espace-ce avec KPIs agrégés par organisation. Si désactivé : /espace-ce et le choix « Comité d'Entreprise » sur /inscription disparaissent.",
category: "business",
version: "0.1.0",
},
// Contenus / i18n
{
key: "content-pages",
name: "Pages de contenu",
description:
"Pages markdown éditables depuis l'admin (À propos, FAQ, Comment ça marche, Pour CE, Devenir loueur).",
category: "content",
version: "0.1.0",
},
{
key: "i18n-fr-en",
name: "i18n FR + EN",
description: "Routes [locale]/, détection navigateur, switcher header. Plugin désactivable = FR pur sans préfixe.",
category: "i18n",
version: "0.1.0",
},
{
key: "legal-pages",
name: "Pages légales",
description: "CGV, RGPD, mentions légales (absorbe SYS-9). Markdown + rendu statique.",
category: "content",
version: "0.1.0",
},
{
key: "demo-ce-seed",
name: "Démo Comité d'Entreprise",
description:
"Seed une organisation CE démo (Comité ESA Kourou) avec 2 managers, 3 membres, 2 carbets co-gérés et 1 provider rental org-scoped + 4 items. Utile pour visualiser le module CE sans signup manuel. Disable : carbets archivés, users + org supprimés. Dépend de `ce-management`.",
category: "visual",
version: "0.1.0",
},
];
export const PLUGIN_KEYS = PLUGINS.map((p) => p.key);
export type PluginKey = (typeof PLUGIN_KEYS)[number];
export function findDescriptor(key: string): PluginDescriptor | undefined {
return PLUGINS.find((p) => p.key === key);
}