Files
pad/internal/server/testdata/cloud_contract/admin_user_by_id.json
T
xarmian 772c1a86ba feat(cloud): the Stripe customer link is compare-and-set, and readable by user (TASK-3549) (#2027)
* feat(cloud): the Stripe customer link is compare-and-set, and readable by user (TASK-3549)

POST /admin/stripe-customer-id no longer replaces a DIFFERENT stored
customer: it answers 409 stripe_customer_conflict with
details.stored_customer_id. The same id again is idempotent. Overwriting
the link is how a second checkout orphaned the first customer's
subscription (still charging, its events finding no user). An admin USER
may still replace with replace:true; the cloud secret alone cannot.

GET /admin/user-by-id (cloud secret or admin) returns user_id, email, plan
and stripe_customer_id, so the sidecar reads the stored customer before it
writes one (an older pad still overwrites) and can compare a webhook's
customer with it. Added to the cloud-admin allow-list, rate limiter,
compress census (no secret) and the cloud-only admin route list.

* test(cloud): golden user-by-id and the compare-and-set answers pad-cloud decodes (TASK-3549)

The contract shaper keeps "code" values verbatim: pad-cloud branches on
stripe_customer_conflict, so a placeholder there would hand it a golden
it cannot decode.

Claude-Session: https://claude.ai/code/session_01FAVXA5mJ5BNhKmv95jxQkQ
2026-10-10 15:59:17 -04:00

7 lines
109 B
JSON

{
"email": "<string>",
"plan": "<string>",
"stripe_customer_id": "<string>",
"user_id": "<string>"
}