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 <[email protected]>
@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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant