Wiki/examples/acadenice-formation-hub
Corentin JOGUET 2ed73fa948
Some checks are pending
CI / Lint bridge (Biome) (push) Waiting to run
CI / Type-check bridge (push) Blocked by required conditions
CI / Tests unit bridge (push) Blocked by required conditions
CI / Tests integration bridge (push) Blocked by required conditions
CI / Security scan (push) Waiting to run
CI / Docker build + healthcheck (push) Blocked by required conditions
feat(bridge): R1 refactor proxy generique style Notion
Pivot strategique : DocAdenice = produit Notion-like generique. Le bridge
est livre vide a un user qui cree ses tables Baserow comme il veut. Code
sans aucune ontologie metier.

Suppressions :
- 9 entites domain metier (Personne, Formation, Bloc, Module, Attribution,
  Client, Projet, Tache, Intervention) + types.ts (Role, statuts)
- baserow-repo.ts (mega-fichier 554 LOC avec 9 repos heritant BaseRepo)
- 6 routes metier (personnes, formations, projets, modules, interventions,
  attributions) + tests associes
- Lookup PersonneRepo.findByEmail dans middleware auth
- Mapping DEFAULT_ROLE_SCOPES dans middleware/scopes.ts
- Cascade rollup metier dans webhooks/baserow-handler.ts

Ajouts :
- Domain generique : Table, Row, Field, View + schemas zod refondus
- 4 repos generiques : tables / rows / fields / views
- Route unique routes/tables.ts avec 9 endpoints REST CRUD generiques
- Claim JWT acadenice_permissions[] lu directement dans le middleware auth
  (alimente par RBAC dynamique cote DocAdenice en R2)
- examples/acadenice-formation-hub/ : README + seed-baserow.md schema
  9 tables + example-roles.md (Formateur, Developpeur, Direction, Support,
  Admin avec permissions generiques)

Refactors :
- BaserowClient etendu : listTables, getTable, listFields, listViews,
  getGridViewRows
- middleware/auth.ts : extractPermissions(payload), AuthenticatedUser
  remplace roles[] par permissions[]
- middleware/scopes.ts : computeOidcScopes(groups, permissions, map)
- webhooks/baserow-handler.ts : invalidation generique
  bridge:tables:<tableId>:* sans cascade cross-table
- lib/cache.ts : invalidateEntity -> invalidateTable(redis, tableId, rowId?)
- container.ts : drop tableIds, RepoSet={tables, rows, fields, views}
- 501 NOT_IMPLEMENTED si DB token sur endpoints /tables qui exigent JWT

Tests : 250/250 verts (depuis 319). Coverage : domain 98.9%, adapters 89%,
auth 97.08%, rate-limit 100%, cache 100%, webhooks 100%.

Quality gates verts : typecheck, lint biome, vitest, coverage thresholds.

Refs: R1 dans le pivot strategique DocAdenice Notion-like generique.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 22:12:32 +02:00
..
example-roles.md feat(bridge): R1 refactor proxy generique style Notion 2026-05-07 22:12:32 +02:00
README.md feat(bridge): R1 refactor proxy generique style Notion 2026-05-07 22:12:32 +02:00
seed-baserow.md feat(bridge): R1 refactor proxy generique style Notion 2026-05-07 22:12:32 +02:00

Example — Acadenice formation-hub

Cet exemple montre un cas d'usage parmi d'autres du bridge generique DocAdenice / Notion-like : le suivi d'heures formateurs et developpeurs pour le CFA + Agence Acadenice.

Contexte

Acadenice est :

  • un CFA (Centre de Formation des Apprentis) — heures de formation a tracer
  • une Agence dev — heures de prestations a tracer

Une meme personne peut porter plusieurs roles : formateur (CFA), developpeur (Agence), admin/direction/support transverse. La capacite annuelle est splittee entre les deux activites.

Pourquoi un exemple et pas du code metier dans le bridge

Le bridge DocAdenice est un proxy generique style Notion. Il expose n'importe quelle table Baserow via /api/v1/tables/* sans rien savoir du metier. La modelisation Acadenice (9 tables, formules de rollup, regles de gestion) vit :

  • cote Baserow : schema des 9 tables + formules + vues (cf seed-baserow.md)
  • cote DocAdenice : RBAC dynamique avec roles custom (Formateur, Developpeur, Direction, Support) qui produisent des claims OIDC acadenice_permissions[] (cf example-roles.md)
  • cote frontend : interface metier (dashboards capacite, attribution modules, saisie heures) consomme l'API generique du bridge

Comment rejouer cet exemple

  1. Provisionner Baserow avec les 9 tables decrites dans seed-baserow.md
  2. Creer les roles custom DocAdenice de example-roles.md
  3. Configurer le bridge : il proxie tout, pas de config metier specifique
  4. Construire le frontend (Tiptap node-views ou pages dediees Docmost)

Mapping bridge generique <-> ce metier

Generique bridge Vu dans cet exemple
/tables 9 tables : Personne, Formation, Bloc, ...
/tables/:id/rows CRUD sur une de ces tables
Webhooks invalidation Cache Redis invalide par tableId touche
Cascades cross-table Faites cote Baserow via formules + lookups
Permissions read:tables Donnees globalement par DocAdenice via OIDC
Permissions specifiques Filtrees cote frontend selon role custom

Autres exemples envisageables

Le meme bridge pourrait servir :

  • un CRM custom (3 tables : Contacts, Opportunites, Notes)
  • un tracker de bugs (2 tables : Issues, Comments)
  • une base d'inventaire IT (5 tables : Asset, Owner, Site, Maintenance, Log)

Aucun de ces cas ne necessite de modification du bridge — juste une config Baserow + DocAdenice.