fix: utm_templates.list() uses the real GET /api/user/utm-templates route - #8
Merged
Conversation
…es route Follow-up to #7 / ADR-020: the platform never actually populated utmTemplates on GET /api/v1/me (ADR-003 was based on incorrect information — there was no dedicated list route at the time). #833 added a real GET /api/user/utm-templates route returning {templates:[...]}; list() now calls it instead of silently returning [] via a field that never existed. create() already sent the correct source/medium/campaign body fields, no change needed there — the 500 it used to get back (#831) was a server-side bug (undefined uuidv4), not a client-side wire-format mismatch. Vendors sdk-contract.json 1.0.10 (utm_list_via_me renamed to utm_list to match; utm_create's expected body corrected from utmSource/utmMedium/ utmCampaign to plain source/medium/campaign, matching what the SDK already sends). Adds previously-missing async test coverage for this resource. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014BLo12Xi5cjtEA5HiNb3y8
Fixes wrong/missing fields in 4 typed models, found by re-verifying the fixtures they were originally built from against live staging response bodies. extra="allow" meant a wrong alias silently yielded None rather than erroring, so none of this surfaced as a test failure until the re-audit. - TrustScoreResult: added source, created_at (raw epoch-ms int on this endpoint specifically — own field validator, not the shared Firestore-dict coercion). short was already correct. - NamespaceInfo: added can_claim_custom_domain, can_claim_subdomain, namespace_data (the real fields) — upgrade_required is never actually sent. - AggregateAnalytics: added bot_clicks_excluded (the only field that was actually missing; the rest — clicks_by_day, country_breakdown, etc. — was already correctly named). - Link: added geo_restriction, og_meta, is_custom, is_disabled, disabled_reason, trust_score, trust_status, threats. All additive (no field renamed or removed) — no breaking changes. affiliate.get_limits()/custom_domains.add()/webhooks.list_event_types() return raw dicts by design; confirmed no wrong-alias risk there and left them alone rather than change their return type to a typed model (which would be breaking). Vendors sdk-contract.json 1.0.11 (ADR-022 fixture corrections). Adds platform-verified-shape tests for all four models fixed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014BLo12Xi5cjtEA5HiNb3y8
cookie_days (kept as the field/kwarg name for backward compatibility) was reading and writing the wrong wire key: cookieDays instead of the platform's actual cookieDurationDays. Wrong on both sides — create_program()/ update_program()'s request body, and the response model. Also adds merchant_id, max_partners, partner_count, is_public, created_at, updated_at (present on the owned-program endpoints; discover()'s public-summary response is a subset, tolerated since every field stays Optional). list_partners()/list_partnerships()/join()/get_partnership_stats() return raw dicts by design (confirmed against the fixture, same reasoning as get_limits()/custom_domains.add()/webhooks.list_event_types() from the prior audit) — no change needed there. Open question flagged to awsys-orch rather than guessed at: the platform's create_program request fixture shows a single `commissionRate` field where this SDK sends commissionType/cpcRate/cpaRate — left unchanged pending confirmation, since restructuring that guess-first risked breaking a currently-working (if unverified) code path in a different way. Vendors sdk-contract.json 1.0.12. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014BLo12Xi5cjtEA5HiNb3y8
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
Follow-up to #7 (1.4.0 contract-parity), per the Gate 6 discussion with
awsys-orchabout issue #831/#833.utm_templates.list()was reading a field (utmTemplates) offGET /api/v1/methat the platform never actually populated — every call silently returned
[]. The platform's ADR-003 assumption (no dedicated list route existed) wasbased on incorrect information at the time. #833 added a real
GET /api/user/utm-templatesroute returning{templates: [...]};list()(sync + async) now calls it.
create()was already sending the correctsource/medium/campaignbodyfields — confirmed no change needed there. The 500 it used to get back
(#831) was a server-side bug (
uuidv4undefined), not a client-sidewire-format mismatch.
sdk-contract.json1.0.10: theutm_list_via_mescenario id wasrenamed to
utm_listto match the new route, andutm_create's expectedrequest body was corrected from
utmSource/utmMedium/utmCampaigntoplain
source/medium/campaign(matching what the SDK already sends andwhat the platform actually reads).
No breaking changes —
list()'s return type (List[UtmTemplate]) isunchanged, only its internal implementation.
Test plan
pytest -q(full suite incl. live staging) — 431 passed, 1 skipped, 10.7sruff check .— cleanmypy awsysco— cleanNote on merge
Per the standing agreement for this cross-SDK effort, my self-merge
authorization was scoped specifically to PR #7 — holding this one for
awsys-orch/Patrick's sign-off rather than auto-merging.Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
🤖 Generated with Claude Code
https://claude.ai/code/session_014BLo12Xi5cjtEA5HiNb3y8