Introduce DB migrations for ladder and pool-attachment tables and an
audit log for provision transitions. Make product_type nullable and add
lifecycle_status plus a product_kinds view. Implement Transition and
ReapplyDefaultsForPool primitives, SQLC queries/models, webhook and
Temporal workflow integration, and accompanying unit/integration tests.
Expose /webhooks/stripe as a public path (signature-verified)
Verify webhook signatures with ConstructEventWithOptions and
IgnoreAPIVersionMismatch=true, and log API version mismatches.
Start two Temporal workflows: stripe-webhook-processor and
stripe-outbox-poller; workflow start failures are non-fatal.
Add ConnectPlain to open the DB without the custom search_path and
switch migration and CLI flows to run on that plain connection.
Wrap multi-statement goose migrations with StatementBegin/End to
ensure statements are executed atomically. Move Stripe price outbox
seeding into a dedicated stripe migration.
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).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Describe that fedwiki.sites is not repopulated from existing site
directories after a DB reset, causing operator and member UIs to show
no sites. Add a note that the Keycloak seed script pins user IDs but
Keycloak may assign different UUIDs, breaking disk-to-IDP ownership
links (example: owner.json shows a different id than the pinned one).
Also add an issues entry that provider_configs should be an app-level
config (discovered during Stripe planning), and update the Future table
to
reference Milestone 4
Update prompts, skills, and .claude commands to invoke the
openspec-sync-specs skill via the Task tool. Bump skills'
generatedBy to 1.2.0 and apply minor copy edits (onboard preflight,
explore/ff wording, bulk-archive messaging)
Add a goose migration to create core and fedwiki schemas and move
existing
domain tables using ALTER TABLE IF EXISTS. Set connection search_path to
"core, public" after successful DB ping. Update FedWiki SQL and
sqlc.yaml to
use fedwiki.sites and include db migrations for schema awareness. Add
design
docs, specs, and tasks for schema-namespacing and the migration plan.
Introduce SafeTemplates.Render to execute templates into a buffer and
prevent partial HTML on errors. Replace direct ExecuteTemplate calls in
partial handlers and add a make lint-templates target to catch bypasses.
Update operator sites template/view model to use OwnerOrgName. Guard the
FedWiki sync by skipping inserts when DefaultWorkspaceID is empty and
scope deletes to the configured default workspace only.
- Add SQL queries and generated methods for Create/List/Update products
- Add CountWorkspacesByOrgID and ListResourceKeys querier methods
- Register workspace partials and operator routes for products and sets
- Add workspace UI section and operator tabs; tweak grant/site forms
- Replace isValidDNSLabel with validateDNSLabel for site validation
Mark Milestones 1 and 2 as complete and add Milestone 3
(UI/UX alignment) to the roadmap. Add a detailed UI/UX gap
analysis and operator/frontend action items. Note DNS label/FQDN
validation shortcomings and recommend purging the vestigial
IsMember view flag.
Add entitlement_sets and entitlement_set_rules with seed data and a
migration that backfills products, grants, and pool_provisions, then
removes product_entitlement_rules. Update Go models, sqlc queries,
materialization, and grant/provision flows to use entitlement_set_id.
Fix assembleMigrations to assign stable per-module numeric namespaces.
Move DB docs to docs/database-management.md and add design/specs/tests.
Reparent product_entitlement_rules into the entitlements module as
entitlement_set_rules and introduce entitlement_sets. Update schemas and
docs: products now reference entitlement_set_id; pool_provisions carry
entitlement_set_id instead of product_id; interfaces, counts, and
companion decisions adjusted accordingly.
SyncSitesToDBActivity passes an empty string to UpsertSiteByDomain,
causing an invalid UUID insertion that Postgres rejects. Either
configure
a valid DefaultWorkspaceID or make the activity skip/handle empty IDs
gracefully.
Implement isValidDNSLabel (RFC 1035/1123) in validate.go. Normalize
domain input (trim, lowercase) and enforce validation in CreateSite
handlers, returning 400 with explanatory error messages when invalid.