store: collapse migrations into a single schema.sql, drop legacy-owner path

Pre-production app, no need to preserve incremental migration history:
replace the 26 migration files with one current-state schema.sql (the
schema.sql comments are now the living documentation), simplify db.go to
apply it once instead of tracking/rebuilding through schema_migrations,
and make user_id NOT NULL everywhere now that there's no staged migration
to accommodate a nullable backfill window.

This removes the reason ClaimLegacyOwner/GENIUSRUN_LEGACY_OWNER_OIDC_SUB
existed (binding a pre-existing singleton-schema database to one account
across a staged migration), so that whole path is gone too -- the
existing dev database was wiped and reseeded fresh under the new schema.

Add cmd/dumpschema, which regenerates docs/DATABASE.md straight from the
live schema (via store.Open + sqlite_master introspection) so the
database documentation can never drift out of sync with reality.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 19:24:19 +02:00
parent 0f2101bce5
commit 644d87f1dc
37 changed files with 648 additions and 1100 deletions

View File

@@ -52,13 +52,6 @@ type Config struct {
SessionSecret []byte
SessionDuration time.Duration
SessionSecure bool
// LegacyOwnerOIDCSub, if set, is used exactly once at startup (via
// store.ClaimLegacyOwner) to bind this deployment's pre-existing
// single-tenant data to one named OIDC subject after upgrading to
// per-user profiles. Safe to leave set indefinitely -- ClaimLegacyOwner
// no-ops once any user already exists.
LegacyOwnerOIDCSub string
}
// Load reads configuration from environment variables, applying defaults
@@ -78,7 +71,6 @@ func Load() (Config, error) {
OIDCClientSecret: os.Getenv("GENIUSRUN_OIDC_CLIENT_SECRET"),
OIDCRequiredRole: getEnvDefault("GENIUSRUN_OIDC_REQUIRED_ROLE", "geniusrun-user"),
SessionDuration: getEnvDuration("GENIUSRUN_SESSION_DURATION", 720*time.Hour),
LegacyOwnerOIDCSub: os.Getenv("GENIUSRUN_LEGACY_OWNER_OIDC_SUB"),
}
if cfg.GarminTokenStoreRoot == "" {