Wiki/docs/03-decision-record.md
Corentin JOGUET 668576cdc4 chore: initial commit — formation-hub conception phase
Conception complete (Phase 0) pour formation-hub Acadenice :

- 19 docs Merise Agile + UML + GitOps + plans (tests/deploy/ops/api)
  cf docs/00-readme.md pour l'index complet
- Stack Docker compose (Docmost + Baserow + Postgres + Redis + MinIO local FS)
  compose.yml + compose.staging.yml + compose.prod.yml
- CI/CD GitHub Actions skeleton (ci, deploy-staging, deploy-prod)
- Bridge service skeleton (Hono + TS + Biome + Vitest + zod + pino)
- Templates GitHub : PR + 3 issue types + CODEOWNERS + dependabot.yml
- Scripts ops : healthcheck, backup quotidien, smoke-test post-deploy
- LICENSE AGPL-3.0 + SECURITY.md + CONTRIBUTING.md + CHANGELOG.md
- Diagramme drawIO archi infra (XML importable dans diagrams.net)

Decisions structurelles enregistrees :
- Scope CFA + Agence avec entite PERSONNE pivot multi-roles (ADR-001)
- Stack composite Docmost AGPL + Baserow MIT + bridge custom (ADR-001)
- Path B : UX quasi-unified via Tiptap node-views custom (ADR-002)
- Monorepo trunk-based development (ADR-003)
- Postgres separe Docmost/Baserow (ADR-004)
- Bridge stack Node 22 + Hono (ADR-005)
- Repo neuf prefere a fork Docmost
- Prod-like des le jour 1 (pas MVP)
2026-05-07 12:16:19 +02:00

141 lines
4.9 KiB
Markdown

# ADR — Architecture Decision Records
Format Architecture Decision Record. Une entree par decision structurelle.
---
## ADR-001 — Stack composite : Docmost (wiki) + Baserow (DBs)
**Statut** : Accepte le 2026-05-07
**Decideurs** : Le user (AdminSys/DevOps) + BYAN (consulting)
### Contexte
Aucun projet OSS unique ne couvre :
- Users illimites self-host (out : AFFiNE 10-seat, AppFlowy 1-user)
- Bidirec + DBs multi-vues + team workspaces simultanement
- Budget recurrent zero (out : AFFiNE Team License)
### Decision
Combiner deux outils OSS matures :
- **Docmost** pour le wiki collaboratif (AGPL, users illimites, team workspaces, share links natifs)
- **Baserow** pour les DBs structurees (MIT core, users illimites, vues multiples, rollups, relations)
Et construire un **bridge service** custom Node TS pour unifier l'UX de surface (l'UI Baserow reste cachee cote utilisateur final).
### Alternatives ecartees
1. **AFFiNE Team License paid** : ~2200€/an recurrent, lock-in vendor.
2. **Custom DB engine sur Docmost** : 4-6 mois dev (~30-60k€), reinvention de la roue.
3. **Notion (cloud)** : pas self-host.
4. **Outline + add bidirec custom** : license BSL bloque usage commercial.
5. **AppFlowy paid** : disqualifie pour stack Flutter (recrutement difficile, pas web-first).
### Consequences
**Positives**
- Zero recurrent licensing cost (juste l'infra ~30€/mois VPS)
- Stack mainstream TS/NestJS/React/Tiptap pour Docmost et Python/Django pour Baserow
- Decouplage permet de remplacer Docmost ou Baserow sans tout refaire
- Baserow couvre les besoins DBs du cas (multi-vues, relations, rollups, formules) parmi les Airtable-likes OSS evalues
**Negatives**
- Deux services a maintenir au lieu d'un
- Bridge service = code custom a ecrire et maintenir
- Performance : appels HTTP entre Docmost et Baserow (mitige par cache Redis)
- Risque scope creep sur le bridge (tentation de reproduire 100% de Notion)
**A surveiller**
- Si Docmost ajoute des DBs natives (pas dans roadmap actuelle), reevaluer la valeur de Baserow
- Si AFFiNE OSS leve sa limite 10-seat, reevaluer le path A
---
## ADR-002 — Path B (UX quasi-unified) plutot que Path A (deux mondes)
**Statut** : Accepte le 2026-05-07
### Contexte
Path A (cross-link URL externe entre Docmost et Baserow) demande **2-4 semaines** mais expose l'UI Baserow aux utilisateurs (jonglage entre deux applis).
Path B (Tiptap nodes custom + API Baserow) demande **2-3 mois pour un fullstack senior, 4-6 mois pour AdminSys/DevOps solo** mais offre une UX unifiee.
### Decision
**Path B** retenu. Le user accepte la courbe d'apprentissage Tiptap/React et la timeline plus longue contre une UX qui ne disrupt pas l'experience metier.
### Consequences
- Phase 1 (Mois 1) : stack vanilla utilisable telle quelle, l'equipe peut commencer a alimenter le wiki et les DBs sans bridge
- Phase 2 (Mois 2-6) : iteration progressive sur les nodes Tiptap custom selon la douleur reelle des utilisateurs
- Risque : tentation d'aller direct au "tout brillant" sans valider l'usage. Garde-fou : Phase 1 obligatoire avant tout code custom.
---
## ADR-003 — Monorepo Git
**Statut** : Accepte le 2026-05-07
### Decision
Monorepo unique `formation-hub/` versionne ensemble :
- Compose files (`compose.yml`, overrides staging/prod)
- Bridge service (`bridge/`)
- Schemas Baserow (`baserow/schemas/`)
- Patches Docmost (`docmost/patches/`) si fork phase 2+
- Docs (`docs/`)
- CI/CD (`.github/workflows/`)
### Pourquoi
- Couplage fort entre infra, donnees, code custom — versionne ensemble = atomique
- Releases coordonnees (un tag = une version coherente du systeme)
- Un seul repo a cloner pour reproduire l'environnement
### Consequences
- Repo va grossir avec patches Docmost. Acceptable (pas de binaires lourds).
- CI/CD doit etre intelligent (ne build que ce qui a change).
---
## ADR-004 — Postgres separe Docmost / Baserow
**Statut** : Accepte le 2026-05-07
### Decision
Chaque service a son propre Postgres (deux containers) en local dev. Possibilite de partager une instance physique en prod via deux databases logiques si besoin perf.
### Pourquoi
- Isolation : un dump de Docmost n'affecte pas Baserow
- Versions Postgres potentiellement differentes selon les exigences
- Migration upstream de Docmost ou Baserow ne risque pas de casser l'autre
### Consequences
- Plus de RAM consommee (~200 Mo overhead par instance)
- Plus de complexite ops (deux backups distincts) — compense par scripts Makefile
---
## ADR-005 — Stack technique du bridge (Phase 2)
**Statut** : Provisoire — sera confirme avant Phase 2
### Hypothese
- **Runtime** : Node 22 LTS
- **Framework** : Hono (rapide, leger, TypeScript-first)
- **HTTP client** : ofetch ou native fetch
- **Cache** : Redis (memoire partagee avec Docmost ou dedie)
- **Validation** : zod
- **Tests** : vitest
### A confirmer en Phase 2
- Si on adopte Bun runtime au lieu de Node (perf + TS native)
- Si le bridge stocke un etat propre (Postgres dedie) ou reste stateless