Some checks failed
CI / test (pull_request) Failing after 1m10s
3 nouveaux templates email (best-effort, dry-run sans Resend) : - sendRentalRequestedTenant : récap de demande au locataire (par RB) - sendRentalRequestedProvider : nouvelle demande au prestataire - sendRentalConfirmed : confirmation paiement reçu Branchements : - POST /api/rentals/checkout : envoie tenant + provider après création des RentalBooking (PENDING), catch global pour ne pas bloquer - Webhook Stripe rental-bundle : envoie sendRentalConfirmed à chaque locataire après update CONFIRMED+SUCCEEDED Plugin gear-rental : - Ajout au registry (catégorie business) - layout.tsx /materiel + /espace-prestataire avec requirePluginOr404 - requirePluginOr404 dans /panier et /mes-locations - isPluginEnabled guard dans POST /api/rentals/checkout (404 si off) - SiteHeader masque liens Matériel / Mes locations / Espace prestataire + CartBadge si plugin désactivé - CompleteYourStay renvoie null si plugin désactivé Décision admin → activable depuis /admin/plugins comme tous les autres. Tests vitest (tests/lib/rentals.test.ts, 16 tests) : - diffDays (mêmes dates, 1 nuit, 7 jours, négatif) - parseCart (null/garbage/schéma invalide/valide/format date) - serializeCart (updatedAt, roundtrip) - commission formula (0%, 15%, arrondi centime) - availability arithmetic (totalQty libre, soustractions, plancher 0) 53 tests pass total. Build OK. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
151 lines
5.1 KiB
TypeScript
151 lines
5.1 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",
|
|
},
|
|
|
|
// 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",
|
|
},
|
|
];
|
|
|
|
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);
|
|
}
|