# PRD — Plateforme SaaS de déploiement et gestion d'applications Docker (jagentix.com)

**Version :** 3.0
**Statut :** À développer
**Type :** SaaS / Docker Application Hosting Platform
**Architecture cible (MVP immédiat) :** Laravel + Vue.js (Inertia) + Docker — **mono-serveur, accès direct par IP:PORT, sans reverse proxy**
**Architecture cible (étape suivante) :** reverse proxy Apache/cPanel + sous-domaines + AutoSSL (voir §15bis)
**Architecture cible (évolution long terme) :** multi-node avec orchestrateur
**Langues initiales :** Français / Anglais
**Applications initiales :**
1. Activepieces
2. Hermes
3. OpenClaw
4. n8n
5. Paperclip
6. Dify
7. Flowise

**Changelog v3.1 :**
- Ajout de la section §36bis — Identité visuelle et anti-AI design (pendant visuel du §44, qui couvrait uniquement le code) : système de design obligatoire à documenter avant implémentation, patterns visuels génériques interdits par défaut (dégradés violet/indigo, glassmorphism, hero IA standard, cartes identiques, badges décoratifs, copywriting générique, dashboards factices), et checklist d'audit anti-AI design à intégrer à la revue de PR frontend.

**Changelog v3.0 :**
- **Décision assumée pour le MVP immédiat : accès direct `http://IP:PORT`, sans Traefik ni reverse proxy Apache, sans sous-domaine, sans SSL.** Cette simplification accélère le lancement mais introduit une dette technique explicite (voir §15bis).
- L'étape "reverse proxy Apache/cPanel + sous-domaines + AutoSSL" envisagée en v2.0 devient une **phase distincte et différée**, avec un critère de déclenchement clair (avant tout lancement public).
- Les containers bindent désormais sur `0.0.0.0:{port}` (exposition publique directe) au lieu de `127.0.0.1:{port}`.

**Changelog v2.0 (conservé pour historique) :**
- Ajout de l'architecture de déploiement mono-serveur avec allocation de ports incrémentée
- Ajout d'une section Principes d'ingénierie et accélération du développement
- Renforcement de la section Sécurité (scan de dépendances, SAST, secrets manager, hardening containers, socket-proxy)
- Ajout d'une section Qualité du code généré par IA (anti-"empreinte IA")
- Renforcement de la section SEO (rendu, structured data, contenu unique, budget de performance)
- CI/CD avancé en Phase 1 au lieu de Phase 10

---

# PARTIE 1 — VISION ET CADRAGE

## 1. Vision du produit

Créer une plateforme SaaS permettant à un utilisateur de sélectionner une application Docker disponible dans le catalogue, choisir une offre de ressources, payer son abonnement et obtenir automatiquement une instance isolée et accessible depuis Internet.

L'utilisateur ne doit pas avoir besoin de connaître Docker, Linux, Nginx, SSL ou les commandes système.

Parcours principal :

```text
Visiteur → Catalogue → Page produit → Choix de l'offre → Création du compte
   → Paiement → Provisionnement automatique → Container Docker
   → Allocation de port → Sous-domaine → SSL → Instance prête
```

La plateforme doit ensuite permettre au client de gérer son instance depuis son dashboard.

## 2. Positionnement

Le produit ne doit pas être présenté comme un simple hébergeur Docker.

> **Deploy and manage powerful self-hosted applications without managing servers.**

L'utilisateur achète une instance managée d'une application (Activepieces Cloud, Hermes Cloud, etc.), mais l'architecture interne reste générique : une application est définie comme un **Application Template**.

## 3. Objectifs du MVP

