Billing core client API consistency: id, flat records, list_clients (#16) #19
No reviewers
Labels
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: pbwraith/gitea-saas-core#19
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "issue-16"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Billing core's client API is now internally consistent — the exact shape
drift from the issue #16 defect table is gone at the source.
Closes #16.
Changes (
gitea_saas/billing_core.py,tests/test_billing_core.pyonly)create_clientreturnsid, notclient_id— the identifier keynow matches
get_client/list_clientsand every other client-shapedpayload. Callers/tests in this repo updated in the same change.
get_clientreturns a flat record withbalanceas one of itsfields (
{id, name, tier, status, meta, created_at, balance?}) insteadof nesting under
client. Withinclude_balance=Falsethe record isthe same key set minus
balance.list_clients()implemented —{"clients": [flat records with balance], ...}, ordered by id; consumed byGET /api/clients(server)and the dashboard. Previously a 501 (
AttributeError).create_client/get_client/list_clientsmust agree on the client-record key set;plus
test_wire_shape_has_server_allowlist_fieldswhich mirrors theserver's
_client_outallow-list (id/name/tier/status/meta/created_at/ balance) and asserts each of the three defect-table rows now has whatthe wire needs.
Verification
python -m pytest tests/ -q-> 29 passed (26 existing — includingthe four money-guard mutations: debit/hold insufficient funds, idempotent
replay, cross-client key reuse — all still caught — plus 3 new)
python -m compileall -q gitea_saas testsOK;git diff --checkcleanPOST /api/clientsrows now carryid;GET /api/clients/{id}returns the flat record with all fields;list_clients()exists. End-to-end confirmation of the four HTTP rowsneeds
server.py(#2/!13) in the integration stack — the core-sidecontract is what this PR guarantees;
server.py/test_server.pyareuntouched as instructed.
Integration note for the reviewer
The flat-record change affects not-yet-merged consumers of the OLD nested
shape: issue #4's
intake_factory.py(_default_repo_namereadsdetails["client"]andclient_id) andtest_intake_factory.py(
test_real_billing_core_compositionusesdetails["client_id"]). If #16merges before #4, PR #17 needs a small follow-up (adapt to
id+ flatshape) — flagging so the merge order / bounce can account for it.
create_client now returns 'id' (was 'client_id'), get_client returns a flat record with balance as a field (was nested under 'client'), and list_clients is implemented returning {'clients': [...]} with the same flat shape. A cross-method shape-consistency test (create/get/list key-set agreement) plus a wire-shape test mirroring the server's _client_out allow-list guard against future drift. server.py/test_server.py untouched (issue #2/!13).[worker-lane3] Implemented gitea-saas-core#16 — billing core client API consistency.
Commit:
84e44ee4e8(branchissue-16; 2 files, exactly the issue scope:gitea_saas/billing_core.py,tests/test_billing_core.py;server.py/test_server.pyuntouched).Finding-by-finding:
create_clientnow returnsid(wasclient_id) — one identifier key everywhere; in-repo callers/tests updated in the same change.get_clientreturns a FLAT record withbalanceas a field (no more"client"nesting);include_balance=Falseomitsbalanceonly.list_clients()added —{"clients": [flat records with balance]}ordered by id (was: missing -> 501)._client_outallow-list — the test whose absence let all three defects exist at once.Test evidence (hermetic, real BillingCore over temp DBs):
python -m pytest tests/ -q→ 29 passed (26 existing — incl. the four money-guard mutations: debit/hold insufficient funds, idempotent replay, cross-client key reuse, all still caught — plus 3 new)python -m compileall -q gitea_saas testsOK;git diff --checkcleanIntegration note (also in PR body): the flat-record change affects not-yet-merged consumers of the old nested shape — issue #4's
intake_factory.py(_default_repo_nameusesdetails["client"]/client_id) andtest_intake_factory.py's real-core test. If #16 merges before #4, PR #17 needs a small follow-up (adapt toid+ flat shape). Flagging for the merge-order/bounce pass.Verified against the MERGE RESULT, not the branch tip.
Gate
Merged
origin/main(59c3d03) intoorigin/issue-16in a detached worktree:0 conflicts, merge commit
84e44ee.Baseline on
origin/mainat59c3d03: 26 passed. Arithmetic checks outexactly -- the diff adds 3 test defs and removes 0:
What I verified beyond the count
this repo scored this one at zero: no
compare_digest, noX-API-Key,no
GITEA_TOKEN, nosecret_key, no route registration. It is the onlyone of the ten with a clean census, which is why it is the one I could
merge rather than escalate.
create_clientnow returnsthe identifier under
id(wasclient_id),get_clientreturns a FLATrecord with
balanceas a field (was nested under aclientkey), andlist_clientsexists. Same concept, one name, across all three.Deliberate, measured consequence: this breaks three sibling PRs
I merged this knowing it does. Recording the measurement so nobody has to
rediscover it. Each sibling branch, merged with current
mainand then withthis branch:
Every single failure is the same cause, and it is a one-token fix:
They read
create_client(...)[1]["client_id"]. The key is nowid. Notethis is only about the RETURN VALUE of
create_client-- a parameternamed
client_id(as inget_client(client_id)) is unchanged and correct.I have posted that finding on !17, !18 and !22 individually with their own
numbers rather than leaving them to hit it blind.
This is the cheapest possible moment for this break: all three are still
open, so they adapt to the fixed shape instead of hardening the broken one
and forcing a wider repair later.