Implement the ux-first-run change: a state-derived setup checklist on
/operator/setup with a landing region that recedes once required steps
are done, and empty states that distinguish blocked from empty across
operator and member surfaces. Also add production deployment and
environment reference docs, plus a config-key completeness test.
Replace product-kind branching and direct position writes with enclosed
database functions driven by structural product shape.
Migrate grant and provision data, unify operator issuance, update
subscription and expiry flows, and add migration and integration proofs.
Squash the pre-production migration history into fresh core, fedwiki,
and stripe baselines and reduce the canonical source list to those
three streams.
Update sqlc configs, generated queries, raw SQL, tests, and docs while
keeping provider tables schema-qualified.
BREAKING: existing local database volumes must be wiped because goose
version history restarts from the new baselines.
Add first-class default-price support: a product has a single default price
that readiness, the member catalog, and checkout all track.
- Migration 00016: is_default column + partial unique index (one default per
product) + backfill (oldest active price per product).
- New queries: GetDefaultPriceByProduct, ClearDefaultPrice, MarkDefaultPrice,
DeactivatePrice (guarded by is_default = FALSE).
- CreatePrice: first price for a product auto-becomes default (NOT EXISTS probe);
success copy differentiates auto-default from subsequent non-default prices.
- Per-row price affordances: Sync (posts price_id, hx-vals), Make default
(clear-then-set transaction), Deactivate (default-price guard).
- computePriceReadiness tracks the default price; resolvePurchasable documented
as the shared purchasability gate.
- SyncProductToStripe: selectable price (explicit price_id or default);
product-idempotent — product-synced guard prevents duplicate Stripe products.
- All error paths route through web.FieldErrorsFromDB (422) or slog+generic text,
never err.Error().
- Render tests for default badge, per-row affordance visibility, form-level
FieldErrors alert.
Closes: openspec/changes/multi-price-support
Drop redundant schema prefixes from all sqlc-generated Go types. Since
each module generates into its own package, the package already provides
the namespace — billing.Account is unambiguous without
billing.BillingAccount.
Changes:
- Add rename: blocks to all 6 sqlc.yaml files mapping schema-prefixed
names to clean idiomatic names (e.g. BillingBillingAccount → Account,
IdentityPerson → Person, OrganizationOrganization → Organization)
- Rename billing.billing_accounts → billing.accounts (table name
repeated
the schema; the schema already provides that context)
- Rename integration.integration_outbox → integration.outbox (same
reason)
- Regenerate all sqlc output across billing, identity, organization,
entitlements, stripe, and fedwiki modules
- Update all calling code (server, workflows, provisioning, tests) to
use
the new names
- Add internal/db/sqlc_schemas.sql — sqlc-only schema declarations so
every module can resolve schema-qualified names without including the
full db migrations
- Update docs/database-management.md with the naming convention and
standard sqlc.yaml template
Convention going forward: table names must not repeat the schema name;
generated types carry no schema prefix; the Go package provides the
namespace (like http.Request, not http.HttpRequest).