- présenter les 7 applications ;
- créer un compte, choisir une application, choisir un plan, payer ;
- créer automatiquement une instance Docker sur le serveur unique et lui allouer un port ;
- attribuer un sous-domaine routé vers ce port ;
- configurer SSL automatiquement ;
- limiter CPU/RAM/stockage réellement (pas seulement dans l'UI) ;
- gérer sauvegardes, monitoring, redémarrage automatique, logs, mises à jour, quotas ;
- suspendre/supprimer une instance, renouveler un abonnement, gérer des snapshots ;
- exposer une API ;
- proposer FR/EN avec SEO optimisé dès la conception ;
- livrer une CI/CD avec contrôles de sécurité et de qualité dès la Phase 1.

## 4. Catalogue initial

| Application | Catégorie |
|---|---|
| Activepieces | Automation |
| Hermes | AI Agent |
| OpenClaw | AI Assistant |
| n8n | Workflow Automation |
| Paperclip | AI Agent Management |
| Dify | AI Application Platform |
| Flowise | AI Workflow Builder |

Une application peut appartenir à plusieurs catégories (Automation, AI Agents, AI Assistants, AI Applications, AI Workflow Builders).

---

# PARTIE 2 — PRINCIPES D'INGÉNIERIE (accélérer sans sacrifier la qualité)

## 5. Principes de développement

L'IA développeuse doit respecter :

- **DRY** — ne jamais dupliquer la logique métier ou Docker ;
- **SOLID** — architecture modulaire, interfaces avant implémentations ;
- **Repository / Service / Adapter** — séparer strictement Business logic, Infrastructure, Docker, Billing, logique spécifique à chaque application ;
- **API-first** — toute fonctionnalité principale doit être accessible via API avant d'être exposée en UI ;
- **Security-first** — toute donnée cliente est non fiable par défaut ;
- **Configuration-driven** — applications et plans configurables en base, jamais codés en dur dans le frontend ;
- **Extensible** — ajouter une 8ᵉ application ne doit pas nécessiter une refonte du système ;
- **Traçable** — toute décision d'architecture significative est documentée en ADR (voir §6).

## 6. Architecture Decision Records (ADR)

Créer un dossier `/docs/adr/NNNN-titre.md` (un fichier par décision : choix du reverse proxy, schéma de sous-domaine, stratégie de ports, choix du secrets manager, etc.).

Objectif : le projet étant développé par IA sur de nombreuses sessions, les ADR évitent que chaque nouvelle session contredise ou réinvente les choix précédents. Chaque ADR contient : contexte, décision, alternatives rejetées, conséquences.

## 7. Ne pas réinventer la roue — packages recommandés

| Besoin | Package |
|---|---|
| Billing / abonnements | Laravel Cashier (Stripe/Paddle) |
| RBAC | spatie/laravel-permission |
| Sauvegardes de la plateforme elle-même | spatie/laravel-backup |
| Audit logs | spatie/laravel-activitylog |
| Média (logos, screenshots) | spatie/laravel-medialibrary |
| Feature flags (draft/private/public/disabled) | Laravel Pennant |
| Supervision des queues de provisioning | Laravel Horizon |
| Debug en développement | Laravel Telescope |
| Frontend public indexable + SPA dashboard | Inertia.js (voir §29) |
| Erreurs runtime | Sentry |

## 8. CI/CD dès la Phase 1 (pas en fin de projet)

Le pipeline doit exister **avant** d'écrire la première fonctionnalité métier, pour que chaque commit ultérieur soit protégé :

```text
Git push
   ↓
Lint (Pint, ESLint/Prettier)
   ↓
Analyse statique (Larastan/PHPStan niveau max)
   ↓
Scan de secrets (gitleaks/truffleHog)
   ↓
Tests (Pest : unit, feature, API)
   ↓
Scan de dépendances (composer audit, npm audit, Dependabot)
   ↓
Build
   ↓
Scan d'image Docker (Trivy) si l'app touche des Dockerfiles/templates
   ↓
Deploy staging
   ↓
Tests E2E + Lighthouse CI (budget de performance)
   ↓
Deploy production (mono-serveur, voir Partie 3)
```

Chaque étape bloquante empêche le merge/déploiement en cas d'échec.

---

# PARTIE 3 — ARCHITECTURE DE DÉPLOIEMENT (MVP mono-serveur, accès direct IP:PORT)

## 9. Contrainte MVP : un seul serveur, sans reverse proxy

**Décision assumée pour cette itération :** pas de Traefik, pas de reverse proxy Apache/cPanel pour l'instant. Le site (Laravel + frontend) et tous les containers Docker des instances clientes tournent sur le même serveur cPanel/Ubuntu, et chaque instance est **directement accessible via `http://IP_DU_SERVEUR:{port}`**.

Conséquence directe : la ressource critique à gérer reste **« quel port allouer sans collision »** (§10, inchangé), mais chaque container est désormais exposé **publiquement** sur le port qui lui est alloué — il n'y a plus de couche intermédiaire pour filtrer, chiffrer ou masquer le trafic.

```text
                         INTERNET
                            │
                         Cloudflare (DNS uniquement pour jagentix.com —
                                      pas de proxy sur les IP:PORT des instances)
                            │
                ┌───────────┴────────────────────────────┐
                │                                         │
                ▼                                         ▼
       https://jagentix.com (Apache, port 443)   http://IP_SERVEUR:{port}
       (site principal, cPanel classique)         (accès direct à chaque instance,
                │                                  sans TLS, sans nom de domaine)
        ┌───────┴────────┐                                │
        │                │                     ┌──────────┼──────────┐
     PostgreSQL         Redis                   ▼          ▼          ▼
        │                │                Instance A  Instance B  Instance C
        └───────┬────────┘                :30000      :30001      :30002
                │                          (0.0.0.0:{port}, même serveur physique)
                ▼
        Queue / Workers
                │
                ▼
       Provisioning Service (via socket-proxy, jamais accès direct au socket Docker)
                │
                ▼
          Docker Engine local
```

Points clés (changement par rapport à v2.0) :
- Chaque container binde désormais sur **`0.0.0.0:{port}`** (exposition publique directe), et non plus `127.0.0.1:{port}` — il n'y a plus de proxy pour absorber le trafic entrant.
- Le firewall du serveur (ufw + CSF si actif sur ce cPanel) doit **ouvrir explicitement** la plage de ports allouée aux instances (§10.2) et **fermer tout le reste** — l'objectif du firewall change : il ne s'agit plus de bloquer la plage, mais de la borner strictement pour qu'aucun port hors plage ne soit jamais exposé par erreur.
- Vérifier explicitement l'interaction Docker/CSF (Docker manipule `iptables` directement et peut créer des règles qui contournent CSF) — un test d'exposition externe doit faire partie de la checklist de mise en production, pas une supposition.
- Le hardening des containers (utilisateur non-root, `--cap-drop=ALL`, seccomp, réseau Docker isolé par instance, limites de ressources — §14) devient **la seule ligne de défense** en l'absence de proxy, donc non négociable, pas optionnel.

## 15bis. Dette technique assumée et critère de bascule vers le reverse proxy

Cette architecture "IP:PORT direct" est un choix volontaire pour accélérer le lancement, pas un oubli. Elle doit être documentée comme telle et présentée honnêtement à l'utilisateur final :

**Limitations acceptées pour cette phase :**
- Pas de sous-domaine par instance (`https://slug.jagentix.com` n'existe pas encore) — l'utilisateur reçoit une URL du type `http://XX.XX.XX.XX:20047`.
- **Pas de HTTPS sur les instances.** Les identifiants et sessions des applications hébergées (Activepieces, Dify, n8n, etc., qui ont toutes une authentification) circulent en clair. Ce point doit être affiché clairement dans le dashboard et dans l'email "Instance prête" (ex. bandeau : « Accès en HTTP pendant la phase bêta — évitez d'y stocker des données sensibles pour l'instant »), pas passé sous silence.
- Pas de protection Cloudflare (WAF/anti-DDoS) sur le trafic direct vers les instances, puisque Cloudflare ne peut proxyfier que des noms de domaine, pas des IP:PORT bruts.
- URLs peu présentables commercialement (mauvais pour la confiance client et invendables telles quelles à grande échelle).

**Critère de déclenchement explicite pour la bascule vers le reverse proxy (§ discuté précédemment — Apache/cPanel + userdata includes + AutoSSL) :**
- avant tout **lancement public/commercial** (cette architecture ne doit jamais être celle vue par des clients payants en production) ;
- ou dès que le nombre d'instances actives simultanées devient difficile à suivre manuellement en `IP:PORT` ;
- ou dès qu'un client demande une garantie de confidentialité (HTTPS) pour son usage.

Tant que ce critère n'est pas atteint, l'architecture reste volontairement simple : pas de proxy, pas de certificats à gérer, un seul point de complexité (l'allocation de ports).

## 10. Allocation des ports incrémentée

### 10.1 Principe

À chaque nouvelle instance provisionnée, la plateforme alloue le **prochain port disponible** dans une plage réservée, de manière strictement séquentielle mais avec réutilisation contrôlée des ports libérés.

### 10.2 Plage réservée

```text
PORT_RANGE_MIN = 30000
PORT_RANGE_MAX = 31000   (≈ 1 000 instances simultanées possibles sur ce serveur)
```

**Remarque sur le dimensionnement :** cette plage est volontairement réduite par rapport à une plage large (ex. 20000-39999). ~1 000 instances simultanées est largement suffisant pour un MVP mono-serveur — la capacité réelle sera de toute façon plafonnée bien avant par le CPU/RAM du serveur (§17), pas par le nombre de ports. Le seuil d'alerte "occupation de la plage > 80 %" (§51) devient donc plus facilement atteignable avec cette plage plus étroite : il faut le surveiller activement plutôt que de le considérer comme un signal lointain, et il constitue un signal d'alerte à part entière avant même que les ressources CPU/RAM soient saturées, s'il fallait par exemple héberger un grand nombre de petites instances peu gourmandes en ressources.

Cette plage ne doit jamais chevaucher les ports systèmes utilisés par Postgres, Redis, SSH, le reverse proxy, l'API interne, etc.

### 10.3 Table `port_allocations`

```text
id
port                (unique, indexé)
instance_id         (nullable — null quand le port est libre)
status              (reserved | in_use | released)
allocated_at
released_at
```

### 10.4 Algorithme d'allocation (anti-collision)

L'allocation **doit** se faire dans une transaction avec verrou pessimiste, car plusieurs jobs de provisioning peuvent s'exécuter en parallèle sur la même queue :

```text
BEGIN TRANSACTION
  SELECT port FROM port_allocations
    WHERE status = 'released'
    ORDER BY released_at ASC
    LIMIT 1
    FOR UPDATE SKIP LOCKED

  SI trouvé :
    marquer ce port comme 'reserved' pour cette instance
  SINON :
    port = MAX(port) + 1 dans la plage (ou PORT_RANGE_MIN si table vide)
    vérifier port <= PORT_RANGE_MAX (sinon lever une alerte "pool de ports épuisé")
    insérer une nouvelle ligne 'reserved'
COMMIT
```

Règles impératives :
- **Ne jamais réutiliser un port immédiatement** après libération : imposer un délai de rétention (ex. 24h) avant de repasser un port `released` en disponible, pour laisser le temps aux caches DNS/proxy/monitoring externes d'expirer et éviter qu'un nouveau client hérite temporairement du trafic résiduel d'un ancien client.
- Le port passe à `in_use` seulement après confirmation que le container a démarré et répondu au health check (§22). En cas d'échec de provisioning, le port repasse immédiatement à `released` (pas `reserved` bloqué indéfiniment).
- Un job planifié (`ReconcilePortAllocationsJob`) doit périodiquement croiser la table `port_allocations` avec les containers Docker réellement actifs (`docker ps`) pour détecter et corriger toute dérive (port marqué `in_use` sans container, ou container actif sans entrée en base).

### 10.5 Pourquoi ne pas se contenter d'un simple compteur global incrémenté

Un compteur naïf (`last_port + 1`, sans jamais réutiliser) fonctionne mais gaspille irrémédiablement des ports au fil des suppressions d'instances, et finit par atteindre `PORT_RANGE_MAX` même avec peu d'instances simultanées réelles. La table avec réutilisation différée (§10.4) est recommandée dès le MVP — le coût d'implémentation est minime et évite une migration douloureuse plus tard.

## 11. Provisionnement automatique (flux mis à jour)

```text
Payment confirmed
       ↓
Create instance record (status: pending)
       ↓
Allocate port (voir §10.4)
       ↓
Allocate resources (CPU/RAM/storage selon le plan)
       ↓
Create volumes (nommés instance_{id}_data, etc.)
       ↓
Create container
   - bind 0.0.0.0:{port}:{container_port}   ← exposition publique directe (voir §9)
   - restart policy: unless-stopped
   - resource limits réellement appliqués (--cpus, --memory)
   - utilisateur non-root, capabilities réduites (voir §14 — seule ligne de défense en l'absence de proxy)
       ↓
Configure environment (secrets injectés depuis le secrets manager, jamais en clair)
       ↓
Health check (voir §22)
       ↓
Port status → in_use / Instance status → running (READY)
       ↓
URL communiquée au client : http://IP_SERVEUR:{port}   ← pas de sous-domaine, pas de SSL pour l'instant (§15bis)
```

Le provisioning reste **asynchrone** (Laravel Queue + Redis + Horizon) : ne jamais bloquer une requête HTTP pendant plusieurs minutes.

## 12. Statuts d'une instance

```text
pending · provisioning · starting · running · stopped · restarting ·
updating · backup · restoring · suspended · failed · deleting · deleted
```

## 13. Isolation

Chaque instance possède : son container, ses volumes, ses variables d'environnement, son réseau Docker dédié, ses limites CPU/RAM, ses logs, ses sauvegardes, son sous-domaine + port, son statut.

Les données d'un client ne doivent **jamais** être accessibles à un autre client — appliqué structurellement via des *global scopes* Eloquent liés au `tenant_id`/`instance_id` sur chaque requête, et non seulement testé a posteriori.

## 14. Sécurité Docker (renforcée)

Interdictions absolues :
- Ne jamais exposer `/var/run/docker.sock` à une application cliente, à un agent IA, ni même directement au processus Laravel.
- Toutes les opérations Docker passent par un **Provisioning Service** dédié, lui-même derrière un **socket-proxy** (ex. Tecnativa `docker-socket-proxy`) qui n'autorise que les endpoints strictement nécessaires (`CONTAINERS`, `NETWORKS`, `VOLUMES` en création/lecture/arrêt — jamais `EXEC`, jamais accès à l'API d'administration du démon).

```text
Laravel → Provisioning Queue → Provisioner → Docker Socket Proxy (endpoints whitelist) → Docker API
```

Durcissement de chaque container applicatif :
- utilisateur non-root dans l'image (`USER` explicite, jamais `root`) ;
- `--read-only` sur le rootfs quand l'application le permet, avec `tmpfs` pour les répertoires qui nécessitent l'écriture ;
- `--cap-drop=ALL` puis ajout minimal des capacités réellement nécessaires ;
- profil seccomp/AppArmor par défaut (ne pas désactiver) ;
- `--pids-limit` pour éviter le fork-bombing ;
- réseau Docker dédié par instance (`network_mode` isolé, pas de `--network host`) ;
- **importance renforcée pour cette phase** : sans reverse proxy, ce durcissement est la seule barrière entre un container compromis et le reste du serveur (y compris le site principal jagentix.com qui tourne sur la même machine). Aucun de ces points n'est optionnel tant que l'exposition est directe.

## 15. Sous-domaines et routage (différé — voir §15bis)

Pour cette itération, il n'y a **ni sous-domaine ni routage applicatif** : l'accès se fait directement en `http://IP_SERVEUR:{port}`. La génération de sous-domaine (`abc123.jagentix.com`) et le routage via reverse proxy Apache/cPanel (userdata includes + AutoSSL) sont conçus comme une **phase ultérieure activable par configuration**, pas comme un développement immédiat :

```text
config('provisioning.routing_mode') = 'direct_port'   ← valeur actuelle
config('provisioning.routing_mode') = 'reverse_proxy'  ← activable plus tard sans réécrire le Provisioner
```

Cette bascule par flag de configuration (plutôt qu'un choix figé dans le code) évite d'avoir à retoucher `ProvisionerInterface`/`ApplicationAdapterInterface` quand le reverse proxy sera implémenté — seule la fonction de résolution d'URL de l'instance change.

## 16. SSL (différé — voir §15bis)

Pas de HTTPS sur les instances clientes pour cette itération : l'accès `http://IP:PORT` est en clair. **Le HTTPS reste obligatoire pour `jagentix.com` lui-même** (site principal, déjà géré par cPanel/AutoSSL) — seule l'exposition des instances provisionnées est concernée par ce report. Voir §15bis pour la communication de cette limitation aux utilisateurs et le critère de bascule.

## 17. CPU / RAM / Stockage

Plans indicatifs (configurables en base, jamais codés en dur en frontend) :

| Plan | CPU | RAM | Storage |
|---|---|---|---|
| Starter | 1 vCPU | 1 GB | 10 GB |
| Professional | 2 vCPU | 4 GB | 30 GB |
| Business | 4 vCPU | 8 GB | 100 GB |

Ces limites doivent être **réellement appliquées par Docker** (`--cpus`, `--memory`), pas seulement affichées dans l'interface. Sur un serveur mono-instance, la somme des ressources allouées à tous les plans actifs ne doit jamais dépasser la capacité physique du serveur — un `ResourceSchedulerService` doit refuser un nouveau provisioning si le serveur est déjà saturé, plutôt que de créer une instance qui dégradera toutes les autres (y compris le site principal).

Suivi du stockage : `allocated_storage`, `used_storage`, `available_storage`, avec alerte configurable (80 %, 90 %, 95 %).

## 18. Volumes Docker

Données persistantes dans des volumes nommés dédiés (`instance_{id}_data`, `instance_{id}_config`, `instance_{id}_database`), qui survivent au redémarrage/remplacement du container.

## 19. Sauvegardes

Fréquences configurables par plan (Daily/Weekly/Monthly), rétention par plan (Starter : 7, Professional : 14, Business : 30). Identifiants horodatés (`backup_2026_09_13_0200`). Actions dashboard : créer, télécharger, restaurer, supprimer.

Backends multiples supportés (Local, S3, S3-compatible), configuration centralisée en administration, credentials jamais affichés au client. Les sauvegardes doivent être chiffrées au repos et en transit.

## 20. Monitoring, health checks, redémarrage automatique

Le dashboard affiche CPU, RAM, storage, network, statut du container, uptime.

Health check par application (HTTP/TCP/commande custom) :

```text
Healthy → Unhealthy → Retry → Restart → Notify
```

Docker restart policy `unless-stopped`, avec protection contre les boucles infinies de redémarrage (compteur + backoff + passage en `failed` après N tentatives).

## 21. Mises à jour

Le client voit `current version`, `latest version`, bouton `Update`.

```text
Create backup → Pull new image → Stop old container → Start new container
   → Health check → Mark successful (ou Restore previous version si échec)
```

## 22. Logs

Logs live consultables par le client, strictement limités à sa propre instance (filtrage par `instance_id`, jamais d'accès croisé). Fonctions : live, recherche, filtre, téléchargement, purge.

---

# PARTIE 4 — FACTURATION ET GESTION DES INSTANCES

## 23. Facturation

Une instance est associée à `subscription`, `plan`, `billing_cycle` (Monthly/Yearly), `price`, `status` (trial/active/past_due/cancelled/expired/suspended), `renewal_date`.

## 24. Plans et quotas

Plans administrables (Starter/Professional/Business/Enterprise), jamais codés en dur côté frontend. Quotas contrôlés **côté backend uniquement** : nombre max d'instances, CPU, RAM, storage, backups, requêtes API — toute opération dépassant un quota est refusée par le backend, pas seulement masquée dans l'UI.

## 25. Cycle de vie de l'abonnement

```text
ACTIVE → GRACE PERIOD → SUSPENDED → DELETED
```

Notifications avant expiration (J-7, J-3, J-1). Durée du grace period configurable. Ne jamais supprimer immédiatement les données après expiration. Renouvellement automatisable si le provider de paiement le permet.

## 26. Suspension / Suppression

Suspension par l'administrateur (impayé, abus, violation des CGU, maintenance) sans suppression immédiate.

Suppression définitive sur demande du client, avec confirmation explicite et sauvegarde finale optionnelle :

```text
Delete requested → Confirmation → Backup final optionnel → Stop container
   → Delete container → Delete network → Delete volumes
   → Release port (status → released, voir §10.4) → Delete domain config → Deleted
```

## 27. Snapshots

Capture complète : configuration de l'instance, version de l'application, configuration d'environnement, données persistantes, métadonnées. Secrets stockés de manière sécurisée (jamais en clair dans le snapshot).

## 28. API publique

API REST versionnée `/api/v1`, authentification par clés API (hashées en base, révocables, limitées, auditées) ou Bearer tokens.

```http
GET    /api/v1/applications
GET    /api/v1/applications/{slug}
GET    /api/v1/plans
GET    /api/v1/instances
POST   /api/v1/instances
GET    /api/v1/instances/{id}
PATCH  /api/v1/instances/{id}
DELETE /api/v1/instances/{id}
POST   /api/v1/instances/{id}/start|stop|restart|backup|update
GET    /api/v1/instances/{id}/backups|logs|metrics
GET    /api/v1/usage
```

## 29. Dashboards

**Client** — page « My Instances » (application, sous-domaine, statut, plan, ressources, actions) + page détaillée par instance (Overview, Metrics, Logs, Backups, Snapshots, Updates, Settings, Billing, API).

**Administrateur** — Utilisateurs/Rôles, Applications/Versions, Instances (toutes/running/stopped/failed/suspended), **Infrastructure** (état du serveur unique : CPU/RAM/storage globaux, occupation de la plage de ports, table `port_allocations`), Billing, Monitoring/Alertes.

---

# PARTIE 5 — FRONTEND, i18n ET SEO

## 30. Rendu frontend : Inertia plutôt qu'une SPA Vue pure

**Recommandation d'architecture (nouveau) :** utiliser **Inertia.js** (Laravel + Vue, rendu côté serveur natif, sans API séparée) pour toutes les pages publiques (accueil, catalogue, pages produit, pricing, blog, documentation). Réserver une SPA Vue classique uniquement pour le dashboard authentifié, qui n'a pas besoin d'être indexé.

Raison : une SPA Vue pure, même avec des balises meta dynamiques, reste mal indexée par défaut par les moteurs de recherche. Inertia résout ce problème sans dupliquer la logique front (pas de build Nuxt séparé à maintenir) tout en gardant une expérience SPA fluide.

## 31. Internationalisation

Multilingue dès le début (FR/EN), architecture prête pour ES/PT/DE. Contenu traduit : interface, emails, notifications, messages d'erreur, pages marketing, catalogue, pages produits, FAQ, documentation. Jamais de texte codé en dur dans les composants Vue — système i18n obligatoire.

Détection de langue au premier accès (langue du navigateur → FR/EN), changement manuel possible, préférence sauvegardée.

URLs localisées (`/fr/apps/activepieces`, `/en/apps/activepieces`), avec `hreflang`, `canonical`, `alternate`, sitemap et robots.txt correctement configurés (y compris `x-default`).

## 32. SEO — pages publiques

Pages principales optimisées : Home, Applications, Application details, Pricing, Features, About, Contact, FAQ, Documentation, Blog, Login, Register. Les pages authentifiées ne doivent jamais être indexées (`noindex` + exclues du sitemap).

Chaque page produit doit posséder : SEO title, meta description, H1/H2, structured data, canonical, Open Graph, Twitter/X metadata, FAQ schema le cas échéant.

**Contenu unique obligatoire (nouveau) :** avec 7 pages produit très similaires dans leur structure, le contenu textuel de chaque page doit être substantiellement différent (cas d'usage réels, comparatifs, captures spécifiques) pour éviter que Google les traite comme du contenu dupliqué/thin content.

## 33. SEO technique renforcé

Au-delà de Core Web Vitals, performance, mobile-first, lazy loading, compression, image optimization (WebP/AVIF), semantic HTML, sitemap XML, robots.txt :

- **Structured data typé** : `SoftwareApplication` ou `Product` avec `offers` (prix des plans) sur chaque page produit, `Organization` sur le site, `BreadcrumbList` pour la navigation.
- **Budget de performance en CI** : Lighthouse CI intégré au pipeline dès la Phase 2, avec seuils bloquants sur les Core Web Vitals — pas une vérification manuelle occasionnelle.
- **Google Search Console + Bing Webmaster Tools** configurés dès le MVP, avec soumission automatique du sitemap à chaque déploiement.
- `sitemap.xml` généré automatiquement avec les pages publiques et produits à chaque déploiement.

## 34. Structure d'une page produit

```text
Hero (logo, nom, description, prix de départ, CTA "Deploy now")
Features
How it works
Available plans
Specifications
Screenshots
Use cases
FAQ
Related applications
CTA final
```

## 35. Recherche et catégories

Recherche interne dans le catalogue avec filtres (catégorie, prix, ressources, cas d'usage). Une application peut appartenir à plusieurs catégories.

## 36. Pages clés

**Accueil** — Hero, avantages (déploiement en un clic, SSL auto, sauvegardes auto, monitoring, mises à jour auto, isolation sécurisée), catalogue des 7 apps, « comment ça marche », pricing, FAQ SEO.

**Pricing** — comparatif des plans (ressources, backups, monitoring, API, support, nombre d'instances), CTA par plan.

**Page application** — nom, logo, description, features, ressources min/recommandées, plans disponibles, version, documentation, FAQ, bouton Deploy.

---

## 36bis. Identité visuelle et anti-AI design (obligatoire pour tout le frontend public et le dashboard)

Complément au §44 (qui couvre la qualité du **code** généré par IA) : cette section couvre la qualité du **design visuel** généré par IA. Le principe est le même — les garde-fous doivent être mécaniques (checklist d'audit, décisions documentées), pas de simples intentions déclaratives.

**Interdiction de principe :** l'interface ne doit pas ressembler visuellement à un SaaS générique produit par un modèle IA qui retombe sur ses valeurs par défaut ("vibe-coded" / "template AI"). L'objectif n'est pas d'éviter le développement assisté par IA, mais d'éviter les patterns visuels génériques qu'un modèle produit par défaut.

### 36bis.1 Système de design à définir *avant* toute page

Avant d'implémenter la moindre page, documenter explicitement (dans un fichier `/docs/design-system.md`, lié en ADR — voir §6) :

```text
Système de couleurs · Système typographique · Échelle d'espacement
Échelle de border-radius · Système d'élévation/ombres · Langage des composants
Iconographie · Principes de mise en page · Principes d'interaction
Direction image/illustration
```

L'IA ne doit jamais inventer ces décisions indépendamment des valeurs par défaut génériques du web — elles doivent découler du positionnement produit de jagentix.com (§2), pas d'un choix arbitraire.

### 36bis.2 Patterns visuels par défaut interdits

Ne jamais utiliser comme langage visuel par défaut :
- dégradés violet→indigo, violet→bleu, violet→rose, combinaisons néon violet/cyan ;
- larges "blobs" lumineux, glow de fond excessif ;
- texte en dégradé (surtout violet/bleu) ;
- glassmorphism comme langage visuel principal, backdrop-blur excessif, cartes "verre" transparentes en masse ;
- interfaces sombres à accents néon violet+cyan ;
- sphères 3D décoratives, réseaux de neurones, particules flottantes ou illustrations IA abstraites sans lien avec le produit.

Le violet ne doit jamais être choisi automatiquement comme couleur "IA / moderne / premium / innovant" par défaut.

### 36bis.3 Typographie

Ne pas se limiter par défaut à Inter/Roboto/Open Sans/Arial ou aux polices système comme identité visuelle complète. Le choix doit être motivé par : catégorie de produit, audience cible, personnalité de marque, densité de contenu, accessibilité, hiérarchie visuelle. Éviter l'usage excessif de graisses 800/900, des titres centrés surdimensionnés systématiques, et une hiérarchie typographique identique sur toutes les pages.

### 36bis.4 Hero, cartes, layout

- **Hero** : ne pas reproduire le pattern standard (hero centré, badge "pill", titre énorme, sous-titre générique, deux CTA centrés, fond dégradé violet, blobs lumineux, mockup de dashboard flottant). La composition doit être pensée spécifiquement pour jagentix.com (mettre en avant le catalogue d'apps réel, un flux de déploiement concret, etc.).
- **Cartes** : ne pas forcer systématiquement trois cartes identiques (icône → titre → description deux lignes → coin arrondi → ombre légère). La structure doit suivre la hiérarchie réelle de l'information (les 7 apps du catalogue n'ont pas nécessairement besoin d'être présentées de façon strictement identique — voir aussi §32 sur le contenu unique par page produit, pour les mêmes raisons SEO et anti-duplication).
- **Layout** : éviter les grilles 3/4 colonnes systématiques, les sections parfaitement symétriques, les dimensions de cartes identiques, l'alternance prévisible de sections. Utiliser des compositions asymétriques/éditoriales quand c'est pertinent.
- **Border-radius** : suivre une hiérarchie (inputs : petit rayon, boutons : petit/moyen, cartes : moyen, modales : moyen, avatars : circulaire) plutôt que d'appliquer `rounded-2xl`/`rounded-3xl`/`rounded-full` partout indistinctement.

### 36bis.5 Badges, icônes, animation, copywriting

- **Badges/pills** : jamais comme remplissage décoratif ("AI Powered", "Next Generation", "New", "Beta", "Powerful", "Smarter", "Future of work"...) — un badge doit porter une information réelle (ex. statut réel d'une app : `private`/`public`, version disponible).
- **Icônes** : éviter la structure répétée icône → carré coloré → titre → description pour chaque feature ; adapter la présentation par défaut des librairies d'icônes au design system du produit plutôt que de les utiliser telles quelles.
- **Animation** : ne pas animer chaque composant avec les mêmes fade-up/fade-in/scale/slide-up/hover-scale/floating. Une animation doit servir un objectif fonctionnel (retour d'état, navigation, continuité spatiale, focus, révélation progressive) — pertinent en particulier pour l'écran de provisioning (§49), où l'animation doit refléter l'avancement réel, pas de la décoration.
- **Copywriting** : bannir "Transform your workflow", "Unlock your potential", "Supercharge your productivity", "The future of...", "Next-generation platform", "Powerful AI", "AI-powered", "Seamless", "Effortless", "Revolutionize your workflow", etc., sauf si le mot est réellement pertinent pour le produit. Le texte doit décrire des capacités, bénéfices et workflows réels (ex. décrire concrètement ce que fait Activepieces plutôt qu'un slogan générique).

### 36bis.6 Dashboard et framework

- Les visualisations du dashboard client (§29) doivent représenter la fonctionnalité réelle du produit (métriques CPU/RAM/storage/statut réellement branchées — §20) — jamais de KPI cards génériques, graphiques factices, faux avatars/notifications/activity feed ajoutés uniquement pour "faire sophistiqué".
- Tailwind/shadcn/Radix/Laravel UI/librairies d'icônes sont autorisés pour l'implémentation, mais **le framework ne doit jamais rester visible comme identité visuelle** — chaque composant doit être personnalisé selon les tokens de design propres à jagentix.com (§36bis.1).

### 36bis.7 Test de spécificité produit

Chaque décision visuelle majeure doit répondre à au moins une question :
1. Pourquoi cela aide-t-il *ce* produit en particulier ?
2. Pourquoi cela aide-t-il *cet* utilisateur en particulier ?
3. Est-ce que ça communique une fonctionnalité réelle du produit ?
4. Est-ce que ça renforce l'identité de marque de jagentix.com ?
5. Est-ce que ça améliore l'utilisabilité ou la compréhension ?

Si un élément visuel n'existe que parce qu'il "fait moderne", le supprimer.

### 36bis.8 Audit anti-AI design (checklist obligatoire avant de valider une page)

Avant de considérer une page terminée, vérifier qu'elle n'accumule pas plusieurs des patterns suivants simultanément (un seul pattern isolé n'indique pas nécessairement un design généré par IA — c'est l'accumulation qui est le signal à éviter) :

```text
□ Dégradé violet/indigo               □ Glow violet
□ Typographie Inter uniquement        □ Blobs décoratifs
□ Hero centré                         □ Pills excessifs
□ Deux CTA génériques centrés         □ Copywriting IA générique
□ Trois cartes de fonctionnalités     □ Mockup de dashboard générique
   identiques                         □ Cartes d'icônes répétitives (style Lucide)
□ Grandes cartes très arrondies       □ Animations excessives
□ Glassmorphism                       □ Structures de section identiques
□ Footer SaaS générique               □ Boutons en dégradé
                                       □ Texte en dégradé
```

Cette checklist doit être intégrée à la revue de PR pour tout composant frontend (en complément des contrôles automatisés de §42) — elle est à documenter comme étape de la CI/CD "design review" au même titre que le lint/analyse statique, même si elle reste une vérification humaine (pas automatisable comme un scan de sécurité).

**Principe directeur :** ne pas se demander *« comment rendre ce site moderne ? »*, mais *« comment créer un langage visuel spécifique à jagentix.com, à ses utilisateurs, à son domaine et à sa marque ? »*. L'interface finale doit ressembler à un design de produit délibéré, pas à la moyenne statistique des sites SaaS actuels.

---

# PARTIE 6 — PAIEMENT, NOTIFICATIONS, AUDIT

## 37. Paiement

Système de paiement abstrait via `PaymentProviderInterface`, pour intégrer Stripe, PayPal, Mobile Money et d'autres providers sans coupler fortement le système à un seul fournisseur.

## 38. Webhooks de paiement

Un `redirect success` ne constitue **jamais** une preuve de paiement suffisante. Flux obligatoire :

```text
Payment provider → Webhook → Verify signature → Idempotency check
   → Payment confirmed → Subscription activated → Provision instance
```

La vérification de signature et la clé d'idempotence évitent le double-provisioning en cas de retry du webhook.

## 39. Notifications et emails

Notifications (email, dashboard, webhook) pour : instance créée/prête/échouée, backup terminé/échoué, mise à jour disponible/terminée/échouée, abonnement expirant, paiement réussi/échoué, instance suspendue.

Templates d'emails multilingues : bienvenue, vérification email, réinitialisation mot de passe, confirmation de paiement, instance prête, backup terminé, abonnement expirant, paiement échoué, instance suspendue.

## 40. Audit logs

Toutes les actions importantes enregistrées : utilisateur, action, instance, IP, timestamp, résultat. Actions couvertes : création, suppression, redémarrage, arrêt, mise à jour, backup, restauration, snapshot, création de clé API, changement d'abonnement.

---

# PARTIE 7 — SÉCURITÉ RENFORCÉE

## 41. Sécurité applicative

Le système doit implémenter au minimum :

- HTTPS obligatoire, hashage sécurisé des mots de passe, 2FA optionnel puis extensible ;
- rate limiting **par tenant/clé API** (pas seulement global — sinon un client compromis peut consommer tout le quota de la plateforme) ;
- CSRF protection, validation serveur systématique (Form Requests Laravel, jamais de validation ad-hoc dans le contrôleur) ;
- authorization policies, RBAC, audit logs ;
- chiffrement des secrets, rotation des credentials ;
- isolation des containers, resource limits réellement appliqués, network isolation ;
- protection contre les container escapes (voir §14) ;
- backups sécurisés (chiffrés).

## 42. Contrôles automatisés (nouveau — au-delà des principes déclaratifs)

- **Scan de dépendances** : `composer audit`, `npm audit`, Dependabot/Renovate en CI, à chaque PR — pas une checklist manuelle ponctuelle.
- **Analyse statique stricte** : Larastan/PHPStan niveau maximum, bloquant en CI.
- **Scan d'images Docker** : Trivy (ou Grype) sur chaque image du catalogue avant publication en statut `public` — une CVE critique bloque la mise en catalogue.
- **Isolation multi-tenant structurelle** : global scopes Eloquent liés au tenant sur chaque requête, pour éliminer les IDOR par construction plutôt que de les découvrir en tests.
- **Pentest externe avant lancement public**, en plus des tests de sécurité internes (§46).

## 43. Secrets et gestion des credentials

Variables sensibles concernées : clés API, mots de passe de base de données, secrets OAuth, clés de chiffrement, credentials des providers. Elles ne doivent jamais apparaître en clair dans les logs, le frontend, ou les réponses API.

**Recommandation renforcée :** utiliser un vrai secrets manager (HashiCorp Vault, ou le service Secrets Manager du cloud utilisé) dès le MVP plutôt qu'un simple chiffrement `.env`, avec rotation automatisée. Aucune credential de production ne doit jamais être présente dans Git.

---

# PARTIE 8 — QUALITÉ DU CODE GÉNÉRÉ PAR IA

## 44. Éviter les « empreintes IA » dans le code produit

Voir aussi §36bis pour le pendant visuel/design de cette exigence (l'interface ne doit pas non plus ressembler à un design générique produit par défaut par un modèle IA).

Le projet étant intégralement développé par IA, des garde-fous mécaniques (pas seulement des consignes) sont nécessaires pour éviter les patterns caractéristiques du code généré sans supervision :

- **Style de code imposé mécaniquement** : Laravel Pint + ESLint/Prettier en pre-commit hook et bloquants en CI. Sans cela, chaque session IA introduit un style légèrement différent (nommage, structure), rendant le code hétérogène et trahissant une génération multi-session incohérente.
- **Zéro tolérance sur les anti-patterns classiques de génération IA non supervisée** :
  - `try/catch` qui avale silencieusement les exceptions ;
  - validation manquante ou ad-hoc (imposer systématiquement les Form Requests) ;
  - `$fillable`/`$guarded` mal configurés (risque de mass assignment) ;
  - secrets ou clés de test codées en dur oubliées dans le code (scan gitleaks/truffleHog en CI) ;
  - commentaires `TODO`/`FIXME` qui traînent, code mort non supprimé.
- **Couverture de tests réelle sur la logique critique** (provisioning, allocation de ports, billing, isolation tenant) — l'IA a tendance à générer du code qui fonctionne sur le chemin heureux mais néglige les cas limites et la concurrence (ex. deux jobs d'allocation de port simultanés).
- **Spec unique comme source de vérité** : schéma OpenAPI unique pour l'API, dont la validation et la documentation sont générées, plutôt que de laisser chaque module IA redéfinir sa propre structure.
- **Revue humaine obligatoire sur le code sensible** (provisioning, allocation de ports, billing, isolation tenant, auth) avant merge, même s'il a été généré par IA et a passé les contrôles automatisés.
- Les **ADR** (§6) et le respect strict des interfaces définies en §54-56 (Provisioner, Adapter) sont la meilleure protection contre la dérive architecturale au fil des sessions.

---

# PARTIE 9 — MODÈLE DE DONNÉES ET ARCHITECTURE LOGICIELLE

## 45. Entités principales

```text
users, roles, permissions
applications, application_versions, application_categories
plans, plan_features
instances, instance_resources, instance_domains, instance_volumes
port_allocations                         ← nouveau (voir §10.3)
subscriptions, payments, invoices
backups, snapshots
usage_records, quota_records
api_keys
notifications, notification_templates
audit_logs
translations
```

## 46. Relations principales

```text
User → subscriptions, instances, payments, api_keys, notifications
Application → versions, categories, instances
Instance → User, Application, Plan, PortAllocation, Domain, Volumes, Backups, Snapshots, Usage
```

## 47. Couches d'abstraction (Provisioner / Adapter)

```text
ProvisionerInterface
  createInstance() · startInstance() · stopInstance() · restartInstance()
  deleteInstance() · updateInstance() · getLogs() · getMetrics()
  createBackup() · restoreBackup() · createSnapshot() · restoreSnapshot()
```

`DockerProvisioner` implémente `ProvisionerInterface` pour le MVP mono-serveur. Le reste de Laravel ne dépend jamais directement des commandes Docker. Plus tard, un `KubernetesProvisioner` ou un provisioner multi-node pourra être ajouté sans réécrire l'application (voir §38).

```text
ApplicationAdapterInterface
  install() · configure() · healthCheck() · backup() · restore() · update()
```

Une classe par application (`ActivepiecesAdapter`, `HermesAdapter`, etc.) — objectif explicite : **éviter** `if ($app === 'n8n') ...` dispersé dans le code. Ajouter une application = créer un template + un adapter, jamais modifier le cœur du système.

## 48. Queue, idempotence, gestion des erreurs

Jobs pour toute opération longue : `ProvisionInstanceJob`, `AllocatePortJob`, `DeleteInstanceJob`, `UpdateInstanceJob`, `BackupInstanceJob`, `RestoreInstanceJob`, `CreateSnapshotJob`, `RestoreSnapshotJob`, `MonitorInstanceJob`, `RenewSubscriptionJob`, `SuspendExpiredInstancesJob`, `ReconcilePortAllocationsJob`.

Chaque job critique doit être **idempotent** (clé `instance_id` / `operation_id` / `idempotency_key`) — un `ProvisionInstanceJob` exécuté deux fois ne doit jamais créer deux instances ni allouer deux ports.

Chaque opération trace `status`, `error_code`, `error_message`, `retry_count`, `started_at`, `finished_at`, visible dans le dashboard admin. Retry automatique avec backoff pour les erreurs temporaires ; passage définitif en `failed` après épuisement des tentatives.

---

# PARTIE 10 — UX, TESTS, OBSERVABILITÉ, ÉVOLUTION

## 49. UX du provisioning

```text
Creating your instance...
✓ Payment confirmed
✓ Resources allocated
✓ Port allocated
✓ Docker container created
● Starting application
○ Health check
```

Puis : `Your instance is ready! → http://IP_SERVEUR:{port}` avec un bandeau visible : *« Accès en HTTP pendant la phase bêta — le HTTPS et les sous-domaines arrivent dans une prochaine mise à jour »* (voir §15bis). Ne jamais afficher une icône de cadenas/HTTPS tant que ce n'est pas réellement le cas.

Responsive design (priorité desktop puis mobile).

## 50. Trial et domaine personnalisé

Trial de 7 jours activable/désactivable depuis l'administration. Le MVP utilise uniquement les sous-domaines de la plateforme ; l'architecture doit permettre plus tard un `Connect custom domain`.

## 51. Observabilité de la plateforme

Surveiller Laravel, Redis, PostgreSQL, le Provisioner, le serveur Docker unique, les workers de queue, les webhooks de paiement.

Alertes administrateur : CPU serveur > 90 %, RAM serveur > 90 %, disque > 85 %, **plage de ports occupée à plus de 80 %** (nouveau — signal à anticiper avant migration multi-node), échec de provisioning, échec de backup, échec de webhook, backlog de queue, démon Docker indisponible.

## 52. Stack technique

**Backend :** Laravel, PHP, PostgreSQL, Redis, Laravel Queue + Horizon.
**Frontend :** Vue.js + Inertia.js (pages publiques indexables) + Vite + i18n ; SPA Vue classique pour le dashboard authentifié.
**Infrastructure (MVP) :** Docker (mono-serveur), Docker Socket Proxy, Traefik, Cloudflare, stockage S3-compatible pour les backups.
**Monitoring :** Prometheus/Grafana ou équivalent, Sentry pour les erreurs applicatives.

## 53. Environnements

Development, Staging, Production. Aucune credential de production dans Git (secrets manager, voir §43).

## 54. Tests

**Backend :** unit, feature, API, autorisation, billing, provisioning, **allocation de ports (concurrence)**.
**Frontend :** tests de composants, E2E.
**Infrastructure :** création/redémarrage de container, backup, restore, update, rollback, SSL, domaine, quota.

## 55. Tests de sécurité

Isolation tenant, IDOR, accès non autorisé aux containers, fuite de clé API, fuite de secrets, élévation de privilèges, rate limiting, spoofing de webhook, **tentative d'accès direct à un port d'instance en contournant le reverse proxy** (nouveau — vérifier que le firewall borne bien l'exposition publique à la plage 30000-31000, sans port ouvert hors de cette plage).

## 56. Critères d'acceptation du MVP

Le MVP est fonctionnel lorsque : un utilisateur peut créer un compte → choisir une application → choisir un plan → payer → obtenir une instance sans intervention manuelle ; l'instance est automatiquement accessible via `http://IP_SERVEUR:{port}` (sous-domaine et HTTPS explicitement hors périmètre de cette itération, voir §15bis) ; les limites CPU/RAM sont réellement appliquées ; le quota de stockage est contrôlé ; une sauvegarde peut être créée et restaurée ; CPU/RAM/storage/statut sont visibles ; l'instance peut être redémarrée, mise à jour, supprimée depuis le dashboard ; les logs sont consultables ; abonnement et date de renouvellement sont visibles ; les quotas bloquent les opérations en dépassement ; un snapshot peut être créé et restauré ; les opérations principales sont disponibles via API ; le site fonctionne en FR/EN avec SEO complet (title, meta, canonical, Open Graph, sitemap, hreflang, structured data) ; **le pool de ports fonctionne sans collision sous charge concurrente**.

## 57. Priorité de développement (phases)

```text
Phase 1 — Foundation + CI/CD + sécurité de base
  Laravel, PostgreSQL, Redis, Vue/Inertia, Authentication, RBAC, i18n,
  pipeline CI/CD complet (§8), secrets manager, ADR

Phase 2 — Catalogue
  Applications, Categories, Application templates, Plans, Pricing,
  Product pages, SEO (§30-36), Lighthouse CI

Phase 3 — Docker Engine mono-serveur, accès direct IP:PORT
  Docker Socket Proxy, Provisioner, Application adapters,
  Container lifecycle, Volumes, Networks, Resource limits,
  Allocation de ports (§10), firewall borné à la plage de ports,
  exposition 0.0.0.0:{port} (voir §9 et §15bis — dette technique assumée)

Phase 4 — Domaine & Reverse Proxy (différée — critère de déclenchement en §15bis)
  Reverse proxy Apache/cPanel (userdata includes), sous-domaines, AutoSSL
  → à réaliser avant tout lancement public, pas en Phase 3

Phase 5 — Instance management
  Dashboard, Logs, Metrics, Restart, Stop, Start, Delete

Phase 6 — Backup
  Backups, Snapshots, Restore, S3

Phase 7 — Updates
  Version management, Update, Health check, Rollback

Phase 8 — Billing
  Plans, Subscriptions, Payments, Invoices, Renewals, Suspension, Quotas

Phase 9 — API
  API keys, REST API, Rate limits, Usage, Webhooks

Phase 10 — Production hardening
  Scan de dépendances/images en continu, Pentest, Monitoring, Alertes,
  Audit logs, Load testing, Backup testing, Disaster recovery

Phase 11 — Évolution multi-node (voir §38)
```

## 58. Ordre d'intégration des 7 applications

```text
1. Activepieces  2. Hermes  3. OpenClaw  4. Paperclip
5. Flowise       6. Dify    7. n8n
```

La disponibilité commerciale de chaque application doit être validée juridiquement avant sa commercialisation. Feature flag par application : `draft`, `private`, `public`, `disabled` — permet de terminer l'intégration technique avant validation commerciale sans modifier le code.

## 59. Évolution vers le multi-node

Le mono-serveur avec allocation de ports (Partie 3) est une contrainte de démarrage, pas une limite d'architecture. Grâce aux abstractions `ProvisionerInterface` et `ApplicationAdapterInterface` (§47), la migration future se fait par ajout d'un nouveau provisioner, sans réécrire la couche métier :

```text
Node 1 (serveur actuel)          Node 2 (nouveau)          Node N
├── Instance A (port 20001)      ├── Instance D            ├── ...
├── Instance B (port 20002)      ├── Instance E
└── Instance C (port 20003)      └── Instance F
```

Un `SchedulerService` choisira alors le node selon CPU/RAM/storage disponibles et les exigences de l'application — le mécanisme d'allocation de ports (§10) reste valable *par node*, avec une plage dédiée par serveur pour éviter toute collision inter-node.

## 60. Résultat attendu et définition finale du produit

Le client sélectionne une application, un plan, paie, et obtient `https://xxxx.jagentix.com` prêt à l'emploi, sans jamais effectuer une opération Docker. Il gère son application depuis un dashboard (Overview, Metrics, Logs, Backups, Snapshots, Updates, API, Billing, Settings).

Le produit est conçu comme un **SaaS Control Plane for Managed Docker Applications**, et non comme sept SaaS indépendants. Le cœur de la plateforme : Users + Applications + Plans + Billing + Provisioning + Ports + Docker + Domains + SSL + Resources + Backups + Monitoring + Updates + API. Les 7 applications initiales sont les premiers **Application Templates** — cette architecture doit permettre d'en ajouter d'autres sans modifier les composants fondamentaux du SaaS, et de migrer vers un déploiement multi-node sans réécriture majeure.
