refactor(BA-4080): add DB Source Pattern in User repository#8455
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors the UserRepository by extracting all DB session-opening logic into a new UserDBSource class, following the established db_source pattern used across other repository domains (e.g., AgentDBSource, ArtifactDBSource, DeploymentDBSource).
Changes:
- Created
UserDBSourceclass that handles all database operations with session management UserRepositorynow delegates pure DB methods toUserDBSourcewhile retaining resilience decorators- Test files updated to access internal methods through the new
_db_sourceattribute
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/ai/backend/manager/repositories/user/repository.py |
Refactored to delegate DB operations to UserDBSource, keeping only orchestration logic and resilience decorators |
src/ai/backend/manager/repositories/user/db_source/db_source.py |
New file containing all DB session-opening logic and data access operations extracted from UserRepository |
src/ai/backend/manager/repositories/user/db_source/__init__.py |
New module initialization file exporting UserDBSource |
tests/unit/manager/repositories/user/test_user_repository.py |
Updated test calls to _validate_user_access to access it through _db_source |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| return len(target_vfs) | ||
|
|
||
| async def delete_keypairs_with_valkey( |
There was a problem hiding this comment.
Similarly, this method takes ValkeyStatClient as a parameter because the original _delete_keypairs_with_valkey performed Valkey cleanup and DB deletion within a single transaction. Splitting them would change the transaction boundary — if Valkey cleanup fails, the DB transaction should roll back, which requires both operations to be in the same begin() scope.
| result = await conn.execute(query) | ||
| rows = result.fetchall() | ||
| # DB query via db_source | ||
| rows = await self._db_source.get_kernel_rows_for_monthly_stats(user_uuid) |
There was a problem hiding this comment.
Only the DB query part was extracted to db_source
Extract all DB session-opening logic from UserRepository into UserDBSource, following the established db_source pattern used in other repository domains. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The `except VFolderOperationFailed: raise` block has no effect and can be safely removed along with its unused import. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SQLAlchemy 2.0 properly infers scalar() return types, making explicit cast(Optional[str], result) redundant. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The method always returns True and is never called in production code. Remove it along with the 3 associated test cases. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove cast(list[VFolderRow], ...) and cast(Optional[UUID], ...) that are no longer needed with SQLAlchemy 2.0 type inference. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
a454479 to
1135c84
Compare
| await execute_batch_purger(session, create_user_error_log_purger(user_uuid)) | ||
| await execute_batch_purger(session, create_user_keypair_purger(user_uuid)) | ||
| await execute_batch_purger(session, create_user_vfolder_permission_purger(user_uuid)) | ||
| await execute_batch_purger(session, create_user_group_association_purger(user_uuid)) |
There was a problem hiding this comment.
Resolved merge conflict with purge_user from main, integrated into db_source pattern
|
Overall, there seems to be a lot of code that needs improvement, but it doesn’t seem appropriate to modify the existing code here. |
Summary
UserRepositoryintoUserDBSource, following the establisheddb_sourcepattern used across other repository domainsUserRepositorynow delegates pure DB methods toUserDBSourcewhile retaining resilience decorators and orchestration logicdelete_vfolders,delete_keypairs_with_valkey,_get_time_binned_monthly_stats) are restructured so that DB access is handled byUserDBSourcewith no behavioral changesRelated Issue
Test plan
pants checkpasses on all modified filespants lintpasses on all modified filestest_user_repository.py)🤖 Generated with Claude Code