fix(postgres): BIGSERIAL ids for users/roles + widen User.id to i64
#22 in Riparion/arium — merged 2026-05-31
Summary
Two postgres-only fixes that together unblock the auth flow on the
postgres backend. Surfaced while running the riparion-cms docker
compose stack against a postgres sidecar.
1. users.id and roles.id: BIGINT PRIMARY KEY → BIGSERIAL PRIMARY KEY
The postgres init migrations mirrored the SQLite INTEGER PRIMARY KEY
shape with BIGINT PRIMARY KEY. That works in SQLite (the rowid alias
auto-generates) but fails on the first app-code INSERT in postgres:
ERROR: null value in column "id" of relation "users" violates not-null constraint
Switch both columns to BIGSERIAL PRIMARY KEY and call setval(...)
after the explicit-id seeds (guest user id=1; roles 1..3) so the
sequence advances past them — otherwise the first auto-generated id
would collide with the seeded row.
2. User.id: i32 → i64
auth::User.id and the inner SqlUser FromRow in auth::load_user
decoded the users.id column into i32. sqlx-sqlite is lenient about
integer widths and silently accepts the truncation; sqlx-postgres is
strict and returns a type-mismatch error. The error propagates up
through load_user, the auth layer treats the call as failed, and
every authenticated request falls back to the anonymous Guest.
End-user symptom: login form posts succeed (session row written with
the correct user_auth_session_id), but the UI never switches to
logged-in because every subsequent request fails to resolve the user.
Widen both fields to i64. The ~17 user.id as i64 casts scattered
across arium-dioxus / arium-leptos / arium-authz / arium become
no-ops and are removed to keep cargo clippy -- -D warnings happy
(clippy::unnecessary_cast).
Test plan
-
cargo check --no-default-features --features sqlite -p arium— clean -
cargo check --no-default-features --features postgres -p arium— clean -
cargo clippy --workspace ... --all-targets -- -D warnings— clean (matches CI) - Fresh postgres + apply patched migrations: user/role
INSERTwithout explicit id auto-generates; guestid=1preserved; sequence advances past seeded rows -
riparion-cmsdocker compose postgres overlay end-to-end: seed succeeds (3 users, 4 categories, 10 tags, 25 posts, 30 comments, 5 subscribers); admin login switches the UI to logged-in state - SQLite path unaffected — existing
dx-blog/riparion-cmsSQLite DBs continue to work (User.id: i64widening is lossless on the SQLite read side)
🤖 Generated with Claude Code
Last updated 2026-06-01
Links to this note
Merged pull requests, newest first.