Files
NianAIGC/.project-docs/30-worklog/tasks/20260817-fix-billing-empty-arrays-4f9d2a7c.md
T

3.9 KiB

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: 600cba023c
  • 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.