YYayaw

Architecture

Architecture de haut niveau et principaux modules techniques.

Vue d'ensemble

Yayaw utilise le Next.js App Router avec des routes préfixées par la locale (/en, /fr). Le produit est organisé autour d'un tableau de bord multi-tenant authentifié, d'un runtime CMS public et d'un plan de contrôle (control plane) réservé au serveur pour l'automatisation de confiance.

Parcours de lecture clés:

Principaux blocs de construction

Frontend et routage

  • Routes applicatives dans src/app
  • Middleware de locale et routage dans src/i18n et src/lib/middleware
  • Blocs UI du tableau de bord sous src/blocks
  • La configuration partagée de routes/navigation pilote la barre latérale, le menu de commande, les fils d'Ariane et la visibilité des routes.

Convention de nommage du tableau de bord

  • Le titre de page définit le sujet de la page (par exemple: Media, Billing, Authorization).
  • Le titre de bloc définit l'entité gérée et implique l'action (par exemple: Assets manager).
  • La description de bloc explique, en une phrase courte, ce que les utilisateurs peuvent faire dans ce bloc.

Authentification et autorisation

  • Configuration Better Auth dans src/config/better-auth.config.ts
  • Intégration serveur auth dans src/lib/server/services/auth/auth-drizzle.ts
  • Les clés API Better Auth sont activées pour l'accès au plan de contrôle avec des permissions explicites control-plane:read, control-plane:write, control-plane:publish et control-plane:admin
  • Les capacités d'administration Better Auth incluent l'usurpation contrôlée et le provisionnement SCIM (@better-auth/scim)
  • L'onboarding par invitation d'organisation privilégie la clé d'accès (passkey) et utilise des tokens d'onboarding d'invitation hachés, stockés hors de la table d'invitations Better Auth
  • Synchronisation des rôles d'organisation dans src/lib/server/services/authz
  • Le modèle d'autorisation interne reste dans Yayaw (Permix + Drizzle):
    • groupes et appartenances
    • bindings scopés explicites dans group_role_bindings
    • policies de rôles dans role_policies
  • Moteur d'autorisation explicable dans src/lib/server/authz:
    • authorizeDetailed(...) pour autorisation/refus + chaîne de décision
    • can(...) comme façade booléenne utilisée par les routes et les actions
  • Actions serveur personnalisées d'administration AuthZ pour liste/détail/bulk/simulate/explain/audit dans src/lib/server/actions/authz/authorization-admin-actions.ts

