## Summary - Add `is_admin` column to users table with Alembic migration and a `require_admin` FastAPI dependency that protects all admin-facing write endpoints (games, pokemon, evolutions, bosses, routes CRUD) - Expose admin status to frontend via user API and update AuthContext to fetch/store `isAdmin` after login - Make navigation menu auth-aware (different links for logged-out, logged-in, and admin users) and protect frontend routes with `ProtectedRoute` and `AdminRoute` components, preserving deep-linking through redirects - Fix test reliability: `drop_all` before `create_all` to clear stale PostgreSQL enums from interrupted test runs - Fix test auth: add `admin_client` fixture and use valid UUID for mock user so tests pass with new admin-protected endpoints ## Test plan - [x] All 252 backend tests pass - [ ] Verify non-admin users cannot access admin write endpoints (games, pokemon, evolutions, bosses CRUD) - [ ] Verify admin users can access admin endpoints normally - [ ] Verify navigation shows correct links for logged-out, logged-in, and admin states - [ ] Verify `/admin/*` routes redirect non-admin users with a toast - [ ] Verify `/runs/new` and `/genlockes/new` redirect unauthenticated users to login, then back after auth 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: #67 Co-authored-by: Julian Tabel <juliantabel.jt@gmail.com> Co-committed-by: Julian Tabel <juliantabel.jt@gmail.com>
2.0 KiB
title, status, type, priority, created_at, updated_at
| title | status | type | priority | created_at | updated_at |
|---|---|---|---|---|---|
| Fix stale PostgreSQL enum causing test failures | completed | bug | normal | 2026-03-21T10:27:53Z | 2026-03-21T10:29:33Z |
Problem
The backend smoke tests fail with:
sqlalchemy.exc.DBAPIError: invalid input value for enum run_visibility: "public"
This happens during Base.metadata.create_all in the engine fixture (backend/tests/conftest.py:27).
Root Cause
The engine fixture only calls create_all during setup and drop_all during teardown. If a previous test run was interrupted before teardown, the run_visibility PostgreSQL enum type persists in the test database with stale/incorrect values. On the next run, create_all (with checkfirst=True default) sees the enum exists and skips recreating it, but the existing enum lacks valid values, causing the DEFAULT 'public' to fail.
PostgreSQL native enum types are not automatically dropped with DROP TABLE — they require explicit DROP TYPE.
Fix
In the engine fixture at backend/tests/conftest.py:23-31, add Base.metadata.drop_all before create_all to ensure a clean slate:
@pytest.fixture(scope="session")
async def engine():
eng = create_async_engine(TEST_DATABASE_URL, echo=False)
async with eng.begin() as conn:
await conn.run_sync(Base.metadata.drop_all) # <-- add this
await conn.run_sync(Base.metadata.create_all)
yield eng
async with eng.begin() as conn:
await conn.run_sync(Base.metadata.drop_all)
await eng.dispose()
Checklist
- Add
drop_allbeforecreate_allin theenginefixture (backend/tests/conftest.py) - Verify tests pass with
pytest backend/tests/test_smoke.py
Summary of Changes
Added drop_all before create_all in the test engine fixture to ensure stale PostgreSQL enum types are cleared before recreating the schema. This prevents test failures when a previous test run was interrupted before cleanup.