Skip to content

feat(projections): add transactional PostgreSQL projections - #40

Merged
jwilger merged 33 commits into
mainfrom
feat/transactional-postgres-projections
Sep 10, 2026
Merged

jwilger merged 33 commits into
mainfrom
feat/transactional-postgres-projections

Conversation

@jwilger

@jwilger jwilger commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Summary

  • add a lossless global PostgreSQL delivery frontier with deterministic backfill and explicit source failures
  • add transactional projectors whose read-model effects and durable progress commit in the same leader-owned SQLx transaction
  • add typed retry/skip/stop/fatal, commit-indeterminate recovery, batch/continuous execution, and coordinated reset/replay
  • add reusable public backend contracts, fault-injection coverage, documentation, and the 2.1.0 release-readiness matrix

Architecture and compatibility

  • Implements accepted ADR-0050 and ADR-0051.
  • Keeps SQLx-free delivery vocabulary in eventcore-types; PostgreSQL execution remains in eventcore-postgres and is re-exported under eventcore::postgres::projections.
  • Preserves the released legacy projector, reader, checkpoint, coordinator, and migration APIs. The new API is additive and targets lockstep version 2.1.0.
  • Supports separate event-source and read-model pools, including distinct databases.
  • Does not add shadow-generation rebuilding or Foundry-specific domain behavior.

Migration and operations

  • Uses a projection-component migration ledger separate from _sqlx_migrations.
  • Initial delivery migration takes ACCESS EXCLUSIVE on the events table while it backfills stable positions and installs the transactional frontier trigger; operators must schedule writer downtime.
  • Projector source/selection identities are durable compatibility boundaries.
  • Advisory leadership is session-affine and the owning connection is close_on_drop.
  • Commit errors are reported as indeterminate; operators recover by starting a fresh run that reloads durable progress.
  • Reset/replay requires coordinated downtime and intentionally has no shadow-generation handoff.

Behavioral contracts

The reusable suite covers all 16 requested contracts: atomic effect/progress commit; both rollback directions; true interrupted-commit recovery; restart; redelivery suppression; commit-order-safe delivery; malformed input; leader exclusion; fence loss; multi-page batch drain; continuous catch-up; bounded retry exhaustion; explicit skip; reset/replay reconstruction; and after-commit ordering.

Additional regressions cover full persisted-envelope fidelity, event-type-aware application decoding, exact failure context, zero-batch rejection, source/selection identity validation, retry backoff arithmetic, and cancellation-safe fixture/proxy ownership.

Local evidence

  • cargo nextest run --workspace --all-features: 500/500 passed, 0 skipped
  • cargo test --doc --workspace --all-features: 35 passed, 18 ignored
  • cargo build --workspace --all-features: passed
  • cargo clippy --all-targets --all-features -- -D warnings: passed
  • standalone eventcore-postgres library check and warning-denied rustdoc: passed
  • focused PostgreSQL projection binaries: 110/110 passed
  • scoped mutation testing: 92 outcomes = 31 caught + 61 unviable, 0 missed/survivors/timeouts
  • 32/32 branch commits are signed and use Conventional Commit subjects
  • final database cleanup: 0 other client sessions and 0 test-owned schemas
  • seven independent pre-PR reviews (architecture, transaction, concurrency/fencing, recovery/fault truthfulness, API/semver, test quality, and documentation): approved with 0 unresolved findings

Full evidence and the 10-finding/16-contract matrices are in the release-readiness report.

Tracking and release boundary

  • Tiber task: 20260909-zscu-deliver-transactional-postgresql-projections-through-reviewed-pr
  • Foundry should consume exact version =2.1.0 with feature postgres only after merge and separately approved publication.
  • No crate publication is authorized by this PR.
  • Merge remains owner-controlled and is not authorized by opening this PR.

@jwilger

jwilger commented Sep 10, 2026

Copy link
Copy Markdown
Owner Author

Final delivery audit for signed head 83cae41048e3cb59ae70ae1f56ca38f7c81c414e:

  • replacement CI run 34503197038 completed successfully
  • all 8 reported checks are green: Detect Changes, Format, Test, Clippy, Experimental Model Feature Isolation, Security Audit, Mutation, and CI Gate
  • GitHub reports the PR mergeable with a clean merge state; there are no unresolved comments
  • seven independent Codex review scopes (architecture, transaction ownership, concurrency/fencing, recovery/fault truthfulness, API/semver, test quality, and documentation) approved with 0 Critical, 0 Important, and 0 Minor findings
  • local evidence: 500/500 all-feature workspace tests, 110/110 focused PostgreSQL projection tests, and 92 scoped mutation outcomes with 0 missed/surviving mutants and 0 timeouts
  • full 10-finding and 16-contract evidence: release-readiness report

The PR is ready for owner review/merge. Opening and validating this PR does not authorize merge or crate publication. Publication remains separately approval-gated.

