feat(examples): v3 reference seller — runnable Tier 2 + v3 wiring (#357)#373
Merged
Conversation
️✅ There are no secrets present in this pull request anymore.If these secrets were true positive and are still valid, we highly recommend you to revoke them. 🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request. |
Multi-file directory under ``examples/v3_reference_seller/`` that wires every Tier 2 / v3-supporting component into one runnable adopter pattern. Spec 3.0-compliant on the wire, 3.1-ready in architecture and storage. * ``src/models.py`` — SQLAlchemy 2.0 models (Tenant, BuyerAgent, Account, MediaBuy) with 3.1-ready columns. * ``src/tenant_router.py`` — SQL-backed SubdomainTenantRouter with in-process cache. * ``src/buyer_registry.py`` — tenant-scoped BuyerAgentRegistry. * ``src/audit.py`` — DbAuditSink writing audit_events. * ``src/platform.py`` — sales-non-guaranteed impl (the bulk of what an adopter customizes). * ``src/app.py`` — main entrypoint wiring serve(transport="both") + a ``build_app`` helper composing SubdomainTenantMiddleware on the parent Starlette app. * ``seed.py`` + ``docker-compose.yml`` — dev fixtures + Postgres. * ``README.md`` — clone-and-modify guide. * ``tests/test_smoke.py`` — 7 import + Protocol-conformance tests. End-to-end verified locally against postgres:16. The compose uses ``POSTGRES_HOST_AUTH_METHOD=trust`` for loopback dev — no literal password in version control; production sellers source DB credentials from a secrets backend. Closes #357 (MVP). Follow-ups: HTTP-Sig verifier middleware in context_factory, admin CRUD API, Alembic migrations, swap to PgTaskRegistry / PgWebhookDeliverySupervisor for production. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
44a66eb to
76ee0b5
Compare
…are=) The 4-expert review of #357 surfaced multiple convergent blockers in the v3 reference seller MVP: * `app.py` `build_app()` imported `_build_mcp_and_a2a_app` from the wrong module → ImportError at adopter call time * `main()` never wired `SubdomainTenantMiddleware` → multi-tenant claim was false; `current_tenant()` would return None * `platform.create_media_buy` extracted `total_budget` / `currency` / `start_time` / `end_time` against a wrong-shape API surface (TotalBudget object, StartTiming union) — every persisted media buy stored corrupted data or NULL * `media_buy_id = f"mb_{uuid[:16]}"` collides at scale → IntegrityError Bundled fix: * Framework: add `asgi_middleware=Sequence[(cls, kwargs)]` kwarg to `adcp.server.serve()` (and forward through `adcp.decisioning.serve()`) so adopters layer Starlette-style ASGI middleware without dropping to `_build_mcp_and_a2a_app`. * Example: `main()` now passes `asgi_middleware=[(SubdomainTenant Middleware, {"router": router})]`. Dead `build_app()` helper removed. * `platform.py`: project `req.total_budget.amount/.currency` and unwrap `StartTiming.root` (`'asap'` → now()); `media_buy_id` is a full UUID (the (tenant_id, idempotency_key) unique constraint already guards replay). * `models.py` + `buyer_registry.py` + `seed.py`: `billing_capabilities`, `default_terms`, `allowed_brands` switched from JSON-encoded String columns to native JSON columns (matches the rest of the schema). * `audit.py`: docstring corrected — `record()` is best-effort but awaited inline (not fire-and-forget). * `tenant_router.py`: cache renamed from "LRU-ish" to bounded FIFO to match actual eviction behavior. * `README.md`: drop inaccurate claims (HTTP-Sig wired, project_account_for_response wired inline). Add dev-only callout for docker-compose trust auth + seed bearer token. Test: `tests/test_serve_asgi_middleware.py` covers the new kwarg's no-op + outermost-first composition contract. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Protocol-expert review surfaced one BLOCKER on commit 8d6d783: ``pricing_options`` in the get_products stub didn't conform to the spec's ``CpmPricingOption`` shape — used ``type``/``rate`` keys instead of the discriminator ``pricing_model`` and required ``fixed_price``, and was missing the required ``pricing_option_id``. Buyer agents validating the response against the discriminated union would reject the seller's catalog. Also addresses two should-fix items: * ``serve(asgi_middleware=)`` docstring now warns adopter middleware to pass through ``lifespan`` and ``websocket`` scopes so the framework's lifespan composition still runs. * README "Alembic migrations" callout clarifies that ``create_all`` does NOT detect column renames or type changes on existing tables — adopters who prototyped against earlier branches need to drop/recreate the dev database after pulling the JSON-column rename. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Multi-file directory under `examples/v3_reference_seller/` that wires every Tier 2 / v3-supporting component into one runnable adopter pattern. Spec 3.0-compliant on the wire, 3.1-ready in architecture and storage.
The directory is the canonical fork-and-modify starting point for adopters building a v3 seller.
What's wired
What's NOT wired (yet)
Separable follow-ups; framework components exist:
Closes #357 (MVP).
Test plan
🤖 Generated with Claude Code