Files
admin/_docs/02_document/data_model.md
T
2026-04-16 06:25:36 +03:00

97 lines
3.5 KiB
Markdown

# Azaion Admin API — Data Model
## Entity-Relationship Diagram
```mermaid
erDiagram
USERS {
uuid id PK
varchar email "unique, not null"
varchar password_hash "not null"
text hardware "nullable"
varchar hardware_hash "nullable"
varchar role "not null (text enum)"
varchar user_config "nullable (JSON)"
timestamp created_at "not null, default now()"
timestamp last_login "nullable"
bool is_enabled "not null, default true"
}
```
The system has a single table (`users`). There are no foreign key relationships.
## Table: `users`
### Columns
| Column | Type | Nullable | Default | Description |
|--------|------|----------|---------|-------------|
| `id` | `uuid` | No | (application-generated) | Primary key, `Guid.NewGuid()` |
| `email` | `varchar(160)` | No | — | Unique user identifier |
| `password_hash` | `varchar(255)` | No | — | SHA-384 hash, Base64-encoded |
| `hardware` | `text` | Yes | null | Raw hardware fingerprint string |
| `hardware_hash` | `varchar(120)` | Yes | null | Defined in DDL but not used by application code |
| `role` | `varchar(20)` | No | — | Text representation of `RoleEnum` |
| `user_config` | `varchar(512)` | Yes | null | JSON-serialized `UserConfig` object |
| `created_at` | `timestamp` | No | `now()` | Account creation time |
| `last_login` | `timestamp` | Yes | null | Last hardware check / resource access time |
| `is_enabled` | `bool` | No | `true` | Account active flag |
### ORM Mapping (linq2db)
Column names are auto-converted from PascalCase to snake_case via `AzaionDbSchemaHolder`:
- `User.PasswordHash``password_hash`
- `User.CreatedAt``created_at`
Special mappings:
- `Role`: stored as text, converted to/from `RoleEnum` via `Enum.Parse`
- `UserConfig`: stored as nullable JSON string, serialized/deserialized via `Newtonsoft.Json`
### Permissions
| Role | Privileges |
|------|-----------|
| `azaion_reader` | SELECT on `users` |
| `azaion_admin` | SELECT, INSERT, UPDATE, DELETE on `users` |
| `azaion_superadmin` | Superuser (DB owner) |
### Seed Data
Two default users (from `env/db/02_structure.sql`):
| Email | Role |
|-------|------|
| `admin@azaion.com` | `ApiAdmin` |
| `uploader@azaion.com` | `ResourceUploader` |
## Schema Migration History
Schema is managed via SQL scripts in `env/db/`:
1. `00_install.sh` — PostgreSQL installation and configuration
2. `01_permissions.sql` — Role creation (superadmin, admin, reader)
3. `02_structure.sql` — Table creation + seed data
4. `03_add_timestamp_columns.sql` — Adds `created_at`, `last_login`, `is_enabled` columns
No ORM migration framework is used. Schema changes are applied manually via SQL scripts.
## UserConfig JSON Schema
```json
{
"QueueOffsets": {
"AnnotationsOffset": 0,
"AnnotationsConfirmOffset": 0,
"AnnotationsCommandsOffset": 0
}
}
```
Stored in the `user_config` column. Deserialized to `UserConfig``UserQueueOffsets` on read. Default empty `UserConfig` is created when the field is null or empty.
## Observations
- The `hardware_hash` column exists in the DDL but is not referenced in application code. The application stores the raw hardware string in `hardware` and computes hashes at runtime.
- No unique constraint on `email` column in the DDL — uniqueness is enforced at the application level (`UserService.RegisterUser` checks for duplicates before insert).
- `user_config` is limited to `varchar(512)`, which could be insufficient if queue offsets grow or additional config fields are added.