# Module: Azaion.Common.Entities.User ## Purpose Domain entity representing a system user, plus related value objects `UserConfig` and `UserQueueOffsets`. ## Public Interface ### User | Property | Type | Description | |----------|------|-------------| | `Id` | `Guid` | Primary key | | `Email` | `string` | Unique user email | | `PasswordHash` | `string` | SHA-384 hash of plaintext password | | `Hardware` | `string?` | Raw hardware fingerprint string (set on first resource access) | | `Role` | `RoleEnum` | Authorization role | | `CreatedAt` | `DateTime` | Account creation timestamp | | `LastLogin` | `DateTime?` | Last successful resource-check/hardware-check timestamp | | `UserConfig` | `UserConfig?` | JSON-serialized user configuration | | `IsEnabled` | `bool` | Account active flag | | Method | Signature | Description | |--------|-----------|-------------| | `GetCacheKey` | `static string GetCacheKey(string email)` | Returns cache key `"User.{email}"` | ### UserConfig | Property | Type | Description | |----------|------|-------------| | `QueueOffsets` | `UserQueueOffsets?` | Annotation queue offset tracking | ### UserQueueOffsets | Property | Type | Description | |----------|------|-------------| | `AnnotationsOffset` | `ulong` | Offset for annotations queue | | `AnnotationsConfirmOffset` | `ulong` | Offset for annotation confirmations | | `AnnotationsCommandsOffset` | `ulong` | Offset for annotation commands | ## Internal Logic `GetCacheKey` returns empty string for null/empty email to avoid cache key collisions. ## Dependencies - `RoleEnum` ## Consumers - All services (`UserService`, `AuthService`, `ResourcesService`) work with `User` - `AzaionDb` exposes `ITable` - `AzaionDbSchemaHolder` maps `User` to the `users` PostgreSQL table - `SetUserQueueOffsetsRequest` uses `UserQueueOffsets` ## Data Models Maps to PostgreSQL table `users` with columns: `id`, `email`, `password_hash`, `hardware`, `role`, `user_config` (JSON text), `created_at`, `last_login`, `is_enabled`. ## Configuration None. ## External Integrations None. ## Security `PasswordHash` stores SHA-384 hash. `Hardware` stores raw hardware fingerprint (hashed for comparison via `Security.GetHWHash`). ## Tests Indirectly tested via `UserServiceTest` and `SecurityTest`.