Skip to content

feat: freeze app display name in billing mirror (migration 037)#49

Merged
I-am-nothing merged 1 commit into
mainfrom
feat/freeze-app-name
Jul 6, 2026
Merged

feat: freeze app display name in billing mirror (migration 037)#49
I-am-nothing merged 1 commit into
mainfrom
feat/freeze-app-name

Conversation

@I-am-nothing

Copy link
Copy Markdown
Contributor

Why

A deleted app's bill rows render as "未知的 App" (unknown app): billing-engine deliberately stored no app names, so the frontend resolved display names from the live app registry by app_id — which loses deleted apps. This freezes the name in the billing mirror so the bill is self-contained (the same "freeze at write time" pattern billing already uses for created_module_count and app_base_snapshots).

What (billing-engine — the foundation; api-platform + frontend follow)

  • Migration 037: ms_billing.apps.name (nullable) — stamped by RegisterApp, updated by SyncAppModules while live, never cleared on delete.
  • RPC: RegisterApp.Name (frozen on first registration, immutable across retries) + SyncAppModules.Name *string (rename while live; no-op once deleted via SetAppName … WHERE deleted_at IS NULL, same gate as SetAppModuleCount).
  • Bill responses: AccountAppBill and GetAppBillResponse gain name + a server-authoritative is_deleted flag. computeAppBill now reads the mirror unconditionally (hoisted out of the un-snapshotted branch) so name/deleted appear on charged periods too — the frontend reads is_deleted to open a charge-breakdown dialog for a deleted app instead of linking to the gone app page.
  • init-db.sql: wired migrations 029–037 (it was stuck at 028 — a fresh make db-init / CI / reset DB was missing the entire base-fee-v2 schema and 503'd every billing route; this closes that latent bug too).

Additive + back-compat: name stays NULL until api-platform sends it; an older api-platform is unaffected. Land this first, then api-platform, then frontend.

Verification

go build, go vet (incl. -tags integration), gofmt clean; unit + integration suites green — migrations 001→037 applied against real Postgres. New tests: name freeze lifecycle (register → live rename → freeze-on-delete) and the hoist guard (name + is_deleted on a charged/snapshotted period).

Follow-ons (this PR is step 1 of 3)

  • api-platform: pass the app name on the RegisterApp / SyncAppModules mirror-sync calls (sourced from the app record it already holds).
  • web-account BillSummaryCard.tsx: prefer the frozen name; branch the row on is_deleted — live app links as today, deleted app opens a web-ui-kit Dialog re-presenting the charge breakdown already in the AccountAppBill row (no new fetch).
  • mirrorstack-docs: add the migration 037 / apps.name entry (schema-docs convention).

🤖 Generated with Claude Code

A deleted app's bill rows rendered as "unknown app": billing-engine
deliberately held no app names, so the frontend resolved them from the
live app registry by app_id — which loses deleted apps. Freeze the name
in the mirror so the bill is self-contained (the same posture as
created_module_count / app_base_snapshots).

- Migration 037: ms_billing.apps.name (nullable), NEVER cleared on delete.
- RegisterApp stamps the name on first registration (frozen across
  retries via ON CONFLICT DO NOTHING); SyncAppModules updates it while
  the app is live and freezes it once deleted (SetAppName, WHERE
  deleted_at IS NULL — same gate as SetAppModuleCount).
- The account bill (AccountAppBill) and single-app bill (GetAppBillResponse)
  now carry `name` + a server-authoritative `is_deleted` flag. computeAppBill
  reads the mirror UNCONDITIONALLY (hoisted out of the un-snapshotted
  branch) so name/deleted show on charged periods too — the frontend uses
  is_deleted to show a deleted app's charges in a dialog instead of
  linking to the gone app page.
- Also wire migrations 029-037 into scripts/init-db.sql (it was stuck at
  028 — a fresh `make db-init` / CI / reset DB was missing the entire
  base-fee v2 schema, which 503'd every billing route).

Additive, back-compat: name stays NULL until api-platform sends it.
Unit + integration suites green (migrations 001->037, real Postgres).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@I-am-nothing I-am-nothing merged commit 572f37d into main Jul 6, 2026
1 check passed
@I-am-nothing I-am-nothing deleted the feat/freeze-app-name branch July 6, 2026 06:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant