ADR-0004

Layout du monorepo

source : docs/adr/0004-monorepo-layout.md · versionné · MADR-lite

ADR-0004 — Layout du monorepo

  • Statut : Accepted
  • Date : 2026-04-24
  • Décideurs : Core team OmbrysWeb
  • Références : cahier des charges § 5.7.4, § 8
  • Dépend de : ADR-0001 (Rust + Axum)

Contexte

OmbrysWeb regroupe :

  • un frontend Next.js 16,
  • 7 micro-services Rust,
  • des packages partagés (UI Tailwind en M3, lib commune Rust ombrys-common),
  • de l'IaC (Talos, Vault, SPIFFE, Linkerd, CrowdSec, Forgejo),
  • une CI/CD non triviale (SLSA, cosign, SBOM, builds reproductibles),
  • une documentation technique étendue (ADR, threat model, runbooks).

On doit choisir entre :

  • Monorepo (tout ensemble),
  • Polyrepo (un repo par composant),
  • Hybride (monorepo pour le code applicatif + repos séparés pour IaC/docs).

Décision

Monorepo unique, layout pnpm workspace + Cargo workspace, avec séparation de premier niveau par intention.

/
├── apps/
│   └── web/                 # Next.js 16 (pnpm workspace "@ombrys/web")
├── services/
│   ├── auth-svc/            # Rust — Axum + WebAuthn
│   ├── blog-svc/
│   ├── storage-svc/
│   ├── messaging-svc/
│   ├── audit-svc/
│   ├── vault-svc/
│   └── admin-svc/
├── packages/
│   ├── ombrys-common/       # Rust lib — health, tracing, shutdown, healthcheck
│   └── ui/                  # (M3) Tailwind components package
├── infra/
│   ├── talos/               # machineconfig + patches + Cilium + Kyverno PSA
│   ├── vault/               # Helm values + policies HCL par service
│   ├── spiffe/              # SPIRE server/agent values + registration entries
│   ├── linkerd/             # annotations + Server/AuthorizationPolicy
│   ├── crowdsec/            # scenarios + config WAF
│   ├── forgejo/             # Helm values Forgejo self-hosted
│   └── k8s-base/            # namespaces, RBAC de base
├── ci/                      # scripts utilisés dans les GitHub Actions
├── scripts/                 # start.sh helpers (doctor, seed, gen-dev-certs)
├── docs/
│   ├── adr/
│   ├── security/
│   ├── operations/
│   └── policy/
├── .github/workflows/       # ci.yml, release.yml, reproducible.yml
├── Cargo.toml               # workspace Rust
├── package.json             # workspace pnpm
├── pnpm-workspace.yaml
├── rust-toolchain.toml
├── docker-compose.yml
├── start.sh
├── .env.example
├── Dockerfile.rust-service  # Dockerfile partagé pour les 7 services Rust (ARG SERVICE)
└── CAHIER_DES_CHARGES.md

Justification

  • Atomicité des changements : une feature qui touche frontend + auth-svc + doc change en un seul commit, visible dans un seul PR.
  • Cohérence des versions : rust-toolchain.toml, pnpm lockfile, image de base Docker unifiés. Pas de dérive entre repos.
  • CI/CD simplifiée : une seule provenance SLSA par release, un seul workflow à maintenir.
  • Onboarding : git clone + ./start.sh suffit. Pas de navigation entre 10 repos.
  • Recherche de code globale : un seul grep -r, un seul index IDE.
  • Threat model / audit : périmètre audit = un repo, plus simple à cartographier.

Conséquences

Positives

  • Builds et scans de chaîne d'approvisionnement uniformes.
  • Miroir public unique (GitHub), vue publique cohérente.
  • Refactors transverses plus simples (renommage d'une API Rust utilisée par 3 services).
  • Partage trivial du code commun (packages/ombrys-common).

Négatives

  • Poids du clone plus élevé à mesure que le projet grandit (mitigation : sparse-checkout possible, partial clone).
  • Permissions granulaires plus limitées (pas de distinction par sous-repo). Mitigation : CODEOWNERS par dossier, branch protection par path.
  • cargo check --workspace et pnpm -r build deviennent longs → caching agressif dans CI (Swatinem/rust-cache, pnpm cache).

Neutres

  • Les IaC et la documentation vivent dans le même repo — cohérent avec le principe "infrastructure = code", renforcé par la politique de revue (ADR, PR).

Conventions de commit et PR

  • Commits petits et ciblés, focus sur une seule section du monorepo quand possible.
  • Préfixe optionnel dans le titre pour grep : web:, auth-svc:, infra:, docs:, ci:.
  • PR obligatoirement reliée à une issue GitHub M0–M7.
  • CODEOWNERS :
  • /services/ → backend team + security lead
  • /apps/web/ + /packages/ui/ → frontend team
  • /infra/ → SRE
  • /docs/security/ + /docs/policy/ → security lead + core team
  • /docs/adr/ → core team (consensus requis)

Suivi

  • En v2, si une partie (ex : SDK publique) nécessite un cycle de release vraiment disjoint, ADR de révision pour extraire un sous-repo dédié.
  • Pas de split prématuré : attendre que la gêne soit mesurable.

Changelog

  • 2026-04-24 : rédaction initiale, statut Accepted.