Skip to content

refactor(server): move the identity handlers' SQL into repositories - #47

Merged
fylorn merged 1 commit into
devfrom
refactor/server-identity-repositories
Sep 24, 2026
Merged

fylorn merged 1 commit into
devfrom
refactor/server-identity-repositories

Conversation

@fylorn

@fylorn fylorn commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Continues the repository migration started in #45, for the identity domain.

What moved

All 56 inline sqlx::query* statements in handlers/admin/users.rs (18), handlers/roles.rs (21) and handlers/teams.rs (17) now live in:

  • services::user_repository (extended) — user listing (global / team-scoped), per-user role and team joins, create, display name / active flags, soft delete, the api_keys cascades, a user's rbac_role_assignments.
  • services::role_repository (new) — rbac_roles CRUD and the role side of rbac_role_assignments (counts, members, reassign-on-delete). RoleRow and ROLE_SELECT move with it.
  • services::team_repository (new) — teams, team_members, team_role_assignments. Team, TeamWithCountRow and TeamRoleRow move with their queries (openapi.rs imports Team from there).

Every statement is carried over verbatim (same text, binds, fetch kind) — checked mechanically by comparing the evaluated SQL literals before and after. Handlers keep permission checks, validation, the super-admin quorum guard, audit and cache invalidation. Transactions that compose several statements with the quorum lock stay in the handler and pass &mut PgConnection down. Where a handler maps or swallows the raw sqlx error (FK/unique constraint names, unwrap_or_default/unwrap_or(0), a logged cascade failure, the team-membership check's own message), the repository returns sqlx::Error so the mapping — and the absence of the From<sqlx::Error> log line — is unchanged.

user_repository loses its #![allow(dead_code)] landing-zone header: the unused get_active / find_email are deleted, and soft_delete now is the statement delete_user actually runs.

No behaviour change: evidence

New crates/test-support/tests/admin_identity.rs (12 tests) covers what the suite didn't reach: user search with LIKE wildcards, pagination, team-scoped user/team listings, create with global + team-scoped roles / generated password / 409 / unknown role / bad scope, admin can't grant super_admin, PATCH role replacement and self-guard, disable → keys user_disabled, delete → keys user_deleted, role create/rename/description null-vs-absent/system rename refused, role members with scopes, delete role with reassign (all 400/404 branches), role history via ClickHouse, team get/update/delete (409/400/404), member cap of 10 + idempotent re-add + inactive user 404 + deleted users hidden, member self-read without teams:read, team role assign/list/remove.

The new tests pass against the original code (run before the move) and after it.

Checks

  • cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings, cargo clippy --workspace --lib -- -D warnings
  • cargo nextest run --workspace --lib --bins --tests — 687 passed
  • Full integration suite on local containers — 298/299; the one failure, streaming_and_cache::streaming_client_disconnect_emits_cancelled_gateway_log ("cancelled row never landed"), is a gateway timing test that passes when rerun alone and doesn't touch these handlers.

🤖 Generated with Claude Code

The users, roles and teams admin handlers carried 56 inline sqlx
statements. They now live in services::user_repository (extended),
services::role_repository and services::team_repository, each
statement carried over verbatim with the same binds and fetch kind.
Handlers keep permission checks, validation, the super-admin quorum
guard, audit and cache invalidation; transactions that compose several
statements stay in the handler and pass the connection down.

Where a handler maps or swallows a raw sqlx error (constraint names,
unwrap_or_default, a logged cascade failure), the repository returns
sqlx::Error so that mapping is unchanged. Team and TeamRoleRow move
with their queries. user_repository drops its dead-code allow and the
unused get_active / find_email; soft_delete now matches the statement
delete_user actually runs.

Adds crates/test-support/tests/admin_identity.rs (12 tests) covering
the endpoints and branches the suite didn't reach; it passes against
the code before and after the move.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@fylorn
fylorn force-pushed the refactor/server-identity-repositories branch from 8af3016 to ea810d0 Compare September 24, 2026 09:07
@fylorn
fylorn merged commit 1c80b83 into dev Sep 24, 2026
6 checks passed
@fylorn
fylorn deleted the refactor/server-identity-repositories branch September 24, 2026 09:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant