# Architecture SaaS B2B — Plan complet

## Contexte
Création d'un SaaS B2B généraliste : socle commun réutilisable (auth multi-tenant, connecteurs externes, couche IA multi-fournisseurs, logs, RGPD) sur lequel viendront s'appuyer des modules d'automatisation métier.

**Contraintes :** monorepo, backend monolithique modulaire, une DB par tenant, auto-hébergement France, auth gérée en interne, onboarding manuel, facturation reportée. Équipe très réduite.

**Révisions v2 :** backend Python ; observabilité allégée ; langages/frameworks massivement représentés dans les données d'entraînement des modèles IA.

---

## 1. Stack technique recommandée

| Domaine | Choix |
|---|---|
| Backend | Python 3.12 |
| ORM / migrations | SQLAlchemy + Alembic |
| Base de données | PostgreSQL |
| Jobs / scheduler | Celery + scheduler |
| Authentification | Construite maison |
| Couche IA | LiteLLM (bibliothèque) |
| Frontend | React + Vite |
| Contrat API | OpenAPI |
| Monorepo | uv (Python) |
| Qualité / IA-friendly | ruff + pyright |
| Logs (allégé) | structlog (JSON) |
| Infra | Docker Compose |
| Secrets/chiffrement | AES-256-GCM |

**Écartés suite à la v2 :** NestJS/Drizzle/better-auth (TS, libs trop récentes pour être bien connues des IA), Vercel AI SDK (remplacé par LiteLLM), stack observabilité complète OTel/Prometheus/Tempo (reportée).

---

## 2. Architecture d'ensemble

Monolithe modulaire, deux processus issus du même code :
- **api** (FastAPI / uvicorn)
- **worker** (Celery)
- Même image Docker, entrypoints différents.

**Structure :**
```
apps/
  api/
    app/core/
    app/tenancy/
    app/auth/
    app/directory/
    app/connectors/
    app/ai/
    app/audit/
    app/gdpr/
    app/admin/
    app/automation/
  web/
    admin/
packages/
  api-client/
  ui/
```

**Pratiques IA-friendly :** CLAUDE.md racine + par module (conventions, invariants), typage strict, modules petits et réguliers, tests pytest par module, contrat OpenAPI comme source de vérité front/back.

---

## 3. Multi-tenant et bases par tenant

**DB control-plane :** catalogue tenants, identités globales (email → plusieurs tenants), memberships (user × tenant × rôles), données d'auth/sessions, événements d'usage IA, config plateforme.

**DB tenant :** toutes les données métier + audit log + connexions OAuth tierces → export/effacement RGPD triviaux.

**Résolution du tenant :** sous-domaine (client.app.tld) croisé avec la session ; dépendance FastAPI qui vérifie le membership et attache le contexte tenant (contextvars).
→ *Invariant : aucune requête métier sans contexte tenant résolu.*

**Routage des connexions :** `TenantEngineManager` — async engine SQLAlchemy par tenant, création paresseuse, LRU + fermeture des inactifs, plafond global. PgBouncer (transaction mode) devant le cluster.

**Migrations :** un seul arbre Alembic pour le schéma tenant (+ un pour control-plane). Runner dédié : verrou advisory, itération sur le catalogue, version journalisée par base, rapport d'échecs partiels (une base en échec ne bloque pas les autres mais bloque le déploiement).

**Provisioning :** commande admin (CLI Typer + back-office) : CREATE DATABASE depuis template → migrations → seed → catalogue → invitation du premier owner.

---

## 4. Authentification auto-hébergée et rôles

