Introduire ProcessManagerShape pour les sagas de cascade (vocabulaire saga ≠ projector) #22

Open
opened 2026-07-04 12:11:03 +00:00 by momsse · 0 comments
Owner

Migré depuis viziertronic/octant#53 — ouvert le 2026-06-16 par @momsse.

Issue de suivi, née de la review de la PR #52 (#8) — voir le fil sur group-deletion.cascade-saga.ts : https://github.com/viziertronic/octant/pull/52#discussion_r3422165497

Problème

Les RoleDeletionCascadeSaga / GroupDeletionCascadeSaga sont nommées « Saga » mais implements ProjectorShape<E>. Tension de vocabulaire :

  • Projector / projection (côté lecture) : flux d'events → read model.
  • Saga / Process Manager (côté écriture) : events → émet des commands pour coordonner un processus inter-agrégats.

Nos *CascadeSaga réagissent à RoleDeletedEvent/GroupDeletedEvent et émettent des commands (RevokeUserRoleAssignmentCommand, RemoveRoleFromGroupCommand, RevokeGroupMembershipCommand) via executeCommand — ce sont des Process Managers. Elles implements ProjectorShape uniquement parce que le runner de projection (checkpoint, replay, livraison at-least-once, hook { name, project, reset }) est réutilisé comme mécanisme d'abonnement. → nom orienté lecture pour un usage orienté écriture.

Solution retenue (option 2 de la discussion)

Introduire un type ProcessManagerShape<Event> dans @octant/event-sourcing (projection.ts), structurellement équivalent à ProjectorShape (le runner reste inchangé) :

export type ProcessManagerShape<Event> = ProjectorShape<Event>

…l'exporter depuis l'index, puis basculer les deux sagas sur ProcessManagerShape<RoleEvent> / ProcessManagerShape<GroupEvent> (et renommer la variable locale projectorprocessManager). Les InlineProjectors des repos restent des ProjectorShape (ce sont de vrais projecteurs read-model).

Périmètre / dépendances

  • Touche @octant/event-sourcing (ajout du type + export) + les 2 sagas de l'authorization.
  • Dépend de #8 / PR #52 (les sagas y sont introduites). À traiter après le merge de la PR 8 (sinon PR stackée).

Hors scope (pistes plus profondes, écartées pour l'instant)

  • Renommer le mécanisme partagé en nom neutre (EventSubscriberShape / EventReactionShape) avec Projection et Saga comme spécialisations — rename transverse de tout le package event-sourcing + toutes les projections.
  • Introduire un ProcessManagerName distinct de ProjectionName pour la clé de checkpoint.

🤖 Generated with Claude Code

> _Migré depuis [viziertronic/octant#53](https://github.com/viziertronic/octant/issues/53) — ouvert le 2026-06-16 par @momsse._ Issue de suivi, née de la review de la PR #52 (#8) — voir le fil sur `group-deletion.cascade-saga.ts` : https://github.com/viziertronic/octant/pull/52#discussion_r3422165497 ## Problème Les `RoleDeletionCascadeSaga` / `GroupDeletionCascadeSaga` sont nommées « Saga » mais `implements ProjectorShape<E>`. Tension de vocabulaire : - **Projector / projection** (côté *lecture*) : flux d'events → *read model*. - **Saga / Process Manager** (côté *écriture*) : events → **émet des commands** pour coordonner un processus inter-agrégats. Nos `*CascadeSaga` réagissent à `RoleDeletedEvent`/`GroupDeletedEvent` et **émettent des commands** (`RevokeUserRoleAssignmentCommand`, `RemoveRoleFromGroupCommand`, `RevokeGroupMembershipCommand`) via `executeCommand` — ce sont des **Process Managers**. Elles `implements ProjectorShape` uniquement parce que le **runner de projection** (checkpoint, replay, livraison at-least-once, hook `{ name, project, reset }`) est réutilisé comme mécanisme d'abonnement. → nom orienté lecture pour un usage orienté écriture. ## Solution retenue (option 2 de la discussion) Introduire un type **`ProcessManagerShape<Event>`** dans `@octant/event-sourcing` (`projection.ts`), structurellement équivalent à `ProjectorShape` (le runner reste inchangé) : ```ts export type ProcessManagerShape<Event> = ProjectorShape<Event> ``` …l'exporter depuis l'index, puis basculer les deux sagas sur `ProcessManagerShape<RoleEvent>` / `ProcessManagerShape<GroupEvent>` (et renommer la variable locale `projector` → `processManager`). Les `InlineProjectors` des repos restent des `ProjectorShape` (ce sont de vrais projecteurs read-model). ## Périmètre / dépendances - Touche `@octant/event-sourcing` (ajout du type + export) + les 2 sagas de l'`authorization`. - **Dépend de #8 / PR #52** (les sagas y sont introduites). À traiter après le merge de la PR 8 (sinon PR stackée). ## Hors scope (pistes plus profondes, écartées pour l'instant) - Renommer le mécanisme partagé en nom neutre (`EventSubscriberShape` / `EventReactionShape`) avec `Projection` et `Saga` comme spécialisations — rename transverse de tout le package event-sourcing + toutes les projections. - Introduire un `ProcessManagerName` distinct de `ProjectionName` pour la clé de checkpoint. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
momsse/octant#22
No description provided.