Couche de données

  • Configuration Drizzle dans src/lib/db
  • Schémas organisés par domaine:
    • schéma Better Auth
    • schéma d'autorisation
    • schéma système
  • Les parents de la barre latérale du tableau de bord sont des tableaux de bord de section navigables. /dashboard/content est le tableau de bord de santé du CMS; il résume l'inventaire de contenu de l'organisation active, l'état de publication, le stockage média, les données CMS et les jobs de génération IA avant que les utilisateurs ne descendent dans les écrans de catalogue dédiés. /dashboard/admin, /dashboard/organization, /dashboard/settings et /dashboard/test sont aussi des racines de section valides; les parents de barre latérale ne pointent donc jamais vers des pages masquées ou manquantes. Le shell de tableau de bord utilise des fils d'Ariane shadcn et une barre de navigation de section partagée dérivés de la hiérarchie de barre latérale filtrée; cette barre liste uniquement les routes enfants de la section dashboard active.
  • Médiathèque d'organisation dans le schéma système:
    • media_folders et media_assets sont scopés par organisation
    • les ressources média sont stockées dans un stockage objet public (bucket media) avec un publicUrl persisté
    • le stockage est adossé à un fournisseur: Supabase reste supporté et le stockage compatible S3 couvre MinIO, S3 et les déploiements de type R2
    • les assets visuels peuvent stocker des miniatures WebP générées pour l'affichage en médiathèque; les miniatures manquantes sont générées opportunistement lors du listage de la médiathèque et ne comptent pas dans le quota de téléversement utilisateur
    • les actions serveur appliquent toujours scope: { orgId } et rejettent les mutations inter-organisations
    • lecture/listage disponibles pour les membres d'organisation, téléversement/édition/suppression réservés aux rôles manager ou admin
    • les quotas de téléversement viennent de la configuration à l'exécution de facturation des plans (par fichier et stockage total de l'organisation)
    • la génération d'images du page-builder stocke les sorties WebP OpenAI par le même pipeline de téléversement/persistance média
  • Catalogue de sections réutilisables dans le schéma système:
    • ui_section_registry_items stocke l'identité stable des sections built-in, globales et d'organisation
    • ui_section_revisions stocke le JSON SectionDefinitionV1 validé + les diagnostics
    • ui_section_publications stocke l'état de cycle de vie et le pointeur vers la dernière révision publiée
    • les définitions de section stockent uniquement les ids de renderers, les recettes, les références de composants et les bindings
    • les pages utilisent des références PageSection pour suivre la dernière section publiée
    • la création de section par IA utilise un shell réutilisable de plan workbench:
      • src/components/ai/plan-workbench/*
      • tiroir adaptateur de section: src/blocks/dashboard/content/sections/block-ai-create-drawer.tsx
      • endpoint de plan streaming: src/app/api/ai/blocks/plan/route.ts
      • endpoints de runs/jobs persistés (resume/poll/cancel): src/app/api/ai/blocks/plan/jobs/*
      • tables de stockage persisté:
        • ui_block_ai_threads
        • ui_block_ai_runs
        • ui_block_ai_run_events
      • abstraction runner: src/lib/server/services/blocks/block-ai-plan-runner.ts
      • le contrat de prompt IA inclut des instructions explicites de design policy (réutilisation de composants + patterns de layout cohérents avec le projet)
      • action de finalisation avec approbations explicites des imports manquants: createBlockFromAiPlanAction
    • les points d'entrée de création IA sont gardés par le réglage de site ai-components-enabled, afin que l'UI et les actions serveur se désactivent ensemble.
  • Catalogue hybride de pages dans le schéma système:
    • ui_page_registry_items stocke l'identité de page, le scope/channel, le chemin et les métadonnées
    • ui_page_revisions stocke un PuckPageDocumentV1 versionné + diagnostics
    • La génération IA de pages utilise un état durable Postgres:
      • ui_page_ai_runs
      • ui_page_ai_run_events
      • APIs sous src/app/api/ai/pages/runs/*
      • Vercel Queues peut réveiller la route worker hébergée; bun run worker:page-ai interroge le même état DB pour les déploiements auto-hébergés avec worker long-lived
    • ui_page_publications stocke l'état de cycle de vie et le pointeur vers la révision publiée
    • l'UX du tableau de bord est divisée entre liste/table puis route d'éditeur dédiée par page
    • l'éditeur est Puck + shadcn direct (aucun chemin de fallback legacy)
    • le modèle de sauvegarde est autosave + publish/archive avec verrouillage optimiste (baseRevisionId)
    • la gestion de conflit est explicite (réponse conflict) sans merge/rebase automatique
    • le runtime lit directement les documents Puck publiés
    • les pages globales se résolvent depuis /[locale]/[...slug]
    • les pages membres d'organisation se résolvent depuis /[locale]/o/[orgSlug]/[[...slug]]
    • la publication est bloquée en cas d'erreurs de diagnostics et de collisions avec des routes réservées
  • Politique d'approbation du registre global dans le schéma système:
    • ui_registry_templates stocke les alias shadcn compatibles approuvés + les modèles d'URL
    • les pipelines d'import résolvent les alias externes uniquement depuis les modèles approuvés
    • la page d'administration est disponible à /dashboard/admin/registry-templates
  • Actions serveur générées dans src/lib/server/actions/database/generated

Observabilité et indicateurs de fonctionnalité

  • Intégration serveur/client PostHog dans src/lib/posthog et src/providers
  • Indicateurs dynamiques dans src/lib/flags
  • Valeurs par défaut des indicateurs gérés déclarées dans src/config/flags.config.ts et seedées par src/lib/scripts/seed.ts
  • Les réglages de site admin s'appuient sur des lignes feature_flags gérées par le code
  • Les indicateurs personnalisés sont générés depuis les lignes feature_flags non gérées et n'affectent le comportement à l'exécution que lorsque le code lit explicitement leur slug
  • Capacités auth runtime résolues dans src/config/authentication-runtime.config.ts
  • Les analytics du tableau de bord sont pilotées par un view-model serveur dans src/lib/server/services/dashboard:
    • /dashboard/admin est la surface de santé plateforme superadmin avec revenu Stripe, audience PostHog, croissance des utilisateurs inscrits, risque de facturation et actions admin. Le parent admin de la barre latérale est un lien direct vers cette route.
    • /dashboard est un accueil de navigation conscient des permissions, construit depuis les racines de sections visibles et les liens rapides, sans dupliquer la santé organisationnelle ou les métriques fournisseur
    • les propriétaires/admins/managers d'organisation voient la facturation, les sièges, l'inventaire de contenu, l'usage et les actions de gestion sur les tableaux de bord de section scopés organisation
    • les membres d'organisation voient uniquement l'activité opérationnelle et les raccourcis sûrs sur les sections auxquelles ils ont accès
    • les agrégats base de données, PostHog et Stripe utilisent le Data Cache partagé de Next.js pendant 5 minutes, avec clés par route, période, organisation et périmètre d'accès, tandis que session et autorisation restent par requête
    • les analytics de vues CMS lisent les événements cms_page_viewed pour les pages de l'organisation active et incluent les pages globales seulement pour les acteurs ayant page:manage global, y compris les classements de pages principales sur /dashboard/content
    • les fallbacks par fournisseur évitent qu'une source de métriques défaillante casse la page
    • le statut de déploiement est adossé au fournisseur: les lectures Vercel restent disponibles, tandis que les runtimes auto-hébergés peuvent fournir des métadonnées statiques via les variables DEPLOYMENT_*
    • les événements PostHog enregistrés depuis l'app incluent organization_id lorsqu'une organisation active est disponible, ce qui permet les analytics scopées par organisation

Fournisseurs De Déploiement

La première cible auto-hébergée portable de Yayaw est Docker standalone Next.js avec Postgres, stockage objet compatible S3, worker Page AI adossé à la base et proxy inverse qui préserve Host et X-Forwarded-*. Vercel reste un fournisseur supporté pour l'hébergement, les queues, les métriques de déploiement et la vérification des domaines projet, mais ces capacités ne sont plus présumées par le runtime coeur.

Seams runtime:

  • stockage: STORAGE_PROVIDER=supabase|s3
  • domaines publics d'organisation: PUBLIC_DOMAIN_PROVIDER=vercel|manual-dns
  • réveil Page AI: PAGE_AI_QUEUE_DRIVER=direct|vercel-queue|db-worker
  • métadonnées de déploiement: variables runtime Vercel ou variables statiques DEPLOYMENT_*

Postgres + Drizzle est la source de vérité des données applicatives. Supabase n'est pas requis pour la persistance coeur; c'est seulement un fournisseur optionnel de stockage objet et un workflow de reset local.

Plan de contrôle

  • Endpoint MCP de production: src/app/api/mcp/route.ts
  • Lanceur stdio local: src/lib/scripts/mcp/yayaw-mcp-server.ts
  • Script de gestion des clés: src/lib/scripts/mcp/control-plane-key.ts
  • Registre partagé d'opérations typées: src/lib/server/services/control-plane
  • Stockage d'audit: control_plane_audit_events
  • L'accès production exige le réglage de site control-plane-mcp-enabled, une clé API Better Auth valide ou un access token OAuth, des permissions de plan de contrôle et l'autorisation Yayaw sous-jacente
  • Les outils d'écriture exigent reason; les flux de publication optimistes exigent expectedRevisionId; les archives destructrices exigent confirm: true

Règle pour les futures fonctionnalités:

  • Traiter par défaut les workflows d'exploitation, contenu, configuration, publication, audit et statut comme candidats au plan de contrôle
  • Placer la logique métier réutilisable derrière des points d'entrée de service explicites et conscients de l'acteur
  • Garder les actions serveur UI, outils MCP, scripts CLI et APIs HTTP facultatives comme de fins adaptateurs au-dessus de la même logique de service
  • Ajouter outils/ressources MCP typés, couverture d'audit, docs, mises à jour de la source LLM et tests ciblés dans le même changement lorsqu'une fonctionnalité devient opérable par le plan de contrôle
  • Documenter les exclusions intentionnelles lorsqu'une fonctionnalité reste uniquement UI

Contrat des indicateurs de fonctionnalité

Pour les fonctionnalités produit, les indicateurs doivent contrôler:

  • le comportement runtime (plugins/services/actions)
  • l'exposition UI (cartes, actions, entrées de navigation)

Cela évite les désactivations partielles où le backend est coupé mais où les liens UI restent visibles.

Architecture de documentation

  • Docs humaines: pages Fumadocs sous content/docs
  • Source de vérité des docs LLM: content/llm/llm-source.md
  • Docs assistant générées:
    • AGENTS.md
    • GEMINI.md
    • .github/copilot-instructions.md

Lorsque vous changez un comportement produit, mettez d'abord à jour la doc de fonctionnalité anglaise pertinente, puis mettez à jour content/llm/llm-source.md lorsque le comportement assistant ou la source de vérité architecturale change. Régénérez les docs assistant avec:

bun run docs:llm:generate