Skip to content

feat: publish deal.created from every booking path - #5

Merged
numarasSigmaSoftware merged 8 commits into
ui/devfrom
feature/booking-events
Sep 15, 2026
Merged

numarasSigmaSoftware merged 8 commits into
ui/devfrom
feature/booking-events

Conversation

@numarasSigmaSoftware

@numarasSigmaSoftware numarasSigmaSoftware commented Sep 15, 2026 •

Copy link
Copy Markdown
Owner

Problem

Only the approval flow and the negotiation service publish events. A deal booked over REST left GET /events empty, so a client polling the feed never learned a deal existed. Verified on a running instance: two bookings, event count zero.

Change

Add _emit_deal_created() and call it after each booking path persists its deal: quote booking, from-template, curated, bulk create, and migration. The payload carries source (one of those five), deal_type, status, product_id, and quote_id.

deal.created is an audit-class event in the event model, so the emission is fail-closed by design: if the bus fails, the event is written to the audit fallback log and the booking still returns 200; if that write also fails, the error propagates after the deal is already persisted. Both branches are pinned by tests. The retry-after-failure ordering, where a failure after the quote is flipped leaves a retry with a 409 and no deal id, applies to any post-persist failure and predates this change; it is tracked as IABTechLab#88.

Docs: the event-bus overview now describes the real emitters and the source values; changelog entry under Unreleased; data/audit_fallback.jsonl is gitignored. The fallback file is the same class of leftover as the database in IABTechLab#82: the audience-plan tests wrote it through a fake storage that backed the event bus, and now publish to an in-memory bus instead.

Verification

Independent of IABTechLab#84; the deal_service.py hunks are disjoint.

Not changed

From-template booking has no idempotency lookup, so a retried request creates a second deal and now a second event. Pre-existing; tracked as IABTechLab#87.

Only the approval flow and the negotiation service emitted events. A
deal booked over REST (quote -> book, from-template, or curated) left
GET /events empty, so a client polling the feed never learned a deal
existed.

Add _emit_deal_created() and call it after each booking path persists
its deal. The payload carries source (quote | template | curated),
deal_type, status, product_id and quote_id. Fail-open like every
non-audit event: a bus failure never fails the booking.

Tests authenticate the quote booking call, since IABTechLab#77 requires a
verified buyer on POST /api/v1/deals.
…nches

_emit_deal_created is fail-closed, not fail-open: deal.created is in
AUDIT_EVENT_TYPES, so a bus failure writes the event to the audit fallback
file and the booking still succeeds; if that write also fails, the error
propagates after the deal is already persisted. No code-path change.

Two tests pin the branches over HTTP on the quote path.
bulk_deal_operations (create branch) and migrate_deal persisted a new deal
without publishing deal.created, so the event feed missed those bookings.
Both now call _emit_deal_created right after storage.set_deal, with
source "bulk" and "migration"; the helper docstring lists all five sources.
No emission for deprecate or for the old deal in a migration.
Same quote booked twice over HTTP with the same idempotency_key: both
responses are 200 with the same deal_id and the bus holds exactly one
deal.created. Test-only; the emission already sits after the replay
short-circuit.
Each payload-inspecting test now asserts source, deal_type, status,
product_id and quote_id (None where the path books without a quote)
through one module-level _assert_payload helper shared by the five tests.
The http_client fixture's _FakeStorage has no ``set``, so the booking's
audit-class deal.created fell back to data/audit_fallback.jsonl on every
run. The fixture now patches get_event_bus to an InMemoryEventBus for
every test that books through it, and the fallback path is gitignored
next to *.db.
The DEAL_CREATED row said the event came from an accepted proposal; it is published by every booking path, with payload.source naming which one.
@numarasSigmaSoftware
numarasSigmaSoftware changed the base branch from main to ui/dev September 15, 2026 20:15
@numarasSigmaSoftware
numarasSigmaSoftware marked this pull request as ready for review September 15, 2026 20:15
@numarasSigmaSoftware
numarasSigmaSoftware merged commit 8184f4d into ui/dev Sep 15, 2026
5 checks passed
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.

1 participant