fix: preserve billing response shape
This commit is contained in:
1 parent
600cba023c
commit
2ef3da7af5
7 files changed
+488
-6
No files matched your search
@@ -0,0 +1,87 @@
|
||||
# Task: Fix billing empty collection contract
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260817-fix-billing-empty-arrays-4f9d2a7c
|
||||
- Mode: Feature
|
||||
- Branch: main
|
||||
- Worktree: D:\Datas\OthersProjects\NianAIGC
|
||||
- Base commit: 600cba023ca39d6dd81e526ba1e6014d4bfad65b
|
||||
- Owner: codex
|
||||
- Status: Ready for Integration
|
||||
|
||||
## Scope
|
||||
|
||||
- Make Go billing overview responses encode empty collections as JSON arrays,
|
||||
never `null`.
|
||||
- Add frontend response-shape validation so malformed billing payloads produce
|
||||
an inline error instead of crashing the `/billing` route subtree.
|
||||
- Replace the obsolete `npm run db:migrate` route-error guidance with wording
|
||||
appropriate to the static Web + Go API architecture.
|
||||
- Add regression coverage at both the Go HTTP contract seam and the pure
|
||||
frontend payload parsing seam.
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- Preserve the accepted static Web + Go-only API architecture and existing
|
||||
authorization behavior.
|
||||
- Do not change database schema, seed fake organizations, or require production
|
||||
data to make empty-state rendering safe.
|
||||
- Keep the fix surgical: Go owns valid JSON output; frontend validation is a
|
||||
defense against incompatible or malformed deployments.
|
||||
- Work test-first from the deterministic diagnosis recorded in
|
||||
`20260817-diagnose-billing-page-7c3a91e2`.
|
||||
|
||||
## Outcome
|
||||
|
||||
- Go billing overview services now normalize every response collection used by
|
||||
the member and super-administrator billing pages to a non-nil slice, so an
|
||||
empty database result is encoded as `[]` rather than `null`.
|
||||
- The browser validates every billing object, collection element, and nested
|
||||
price dimension used by the renderer before committing API data to React
|
||||
state. Incompatible successful responses now produce the existing inline
|
||||
error state instead of throwing during render and activating the route error
|
||||
boundary. Validation preserves Go `omitempty` behavior for optional fields,
|
||||
including a fresh super-administrator without `organizationId`.
|
||||
- The billing route error boundary and invalid-JSON fallback now direct
|
||||
operators to the Go API status and server logs rather than the removed Node
|
||||
migration workflow.
|
||||
- Regression tests cover the real Go HTTP response contract with an empty store
|
||||
and the frontend parser contract for empty, missing, null, and malformed
|
||||
payloads.
|
||||
|
||||
## Verification
|
||||
|
||||
- RED: `go test ./internal/httpapi -run TestBillingOverviewResponsesEncodeEmptyCollectionsAsArrays -count=1`
|
||||
failed because empty member/admin collections encoded as `null`.
|
||||
- RED: `npx vitest run tests/billing-api-contract.test.ts` failed before the
|
||||
frontend parser module existed.
|
||||
- PASS: `go test ./...`.
|
||||
- PASS: `go vet ./...`.
|
||||
- Initial final review: FAIL because top-level array checks still allowed
|
||||
malformed collection elements such as `priceRules: [null]` and a null member
|
||||
`organization` to reach render-time property access.
|
||||
- Remediation: added complete render-shape validation and regressions for admin
|
||||
organizations/wallets, members, ledger entries, price rules/dimensions/tiers,
|
||||
and member organization/wallet/summary/personal data.
|
||||
- PASS after remediation: `npm test` (`54` files, `174` tests).
|
||||
- PASS: `npx tsc --noEmit --incremental false`.
|
||||
- PASS: `npm run deploy:check` (`7` ACK manifest files).
|
||||
- PASS: `npm run build` (all routes statically exported, including `/billing`).
|
||||
- PASS: `check_project_docs.py --target .`.
|
||||
- PASS: task-aware `check_doc_drift.py` for this task ID.
|
||||
- PASS: `git diff --check` (line-ending notices only).
|
||||
- Final read-only review: PASS on both Standards and Spec after the malformed
|
||||
nested-payload remediation; no blockers remain.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- After publishing new Web and Go images under a fresh immutable tag, verify an
|
||||
authenticated super-administrator with zero organizations sees the billing
|
||||
empty state in production. This requires deployment access and is not a code
|
||||
acceptance blocker.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- None. This task applies the existing static Web + Go API architecture and does
|
||||
not introduce a new architectural decision.
|
||||
Reference in new issue
Block a user