feat(db): add embedded auto-migrating schema system

Replace 4 independent schema management code paths (Docker shell
script, setup wizard pg_restore, test helpers, manual psql) with a
single migration runner embedded in the server binary.

The new server/migrations/ package uses Go embed to bundle all SQL
schemas. On startup, Migrate() creates a schema_version tracking
table, detects existing databases (auto-marks baseline as applied),
and runs pending migrations in transactions.

Key changes:
- Consolidated init.sql + 9.2-update + 33 patches into 0001_init.sql
- Setup wizard simplified to single "Apply schema" checkbox
- Test helpers use migrations.Migrate() instead of pg_restore
- Docker no longer needs schema volume mounts or init script
- Seed data (shops, events, gacha) embedded and applied via API
- Future migrations just add 0002_*.sql files — no manual steps
This commit is contained in:
Houmgaor
2026-02-23 21:19:21 +01:00
parent 6a7db47723
commit 27fb0faa1e
62 changed files with 4736 additions and 932 deletions

View File

@@ -122,9 +122,7 @@ h1{font-size:1.75rem;margin-bottom:.5rem;color:#e94560;text-align:center}
<p style="font-size:.85rem;color:#888;margin-bottom:1rem">Select which schema operations to perform.</p>
<div id="schema-options">
<label class="checkbox" id="chk-create-db-label"><input type="checkbox" id="chk-create-db" checked> Create database</label>
<label class="checkbox"><input type="checkbox" id="chk-init" checked> Apply init schema (pg_restore — required for new databases)</label>
<label class="checkbox"><input type="checkbox" id="chk-update" checked> Apply update schemas</label>
<label class="checkbox"><input type="checkbox" id="chk-patch" checked> Apply patch schemas (development patches)</label>
<label class="checkbox"><input type="checkbox" id="chk-schema" checked> Apply database schema (required for new databases)</label>
<label class="checkbox"><input type="checkbox" id="chk-bundled" checked> Apply bundled data (shops, events, gacha — recommended)</label>
</div>
<button class="btn btn-primary" id="btn-init-db" onclick="initDB()">Initialize Database</button>
@@ -208,9 +206,9 @@ function updateSchemaOptions() {
createCheck.disabled = false;
createLabel.style.opacity = '1';
}
// If tables already exist, uncheck init
// If tables already exist, uncheck schema (migrations will detect and skip)
if (dbTestResult && dbTestResult.tablesExist) {
document.getElementById('chk-init').checked = false;
document.getElementById('chk-schema').checked = false;
}
}
@@ -283,9 +281,7 @@ async function initDB() {
password: document.getElementById('db-password').value,
dbName: document.getElementById('db-name').value,
createDB: document.getElementById('chk-create-db').checked,
applyInit: document.getElementById('chk-init').checked,
applyUpdate: document.getElementById('chk-update').checked,
applyPatch: document.getElementById('chk-patch').checked,
applySchema: document.getElementById('chk-schema').checked,
applyBundled: document.getElementById('chk-bundled').checked,
})
});