fix(postgres): BIGSERIAL ids for users/roles + widen User.id to i64

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 KEYBIGSERIAL 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: i32i64

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 INSERT without explicit id auto-generates; guest id=1 preserved; sequence advances past seeded rows
  • riparion-cms docker 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-cms SQLite DBs continue to work (User.id: i64 widening is lossless on the SQLite read side)

🤖 Generated with Claude Code

Last updated 2026-06-01