refactor(server): move the identity handlers' SQL into repositories - #47
Merged
Merged
Conversation
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
force-pushed
the
refactor/server-identity-repositories
branch
from
September 24, 2026 09:07
8af3016 to
ea810d0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Continues the repository migration started in #45, for the identity domain.
What moved
All 56 inline
sqlx::query*statements inhandlers/admin/users.rs(18),handlers/roles.rs(21) andhandlers/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, theapi_keyscascades, a user'srbac_role_assignments.services::role_repository(new) —rbac_rolesCRUD and the role side ofrbac_role_assignments(counts, members, reassign-on-delete).RoleRowandROLE_SELECTmove with it.services::team_repository(new) —teams,team_members,team_role_assignments.Team,TeamWithCountRowandTeamRoleRowmove with their queries (openapi.rsimportsTeamfrom 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 PgConnectiondown. 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 returnssqlx::Errorso the mapping — and the absence of theFrom<sqlx::Error>log line — is unchanged.user_repositoryloses its#![allow(dead_code)]landing-zone header: the unusedget_active/find_emailare deleted, andsoft_deletenow is the statementdelete_useractually 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 → keysuser_disabled, delete → keysuser_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 withoutteams: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 warningscargo nextest run --workspace --lib --bins --tests— 687 passedstreaming_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