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:
@@ -17,20 +17,8 @@ type User struct {
|
||||
CreatedAt string
|
||||
}
|
||||
|
||||
// CreateUser inserts a bare users row. Most callers want ProvisionUser
|
||||
// instead, which also seeds the profile/taxonomy/sync-state a fresh account
|
||||
// needs; CreateUser alone exists for ClaimLegacyOwner (Task 3), which
|
||||
// attaches an *existing* profile/taxonomy rather than seeding new ones.
|
||||
func (db *DB) CreateUser(ctx context.Context, oidcSub, displayName string) (int64, error) {
|
||||
res, err := db.ExecContext(ctx, `INSERT INTO users (oidc_sub, display_name) VALUES (?, ?)`, oidcSub, displayName)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("create user %q: %w", oidcSub, err)
|
||||
}
|
||||
return res.LastInsertId()
|
||||
}
|
||||
|
||||
// GetUserBySub looks up a user by their OIDC subject -- the only lookup key
|
||||
// the session-resolution middleware (Task 11) ever uses.
|
||||
// the session-resolution middleware ever uses.
|
||||
func (db *DB) GetUserBySub(ctx context.Context, oidcSub string) (User, bool, error) {
|
||||
var u User
|
||||
err := db.QueryRowContext(ctx, `SELECT id, oidc_sub, display_name, created_at FROM users WHERE oidc_sub = ?`, oidcSub).
|
||||
@@ -45,7 +33,7 @@ func (db *DB) GetUserBySub(ctx context.Context, oidcSub string) (User, bool, err
|
||||
}
|
||||
|
||||
// ListUsers returns every provisioned user, for the background incremental
|
||||
// sync loop (Task 13) to iterate.
|
||||
// sync loop to iterate.
|
||||
func (db *DB) ListUsers(ctx context.Context) ([]User, error) {
|
||||
rows, err := db.QueryContext(ctx, `SELECT id, oidc_sub, display_name, created_at FROM users ORDER BY id`)
|
||||
if err != nil {
|
||||
@@ -64,9 +52,9 @@ func (db *DB) ListUsers(ctx context.Context) ([]User, error) {
|
||||
return users, rows.Err()
|
||||
}
|
||||
|
||||
// neverMatchRule is the same placeholder every fresh install's rule-engine
|
||||
// kinds start with (migration 0004) -- every activity lands in needs_review
|
||||
// until the user tunes real rules.
|
||||
// neverMatchRule is the placeholder every fresh install's rule-engine kinds
|
||||
// start with -- every activity lands in needs_review until the user tunes
|
||||
// real rules.
|
||||
const neverMatchRule = `{"match":"all","conditions":[{"metric":"distance_meters","op":"<","value":0}]}`
|
||||
|
||||
// defaultWorkoutKindSeeds mirrors the 8 kinds migrations 0004/0007 seed for
|
||||
|
||||
Reference in New Issue
Block a user