# User Management ## 1. High-Level Overview **Purpose**: Full user lifecycle management — registration, credential validation, hardware binding, role changes, account enable/disable, and deletion. **Architectural Pattern**: Service layer — stateless business logic operating on the Data Layer through `IDbFactory`. **Upstream dependencies**: Data Layer (IDbFactory, ICache, User entity), Security & Cryptography (hashing). **Downstream consumers**: Admin API (endpoint handlers), Authentication (GetByEmail). ## 2. Internal Interfaces ### Interface: IUserService | Method | Input | Output | Async | Error Types | |--------|-------|--------|-------|-------------| | `RegisterUser` | `RegisterUserRequest, CancellationToken` | void | Yes | `BusinessException(EmailExists)` | | `ValidateUser` | `LoginRequest, CancellationToken` | `User` | Yes | `BusinessException(NoEmailFound, WrongPassword)` | | `GetByEmail` | `string? email, CancellationToken` | `User?` | Yes | `ArgumentNullException` | | `UpdateHardware` | `string email, string? hardware, CancellationToken` | void | Yes | None | | `UpdateQueueOffsets` | `string email, UserQueueOffsets, CancellationToken` | void | Yes | None | | `GetUsers` | `string? searchEmail, RoleEnum? searchRole, CancellationToken` | `IEnumerable` | Yes | None | | `CheckHardwareHash` | `User, string hardware, CancellationToken` | `string` (hash) | Yes | `BusinessException(HardwareIdMismatch)` | | `ChangeRole` | `string email, RoleEnum, CancellationToken` | void | Yes | None | | `SetEnableStatus` | `string email, bool, CancellationToken` | void | Yes | None | | `RemoveUser` | `string email, CancellationToken` | void | Yes | None | **Input DTOs**: ``` RegisterUserRequest: Email: string (required) — validated: min 8 chars, valid email format Password: string (required) — validated: min 8 chars Role: RoleEnum (required) LoginRequest: Email: string (required) Password: string (required) SetHWRequest: Email: string (required, validated: not empty) Hardware: string? (optional — null clears hardware) SetUserQueueOffsetsRequest: Email: string (required) Offsets: UserQueueOffsets (required) ``` ## 3. External API Specification N/A — exposed through Admin API component. ## 4. Data Access Patterns ### Queries | Query | Frequency | Hot Path | Index Needed | |-------|-----------|----------|--------------| | User by email (cached) | High | Yes | Yes | | User list with filters | Medium | No | No | | User insert (registration) | Low | No | No | | User update (hardware, role, config, status) | Medium | No | No | | User delete | Low | No | No | ### Caching Strategy | Data | Cache Type | TTL | Invalidation | |------|-----------|-----|-------------| | User by email | In-memory (via ICache) | 4 hours | After UpdateHardware, UpdateQueueOffsets, CheckHardwareHash (first login) | ## 5. Implementation Details **State Management**: Stateless — all state in PostgreSQL + in-memory cache. **Key Dependencies**: | Library | Version | Purpose | |---------|---------|---------| | FluentValidation | 11.10.0 | Request validation (auto-discovered) | **Error Handling Strategy**: - Domain errors thrown as `BusinessException` with specific `ExceptionEnum` codes. - `GetByEmail` throws `ArgumentNullException` for null/whitespace email. - Database errors propagate from `IDbFactory`. - Write operations use `RunAdmin` (admin connection); reads use `Run` (reader connection). ## 6. Extensions and Helpers | Helper | Purpose | Used By | |--------|---------|---------| | `Security.ToHash` | Password hashing (SHA-384) | RegisterUser, ValidateUser | | `Security.GetHWHash` | Hardware fingerprint hashing | CheckHardwareHash | | `QueryableExtensions.WhereIf` | Conditional LINQ filters | GetUsers | ## 7. Caveats & Edge Cases **Known limitations**: - No pagination on `GetUsers` — returns all matching users. - `CheckHardwareHash` auto-stores hardware on first access (no explicit admin approval step). - `RemoveUser` is a hard delete, not soft delete. **Potential race conditions**: - Concurrent `RegisterUser` calls with the same email: both could pass the existence check before insert. Mitigated by database unique constraint on email (if one exists). - `CheckHardwareHash` first-login path: concurrent requests could trigger multiple hardware updates. **Performance bottlenecks**: - `GetUsers` loads full user objects including `UserConfig` JSON; for large user bases, projection would be more efficient. ## 8. Dependency Graph **Must be implemented after**: Data Layer, Security & Cryptography. **Can be implemented in parallel with**: Resource Management. **Blocks**: Authentication (uses `GetByEmail`), Admin API. ## 9. Logging Strategy No explicit logging in UserService. ## Modules Covered - `Services/UserService` - `Common/Requests/LoginRequest` - `Common/Requests/RegisterUserRequest` - `Common/Requests/SetHWRequest` - `Common/Requests/SetUserQueueOffsetsRequest`