fix(seed): mark instance configured in e2e_seed so a prod→dev reseed skips setup

`siftlode seed-dev-from-prod` TRUNCATEs app_state (excluded from the data
allow-list as local/operational state), which dropped localdev back into the
first-run "Setup needed" gate and blocked login/UAT. e2e_seed runs at the end
of both `seed` and `seed-dev-from-prod` and always leaves a loginable admin, so
it now also flips app_state.configured=true (idempotent; the running api re-reads
and promotes its one-way cache, no restart needed).
This commit is contained in:
2026-08-08 01:01:16 +02:00
parent 1199bb0eaf
commit 97c584733a
+16
View File
@@ -24,6 +24,7 @@ from sqlalchemy import delete, func, select # noqa: E402
from app.db import SessionLocal # noqa: E402
from app.models import ( # noqa: E402
AppState,
Channel,
Playlist,
PlaylistItem,
@@ -46,6 +47,21 @@ def _now() -> datetime:
def main() -> None:
db = SessionLocal()
try:
# 0. Mark the instance configured so the first-run setup wizard is skipped. A prod→dev
# reseed (siftlode seed-dev-from-prod) TRUNCATEs app_state — it's excluded from the
# data allow-list, being local/operational state — which would otherwise drop the box
# back into "Setup needed" and block login/UAT. Since e2e_seed always leaves a loginable
# admin below, the instance is legitimately set up. Idempotent (mirrors state._row +
# state.mark_configured). The running api process caches `configured` one-way from False,
# so it re-reads the DB and promotes on the next request — no restart needed.
app_state = db.get(AppState, 1)
if app_state is None:
app_state = AppState(id=1, sync_paused=False)
db.add(app_state)
app_state.configured = True
app_state.setup_token_hash = None
db.commit()
# 1. Upsert the account and always reset it to a clean, loginable baseline
# (email_verified + is_active + not suspended + not demo + password set).
user = db.scalar(select(User).where(User.email == EMAIL))