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
Workflows (playbooks markdown) pour orchestrer les 4 agents specialises : - README.md : index + conventions communes + integration BYAN web futur - build-story.md : cycle complet livrer 1 story Phase 2 (bridge-dev → bridge-tester → review → CI → deploy staging → validation metier) - sync-bidirec.md : sync Docmost ↔ Baserow event-driven (idempotence + anti-loop X-Bridge-Origin) - release.md : process release semver (E2E staging → tag → approval → deploy prod → watch 30min) - incident.md : SEV1/2/3 response + post-mortem blameless + runbooks - bump-deps.md : Dependabot PRs + major bumps + Docmost/Baserow upstream Chaque workflow specifie : trigger, acteurs (agents + humains), sequence ordonnee avec outputs, gates humains bloquants, rollback, comm templates. Workflows = playbooks declaratifs pour Claude main qui orchestre les agents via Agent tool sequentiel. A migrer plus tard vers BYAN web workflow runs quand le runtime BYAN sera fix. Equipe complete pour formation-hub : - 4 agents specialises (bridge-dev, bridge-tester, acadenice-devops, docmost-fork-dev) - 5 workflows orchestrant leur collaboration
6.3 KiB
6.3 KiB
Workflow : SYNC BIDIREC Docmost ↔ Baserow
Orchestration de la synchronisation bidirectionnelle entre Docmost (wiki) et Baserow (DBs). Phase 2 — necessite que le bridge service soit deploye et operationnel.
Equivalent BYAN-natif : event-driven workflow avec idempotence.
Trigger
L'un des suivants :
- Webhook Baserow
row.created/row.updated/row.deletedsur table donnee - Webhook Docmost
page.created(si configure cote Docmost custom) - Action explicite admin : "Sync forcee projet 42 → Docmost"
- Cron periodique de reconciliation (Phase 3+)
Acteurs
- bridge-dev (handler webhook + sync logic)
- acadenice-devops (config webhooks + monitoring)
- bridge-tester (validation idempotence + anti-loop)
- Corentin (alerte si depassement capacite)
Sequence — type webhook Baserow row.created sur table 'projet'
[1] Webhook recu (bridge endpoint POST /api/webhooks/baserow/projet-changed)
- Verifier signature HMAC X-Baserow-Signature (anti-spoofing)
- Si invalide : log + 401, ABORT
- Output : event valide
[2] Idempotence check (bridge + Redis)
- Lire payload event_id
- Redis : SET bridge:webhook:event:<event_id> "1" EX 86400 NX
- Si SET retourne null (key existait) : event deja traite, ABORT 200
- Sinon : continue
- Output : event nouveau, marque traite
[3] Anti-loop check
- Verifier header X-Bridge-Origin sur la row Baserow
- Si X-Bridge-Origin == "bridge" : c'est nous qui avons cree la row, ABORT
- Sinon : c'est un user qui a cree, continue
- Output : event source legitime
[4] Logique metier (bridge service)
- Pour 'row.created' sur 'projet' :
* Fetch projet detail depuis Baserow (BaserowClient.getRow)
* Fetch client lie (BaserowClient.getRow)
* Calcul nom de page Docmost : "Projet [nom] - [client]"
* Determiner space cible : "Agence" → fetch space ID
- Output : payload pour creation Docmost
[5] Action Docmost (bridge service via DocmostClient)
- DocmostClient.createPage({ spaceId, title, content: template_projet(projet) })
- Header : X-Bridge-Origin: bridge (eviter loop futur)
- Output : pageId Docmost cree
[6] Update Baserow row (bridge service)
- BaserowClient.updateRow(projet_id, { docmost_page_id: pageId })
- Header : X-Bridge-Origin: bridge
- Output : projet Baserow enrichi avec docmost_page_id
[7] Cache invalidation (bridge + Redis)
- RedisCache.invalidatePattern("bridge:projet:*")
- RedisCache.invalidatePattern("bridge:client:<id>:projets")
- Output : caches invalides
[8] Notif si capacite formateur depassee (cas attribution)
- Si event = creation 'attribution' :
* Recalculer Personne.heures_restantes_total
* Si < 0 : notifier admin via SMTP/Slack
- Output : notification envoyee si depassement
[9] Audit log
- Log structurel : { event_id, source: 'baserow', target: 'docmost', action: 'createPage', success: true, duration_ms, ... }
- Output : trace persistee
[10] Reponse webhook
- Return 200 OK { processed: true, page_id: <docmost_page_id> }
Patterns specifiques par event
| Trigger | Action sync |
|---|---|
Baserow row.created sur projet |
Auto-create page Docmost dans space Agence |
Baserow row.created sur formation |
Auto-create collection Docmost (sub-pages par bloc) |
Baserow row.updated sur projet/formation (titre, statut) |
Update title/icon page Docmost liee |
Baserow row.created sur intervention |
Check capacite → notify admin si depassement |
Baserow row.created sur attribution |
Notify formateur (email) + check capacite |
| Docmost page.created (template specifique 'compte-rendu') | Auto-create row dans table comptes_rendus Baserow (Phase 3+) |
| Docmost share.created | Log audit + notify admin (alerte data leak risk) |
Gates humains
Aucun gate bloquant — c'est event-driven temps reel. Mais :
- Notif Corentin sur depassement capacite (asynchrone)
- Notif Corentin sur erreurs critiques (sync echec apres 3 retry)
Rollback / gestion d'erreurs
| Echec | Strategy |
|---|---|
| Docmost API down | Retry 3x exponential backoff. Si tjrs KO : queue Redis pour retry batch |
| Baserow row introuvable (race condition) | Fetch retry x2 avec 200ms delay. Sinon : log + skip event |
| Cache invalidation echec | Log warning, continuer (TTL fallback 5 min) |
| Notification SMTP fail | Log warning, alerte degraded |
| Loop detecte (X-Bridge-Origin manquant cote bridge writes) | URGENT : alerte Corentin, audit code bridge |
Anti-loop strategy (CRITICAL)
Pour eviter Docmost → bridge → Baserow → bridge → Docmost → ... boucle infinie :
- Header X-Bridge-Origin : tous les writes du bridge vers Baserow et Docmost ajoutent ce header
- Detection cote handler : si l'event provient d'une row/page avec ce flag, ABORT
- Idempotence event_id : meme si une boucle se forme, max 1 cycle (TTL 24h en Redis)
- Rate limit : max 1 sync identique / 5 min sur entite (cle:
bridge:sync:<entity>:<id>) - Monitoring : alerter si > 10 events identiques en 1 min (signe de boucle)
Outputs
- Pages Docmost crees automatiquement
- Rows Baserow enrichies avec ids Docmost (lien bidirec)
- Caches invalides
- Audit log evenement traite
- Notifications metier si necessaire
Tests obligatoires
- Test idempotence : envoyer le meme event 5 fois → un seul effet (bridge-tester)
- Test anti-loop : simuler bridge-write → verifier que webhook ignore (bridge-tester)
- Test rate limit : 100 events identiques en 1 min → verifier que rate limit kick in
- Test recovery : Docmost down 5 min → events queues et processed apres recovery
- Test webhook signature invalid : event avec mauvais HMAC → 401 (bridge-tester)
Exemple invocation
Trigger non-manuel — se declenche automatiquement quand Baserow envoie un webhook au bridge. Mais peut etre invoque manuellement pour :
- Reconciliation : "WF SYNC : force re-sync de tous les projets non-mappes vers Docmost"
- Debug : "WF SYNC : trace l'event ID xyz pour comprendre pourquoi il a abort"
Notes
- Webhooks Baserow : a configurer cote Baserow UI ou API (apres deploy bridge)
- Endpoint signature secret :
BASEROW_WEBHOOK_SECRETdans.envbridge - Logs : toutes les operations sync sont loguees structurellement (Pino) avec event_id pour traceability