Skip to content

fix(outbox): repair OutboxEntry hydration (delivery was broken)#7

Merged
titus-toia merged 2 commits into
masterfrom
fix/outbox-entry-hydration
May 29, 2026
Merged

fix(outbox): repair OutboxEntry hydration (delivery was broken)#7
titus-toia merged 2 commits into
masterfrom
fix/outbox-entry-hydration

Conversation

@titus-toia

Copy link
Copy Markdown
Contributor

What

OutboxRepository::entry_from_row drifted from OutboxEntry's constructor:

  • omitted required locked_until / locked_byArgumentCountError
  • wrapped scheduled_at / next_attempt_at / created_at / processed_at in DateTimeImmutable where the constructor now wants raw string

Impact

Latent but serious: any consumer whose DI resolves OutboxProcessor hits this on the first fetch. Net effect — integration events get written to the outbox but never delivered on this path. It stayed hidden because consumers with an incomplete DI never ran the processor, so entry_from_row was never exercised.

Fix

Pass the date fields as raw stored strings; add the two locked_* args.

Verified

End-to-end on a live install: pending event → process_batchcompleted (1 total, 1 completed, 0 failed).

206 unit tests pass. Version 0.1.5 → 0.1.6.

🤖 Generated with Claude Code

titustangible and others added 2 commits May 29, 2026 16:05
OutboxEntry's constructor was refactored — date fields became plain strings
and locked_until/locked_by were added — but entry_from_row was never updated
in lockstep. It omitted the two required locked_* args (ArgumentCountError)
and wrapped the date fields in DateTimeImmutable where the constructor now
expects raw strings.

This never surfaced because the consumer DI that resolves OutboxProcessor was
also incomplete, so the processor never ran and entry_from_row was never
exercised. Once the processor resolves, every fetch hit this. Net effect:
integration events were written to the outbox but never delivered on this
code path.

- Pass scheduled_at / next_attempt_at / created_at / processed_at as the raw
  stored strings (no DateTimeImmutable wrap).
- Add locked_until and locked_by to the hydration.

Verified end-to-end: pending event → process_batch → completed.

Bumps 0.1.5 -> 0.1.6.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The wiring snippet emitted OutboxProcessor with 3 positional args in the wrong
order (IOutboxRepository, IOutboxPublisher, OutboxConfig), omitting IDDDConfig
entirely — it never matched the 4-arg constructor (IDDDConfig, IOutboxRepository,
OutboxConfig, IOutboxPublisher). Any consumer pasting it got a broken processor.

Emit `~` instead: autowired by type, all four deps are already registered, and
it can't drift from constructor arg order — the exact failure that left the
outbox undeliverable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@titus-toia titus-toia merged commit 5f329d5 into master May 29, 2026
1 check passed
@titus-toia titus-toia deleted the fix/outbox-entry-hydration branch May 29, 2026 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants