GOO-415 · local stack · 2026-10-28

Per-org credit rollover: what was proven

The admin switch on the customer detail page was clicked in a real browser, and the result was checked in the gateway, the database and the logs. The allocation change is proven against real Postgres by the service tests. Only the Stripe webhook hop in front of it could not run locally.

Which hops were exercised

Admin toggle Switch (browser)→ Next proxy route→ Gateway PATCH + admin auth→ organizations row→ Reload reads it back
Monthly renewal Stripe webhook → gateway→ go-credits handler→ AllocateMonthlyCredits→ credit_ledger rows
exercised end to end, this run service test real Postgres, called directly not run no Stripe key locally

Part A: the admin switch PASS

Signed in through a Clerk dev sign-in token as the platform admin, at /admin/customers/036bb424-47ab-42ee-ba4c-0bbbc28a83ec, viewport 1600×1000.

StepWireDatabase
Page loadGET …/organizations/036bb424… 200, "credit_rollover_enabled":falsefPASS
Click onPATCH …/credit-rollover {"enabled":true} → 200 {"message":"Credit rollover updated"}t (20:42:34 UTC)PASS
ReloadGET returns true, switch aria-checked="true"tPASS
Click offPATCH …/credit-rollover {"enabled":false} → 200f (20:42:52 UTC)PASS
ReloadGET returns false, switch aria-checked="false"fPASS
Customer header with the rollover switch off on first load
First load: off
Customer header with the rollover switch on after clicking
After clicking: on
Customer header with the rollover switch still on after a reload
After a reload: still on
Customer header with the rollover switch off after turning it off and reloading
Turned off, reloaded: off

Gateway audit lines, verbatim (/tmp/main.log)

{"time":"2026-10-28T04:42:34.434842+08:00","severity":"INFO","message":"[Admin] <platform-admin email> set credit_rollover_enabled=true for org 036bb424-47ab-42ee-ba4c-0bbbc28a83ec","logging.googleapis.com/labels":{"service":"main"}}
{"time":"2026-10-28T04:42:52.741535+08:00","severity":"INFO","message":"[Admin] <platform-admin email> set credit_rollover_enabled=false for org 036bb424-47ab-42ee-ba4c-0bbbc28a83ec","logging.googleapis.com/labels":{"service":"main"}}

Earlier API checks against the same gateway: {} → 400 (the field is required), an unknown org → 404, and the field appears in both the customer list and the detail response.

Part B: the renewal allocation SERVICE TEST

The plan was to post a fabricated invoice.payment_succeeded to go-credits for two throwaway orgs. It stopped before any allocation: go-credits registers its Stripe routes only when STRIPE_API_KEY is set (cmd/main.go:41-44, 90-91), and no local env file sets one, so /api/v1/stripe/webhook answers 404. Nothing was worked around, and the two throwaway orgs were deleted.

The allocation itself is covered by the two tests in subscription_allocate_test.go, run against the migrated local Postgres:

--- PASS: TestAllocateMonthlyCredits_IdempotentOnInvoiceKey (0.19s)
--- PASS: TestAllocateMonthlyCredits_RolloverKeepsBalance (0.06s)
PASS
ok  	github.com/goodtake-ai/deimos/services/go-credits/internal/services	0.599s
CaseSeed balanceLedger writtenNew balance
Flag off (existing test)100expiry 100 → 0, then credit 0 → 1300; replay of the same invoice is a no-op1300
Flag on (new test)12.3456no expiry row; credit 12.3456 → 1312.34561312.3456

Each of the new test's three assertions was shown to fail on its own target bug: the rollover branch removed, the grant row left at 0, and the returned balance left at the plan amount.

Changed after this run

Not covered

Cleanup, re-queried