Files
goodgo-platform/apps
Ho Ngoc Hai 769cc9f758 feat(read-models): add projection_offset table + idempotency harness (GOO-187)
RFC-003 §0 Phase 0 — the (eventId, handlerName) offset contract.

- prisma: ProjectionOffset model + 20260424100000_add_projection_offset
  migration (composite PK, handlerName/appliedAt index for reconciliation)
- infra: PrismaProjectionOffsetStore (createMany skipDuplicates +
  applyWithOffset transactional helper that rolls offset+mutation back
  together on failure)
- module: bind PROJECTION_OFFSET_STORE → PrismaProjectionOffsetStore
- testing: assertProjectorIdempotent harness ("replay N times → single
  state mutation") for Phase 2/3 projector specs to reuse
- tests: 12 specs lock the contract — replay 5x → 1 mutation, broken
  projectors fail loudly, two projectors keep independent offsets

Note: prisma format normalised existing column alignment when the new
model was added; the meaningful diff is the appended ProjectionOffset
block at the bottom of schema.prisma.

Acceptance criteria from issue:
- migration applies cleanly (validated via prisma format/parse)
- harness exported from read-models/testing and used by example
  projector spec at __tests__/idempotency-harness.spec.ts

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-24 12:24:30 +07:00
..