Évaluer et adapter

Comment Sushi SaaS est structuré

Comprendre les couches imposées, leurs compromis et comment ajouter une fonctionnalité sans créer une seconde architecture.

Ce guide aide les adoptants à placer leur première fonctionnalité produit. Sushi SaaS applique une architecture horizontale à tous les domaines et des tests en imposent les règles.

Le parcours d’une requête

src/app/**       routes et pages — HTTP entrant et sortant

src/services/**  règles métier, orchestration, invariants

src/models/**    persistance typée ; seule couche appelant db()

src/db/**        schéma, migrations, connexion

Une route analyse et répond. Un service décide si l’action est autorisée et coordonne les effets. Un modèle possède les lectures et écritures. Les contraintes de base restent la dernière protection contre les requêtes concurrentes.

Le navigateur suit une autre frontière :

Server Component  → service directement
Client Component  → src/api/** → client API partagé → /api/**

Cela évite au serveur un appel HTTP vers lui-même et donne aux erreurs client un contrat unique. Les règles exactes figurent dans Architecture et contrats d’erreur.

Pourquoi des couches horizontales

Facturation, crédits, stockage, réservations et tâches ont tous besoin d’authentification, de scope tenant, d’erreurs et de persistance. Les mêmes couches rendent chaque responsabilité prévisible et permettent aux tests de détecter les raccourcis.

En contrepartie, une fonctionnalité se répartit entre plusieurs dossiers. Un dossier vertical par feature peut être plus lisible dans un grand produit ; mélanger les deux structures est toutefois pire, car chaque nouvelle requête ou règle a deux emplacements plausibles.

Vos options

  • Garder la structure livrée pour une petite équipe qui veut des conventions fortes et une infrastructure commune.
  • Passer entièrement aux tranches verticales si c’est la norme de l’équipe. Déplacez des domaines complets et adaptez tests/unit/architecture.test.ts ; n’ajoutez pas un îlot src/features à côté des règles actuelles.
  • Simplifier pour un prototype temporaire en acceptant une migration ultérieure. Si les routes écrivent directement en base, modifiez explicitement le test au lieu d’empiler des exceptions.

La tenancy est aussi un choix d’architecture

Chaque utilisateur reçoit une organisation personnelle. Un client seul et une équipe utilisent ainsi les mêmes facturation, crédits, fichiers et limites au scope organisation, sans deux chemins parallèles « utilisateur » et « équipe ».

Gardez ce modèle si des équipes sont possibles. Pour un produit toujours mono-utilisateur, retirer les organisations est valide, mais coordonne autorisation, schéma, modèles, facturation, stockage et tests ; ce n’est pas un simple toggle UI. Lisez Organisations et équipes avant de décider.

Pourquoi l’admin est séparé

apps/admin possède pages, APIs, accès aux données, barrière MFA et rôles opérateur. Il partage schéma et auth, mais peut tourner sur une autre origine. Le coût est un build et un déploiement supplémentaires ; le bénéfice, une frontière opérateur claire.

Vous pouvez le fusionner avec l’application client pour un déploiement unique. Conservez l’autorisation admin côté serveur et l’audit : masquer la navigation n’est pas une mesure de sécurité. Commencez par Configurer la console d’administration.

Un parcours vertical complet à travers les couches

La référence image montre l’intérêt de la structure. La route authentifie ; le service empreinte la requête, réserve une dépense déterministe de cinq crédits et distribue le job ; les modèles possèdent SQL ; les contraintes relient les enregistrements ; l’adaptateur reste remplaçable ; le worker stocke en privé ou compense le registre. Tests route, service, base, composant et Playwright prouvent chacun une frontière.

Lisez Pourquoi une tâche de cinq crédits teste tout le SaaS avant votre premier domaine payant.

Ajouter votre premier domaine

  1. Définissez vocabulaire et limites dans src/types et src/config.
  2. Ajoutez schéma et migration expand-safe dans src/db.
  3. Placez le CRUD typé dans src/models.
  4. Placez autorisation, idempotence et effets dans src/services.
  5. Ajoutez route ou Server Component dans src/app ; utilisez src/api côté client.
  6. Testez la règle service, la barrière auth de la route et les replays pour argent ou crédits.

Testez les capabilities plutôt que le nom du plan et mettez à jour le runbook si le contrat change. Ce guide reflète le commit 2a1a04a.

Comment Sushi SaaS est structuré · Sushi SaaS