Auth construite dans le backend sur des briques Python éprouvées (plutôt qu'IdP dédié Keycloak/Zitadel) :
- Mots de passe : **argon2** ; 2FA : **pyotp** (TOTP)
- Sessions serveur en DB control-plane, cookie httpOnly/SameSite, révocables
- OAuth login Google & Microsoft : **Authlib** (référence Python OAuth/OIDC)
- SSO entreprise entrant : OIDC via Authlib, SAML via python3-saml, configurable par organisation
- Inscription publique désactivée : uniquement invitations

**Plan B documenté :** si SCIM ou exigences IdP lourdes → basculer vers Zitadel/Keycloak self-hosted.

**RBAC :** rôles plateforme (platform_admin) ; rôles tenant (owner, admin, member + rôles custom) ; permissions granulaires `ressource.action` vérifiées par une dépendance FastAPI unique.

---

## 5. Framework de connecteurs externes

- **Provider :** Google, Microsoft... (manifest : scopes OAuth, capabilities, endpoints webhooks)
- **Connection :** instance liée à un tenant, statut de santé, refresh tokens, consentement guidé si refresh échoue
- **Capability :** interfaces normalisées (`MailCapability`, `CalendarCapability`, `ContactsCapability`, `FilesCapability`...) — les modules métier consomment les capabilities, jamais les APIs propriétaires

**Mécanique commune :** flux OAuth tiers distincts du login ; refresh proactif des tokens par tâche Celery ; webhooks entrants/provider + jobs de renouvellement (Microsoft Graph ~3 jours, Google Push ~7) ; rate limiting par provider + backoff.

**Premières implémentations :** Google Workspace (google-api-python-client) et Microsoft 365 (msgraph-sdk + msal).

---

## 6. Couche IA et mesure de consommation

**AI Gateway (module `ai`) :** interface interne unique — chat, streaming, tool-calling, embeddings — au-dessus de LiteLLM en mode bibliothèque (pas de proxy séparé).

**Routing par politique de tenant :** provider/modèle par défaut, providers autorisés, option « zéro rétention » (Mistral France, endpoints Zero-Data-Retention).

**Providers initiaux :** Anthropic, OpenAI, Mistral.

**Metering :** événement structuré par appel (timestamp, user, module, provider, modèle, tokens in/out/cachés, latence, coût estimé) → `ai_usage_events` en control-plane + agrégats journaliers.

**Garde-fous :** quotas par tenant (soft limit + alerte), timeout, fallback de provider optionnel.

**RGPD IA :** Anthropic/OpenAI = transfert hors UE (DPA + SCC) ; Mistral = France. Politique « zéro rétention » par tenant.

---

## 7. Logs, observabilité (allégée) et RGPD

**Logs techniques :** structlog JSON, corrélés (request_id, tenant_id, user pseudonymisé), rédaction des PII → Loki + Grafana (2 conteneurs, collecte Promtail/Alloy). Rétention 30 jours.

**Supervision minimale :** endpoints /health, Uptime Kuma (1 conteneur) pour l'alerte de disponibilité (email/ntfy).

**Reporté (phase 8) :** Prometheus/métriques fines, traces, GlitchTip/Sentry.

**Audit log applicatif :** qui a fait quoi, quand, sur quoi — DB du tenant, consultable dans l'app.

**RGPD :**
- DB-par-tenant + France = minimisation structurelle
- Export = dump base tenant + données control-plane associées
- Effacement = drop + purge catalogue + purge backups à échéance
- Chiffrement : disques LUKS, TLS partout, secrets/tokens chiffrés applicativement
- Jobs de rétention/purge configurables par type de donnée

**Livrables non techniques :** registre des traitements, DPA type, liste des sous-traitants, procédure de notification de violation.

---

## 8. Besoins et risques non mentionnés

1. **Backups offsite :** pgBackRest chiffré vers object storage français (Scaleway/OVH) + tests de restauration
2. **Disponibilité domestique :** SLA réaliste, page de statut hébergée ailleurs
3. **Vérification apps OAuth :** validation Google (scopes Gmail/Agenda) et Microsoft publisher verification — à lancer dès la phase 3
4. **Emails transactionnels :** relais SMTP français (Scaleway TEM / OVH)
5. **Staging dès le départ** (runner de migrations multi-bases à tester ailleurs qu'en prod)
6. **Sécurité périmétrique :** admin derrière WireGuard, mises à jour auto, fail2ban, scan dépendances en CI
7. **Scalabilité DB-par-tenant :** OK jusqu'à quelques centaines de tenants avec PgBouncer

---

## 9. Ordre de construction (Phases)

| Phase | Description | Critère de démo |
|---|---|---|
| **0** | Fondations : monorepo, CI (ruff, pyright, pytest, tsc), Docker Compose (Postgres, Valkey, Caddy, Loki+Grafana, Uptime Kuma), squelettes api/worker/web, génération client TS depuis OpenAPI, déploiement continu staging | — |
| **1** | Socle multi-tenant : control-plane, catalogue, TenantEngineManager, runner de migrations Alembic multi-bases, provisioning CLI | « Créer un tenant en CLI, migrations appliquées sur N bases, échec partiel correctement rapporté » |
| **2** | Auth + annuaire : sessions, argon2, TOTP, OAuth Google/Microsoft, orgs/équipes/rôles/permissions, invitations | — |
| **3** | Frontends + back-office : SPA client (login, gestion d'équipe), back-office (provisioning, supervision migrations). Lancer vérifications apps OAuth | — |
| **4** | Audit + socle RGPD : audit log, export/effacement, purges | — |
| **5** | Framework connecteurs : abstraction + Google Workspace + Microsoft 365 (mail/agenda), token store chiffré, refresh Celery, webhooks | Le plus gros morceau |
| **6** | AI Gateway : LiteLLM, politiques par tenant, metering, quotas | — |
| **7** | Runtime d'automatisation (coquille) : contrat de module métier (manifest : routes, tâches Celery, permissions, capabilities), scheduler, module d'exemple bout en bout | Prouve qu'un module s'ajoute sans toucher au cœur |
| **8** | Durcissement : SAML client pilote, rate limiting global, métriques Prometheus + GlitchTip, revue sécurité, runbook, restauration testée | — |

**Validation attendue :** (1) stack Python/FastAPI/SQLAlchemy/Celery + React/TS, (2) auth Authlib/python3-saml, (3) identités globales control-plane + données métier DB tenant, (4) observabilité minimale Loki+Grafana+Uptime Kuma, (5) ordre des phases.