@jwilger
jwilger merged commit 5d496c7 into main Sep 10, 2026
8 checks passed
@jwilger
jwilger deleted the feat/transactional-postgres-projections branch September 10, 2026 17:18
@jwilger jwilger mentioned this pull request Sep 10, 2026
jwilger added a commit that referenced this pull request Sep 10, 2026
## 🤖 New release

* `eventcore-macros`: 2.0.1 -> 2.1.0
* `eventcore-types`: 2.0.1 -> 2.1.0 (✓ API compatible changes)
* `eventcore-postgres`: 2.0.1 -> 2.1.0 (✓ API compatible changes)
* `eventcore-sqlite`: 2.0.1 -> 2.1.0
* `eventcore`: 2.0.1 -> 2.1.0 (✓ API compatible changes)
* `eventcore-memory`: 2.0.1 -> 2.1.0
* `eventcore-testing`: 2.0.1 -> 2.1.0 (✓ API compatible changes)
* `eventcore-examples`: 2.0.1 -> 2.1.0
* `eventcore-fs`: 2.0.1 -> 2.1.0

<details><summary><i><b>Changelog</b></i></summary><p>

## `eventcore-macros`

<blockquote>

##
[1.1.1](eventcore-macros-v1.1.0...eventcore-macros-v1.1.1)
- 2026-08-06

### Bug Fixes

- *(model)* complete experimental checker acceptance
</blockquote>

## `eventcore-types`

<blockquote>

##
[2.1.0](eventcore-types-v2.0.1...eventcore-types-v2.1.0)
- 2026-09-10

### Features

- *(projections)* add transactional PostgreSQL projections
([#40](#40))

### Features

- _(projections)_ add backend-neutral delivery positions, stable
projection identities,
selections, persisted envelopes, and the replayable source contract for
the planned 2.1.0
  release
</blockquote>

## `eventcore-postgres`

<blockquote>

##
[2.1.0](eventcore-postgres-v2.0.1...eventcore-postgres-v2.1.0)
- 2026-09-10

### Features

- *(projections)* add transactional PostgreSQL projections
([#40](#40))

### Documentation

- _(projections)_ add migration, operation, recovery, and reset guidance
for transactional read models

### Features

- _(projections)_ add lossless source delivery, named progress, fenced
leadership, atomic
read-model effects and progress, typed failure policies,
batch/continuous execution, and
  coordinated reset/replay for the planned 2.1.0 release
- _(projections)_ add application-owned envelope-aware decoding for
multi-type selections while
  retaining payload JSON decoding by default
</blockquote>

## `eventcore-sqlite`

<blockquote>

##
[2.0.0](eventcore-sqlite-v1.1.1...eventcore-sqlite-v2.0.0)
- 2026-08-11

### Documentation

- *(snapshots)* explain durable command state

### Features

- *(snapshots)* persist command state projections
</blockquote>

## `eventcore`

<blockquote>

##
[2.1.0](eventcore-v2.0.1...eventcore-v2.1.0)
- 2026-09-10

### Features

- *(projections)* add transactional PostgreSQL projections
([#40](#40))

### Documentation

- _(projections)_ document the legacy and transactional PostgreSQL
projection guarantees

### Features

- _(projections)_ expose the additive transactional PostgreSQL
projection API through
`eventcore::postgres::projections` for the planned 2.1.0 release;
existing 2.0.1
  `Projector` and `run_projection` callers remain source-compatible
</blockquote>

## `eventcore-memory`

<blockquote>

##
[2.0.0](eventcore-memory-v1.1.1...eventcore-memory-v2.0.0)
- 2026-08-11

### Documentation

- *(snapshots)* explain durable command state

### Features

- *(snapshots)* persist command state projections

### Refactoring

- *(testing)* stabilize reconstruction benchmarks
</blockquote>

## `eventcore-testing`

<blockquote>

##
[2.1.0](eventcore-testing-v2.0.1...eventcore-testing-v2.1.0)
- 2026-09-10

### Features

- *(projections)* add transactional PostgreSQL projections
([#40](#40))

### Features

- _(projections)_ add reusable public transactional-projection contract
fixtures covering
atomicity, restart, malformed input, leadership, retry/skip/stop/fatal
behavior, batching,
  after-commit ordering, and commit acknowledgement loss
</blockquote>

## `eventcore-examples`

<blockquote>

##
[1.0.1](https://git.johnwilger.com/Slipstream/eventcore/compare/eventcore-examples-v1.0.0...eventcore-examples-v1.0.1)
- 2026-06-15

### Testing

- harden doctests and guard docs against fabricated APIs
([#426](https://git.johnwilger.com/Slipstream/eventcore/pulls/426))
</blockquote>

## `eventcore-fs`

<blockquote>

##
[2.0.0](eventcore-fs-v1.1.1...eventcore-fs-v2.0.0)
- 2026-08-11

### Documentation

- *(snapshots)* explain durable command state
- *(ordering)* clarify projection cursor semantics

### Features

- *(snapshots)* persist command state projections

### Refactoring

- *(testing)* stabilize reconstruction benchmarks

### Testing

- *(contract)* cover command state snapshots
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant