6.7 KiB
Favorites Handlers Authentication Refactor
Overview
This PRD outlines the plan to refactor all favorites handlers in libs/handlers/src/favorites/
to accept the complete AuthenticatedUser
object instead of just the user_id
parameter.
Problem Statement
Currently, favorites handlers accept only a user ID (Uuid
) as the user parameter. This approach has several limitations:
- It lacks rich user context information such as organization memberships and roles
- It requires additional database lookups to fetch user data within handlers
- It doesn't align with the REST endpoints which already use the
AuthenticatedUser
type from middleware
By refactoring these handlers to accept the complete AuthenticatedUser
object, we will:
- Improve code efficiency by reducing redundant database queries
- Enhance security by making permission checks more comprehensive
- Increase consistency across the codebase
- Improve test reliability with standardized test user fixtures
Goals
- Update all favorites handlers to use
AuthenticatedUser
instead of user ID - Ensure tests continue to pass with the new parameter format
- Optimize handler code to use available user context information
- Maintain backward compatibility with existing functionality
Non-Goals
- Changing the business logic of the favorites handlers
- Modifying database schemas
- Adding new features to favorites handlers
- Changing the API contract between handlers and consumers
Technical Design
Overview
The refactoring will involve updating function signatures across all favorites handlers to accept &AuthenticatedUser
instead of &Uuid
, and then modifying the internal logic to use user.id
instead of user_id
where appropriate.
Components to Modify
Favorites Handlers
list_favorites.rs
create_favorite.rs
update_favorites.rs
delete_favorite.rs
favorites_utils.rs
(if it contains any user-related functions)
Example Function Signature Changes
// Before
pub async fn list_favorites_handler(user_id: &Uuid) -> Result<Vec<FavoriteResponse>> {
// ...
}
// After
pub async fn list_favorites_handler(user: &AuthenticatedUser) -> Result<Vec<FavoriteResponse>> {
// ...
}
Key Implementation Details
For each handler, we'll:
- Update the function signature to accept
&AuthenticatedUser
instead of&Uuid
- Replace all instances of
user_id
withuser.id
in function body - Update database queries to filter by
user.id
instead ofuser_id
Example Implementation (for list_favorites.rs)
// Before
pub async fn list_favorites_handler(user_id: &Uuid) -> Result<Vec<FavoriteResponse>> {
let mut conn = get_pg_pool().get().await?;
// Get all favorites for this user
let favorites = user_favorites::table
.filter(user_favorites::user_id.eq(user_id))
.filter(user_favorites::deleted_at.is_null())
.order_by(user_favorites::updated_at.desc())
.load::<UserFavorite>(&mut conn)
.await
.map_err(|e| anyhow!("Failed to load favorites: {}", e))?;
// Convert to response format
let responses = favorites.into_iter()
.map(FavoriteResponse::from)
.collect();
Ok(responses)
}
// After
pub async fn list_favorites_handler(user: &AuthenticatedUser) -> Result<Vec<FavoriteResponse>> {
let mut conn = get_pg_pool().get().await?;
// Get all favorites for this user
let favorites = user_favorites::table
.filter(user_favorites::user_id.eq(user.id))
.filter(user_favorites::deleted_at.is_null())
.order_by(user_favorites::updated_at.desc())
.load::<UserFavorite>(&mut conn)
.await
.map_err(|e| anyhow!("Failed to load favorites: {}", e))?;
// Convert to response format
let responses = favorites.into_iter()
.map(FavoriteResponse::from)
.collect();
Ok(responses)
}
REST Endpoint Changes
REST endpoints will need minimal changes:
// Before
pub async fn list_favorites_route(
Extension(user): Extension<AuthenticatedUser>
) -> Result<ApiResponse<Vec<FavoriteResponse>>, ApiError> {
match list_favorites_handler(&user.id).await {
// ...
}
}
// After
pub async fn list_favorites_route(
Extension(user): Extension<AuthenticatedUser>
) -> Result<ApiResponse<Vec<FavoriteResponse>>, ApiError> {
match list_favorites_handler(&user).await {
// ...
}
}
Files to Modify
Handler Files
/libs/handlers/src/favorites/list_favorites.rs
/libs/handlers/src/favorites/create_favorite.rs
/libs/handlers/src/favorites/update_favorites.rs
/libs/handlers/src/favorites/delete_favorite.rs
/libs/handlers/src/favorites/favorites_utils.rs
(if applicable)
REST Endpoints
/src/routes/rest/routes/users/favorites/list_favorites.rs
/src/routes/rest/routes/users/favorites/create_favorite.rs
/src/routes/rest/routes/users/favorites/update_favorites.rs
/src/routes/rest/routes/users/favorites/delete_favorite.rs
Implementation Plan
Phase 1: Handler Refactoring
- ⏳ Update signature and implementation of all favorites handlers
- ⏳ Modify any utility functions that use user ID
- 🔜 Run tests to validate the changes
Phase 2: REST Endpoint Integration
- 🔜 Update REST endpoints to pass the full user object
- 🔜 Run integration tests to ensure everything works together
- 🔜 Fix any issues that emerge during testing
Testing Strategy
Unit Tests
- Each refactored handler will need updated tests
- Tests will use the new test utilities to create mock users
Integration Tests
- End-to-end tests to validate the complete flow
- Verify favorites operations for different user types
Test Cases
- User listing their favorites
- User creating a new favorite
- User updating their favorites
- User deleting a favorite
- Verifying that users can only access their own favorites
Rollback Plan
If issues arise during implementation:
- Revert affected handlers to original implementation
- Document specific issues for resolution in next attempt
Success Criteria
- All favorites handlers successfully accept
AuthenticatedUser
instead of just user ID - All tests pass with the new implementation
- REST endpoints work correctly with refactored handlers
- No regression in functionality or performance
Dependencies
- Completion of the test utilities for creating mock
AuthenticatedUser
objects middleware::AuthenticatedUser
struct fromlibs/middleware/src/types.rs
- Existing favorites handlers implementation
Timeline
Expected completion time: 1-2 days
This PRD depends on the completion of the test utilities PRD and can be implemented in parallel with other handler refactorings.