# Phase 1 Design: Data Model (046) ## Entities ### InventorySyncRun Existing table: `inventory_sync_runs` **Purpose**: Observable record of one inventory sync execution for a tenant + selection. **Existing fields (selected)** - `id` - `tenant_id` (FK) - `selection_hash` (sha256) - `selection_payload` (jsonb) - `status` (`running|success|partial|failed|skipped`) - `had_errors` (bool) - `error_codes` (jsonb) - `error_context` (jsonb) - `started_at`, `finished_at` - `items_observed_count`, `items_upserted_count`, `errors_count` **Planned additions (to satisfy FR-008)** - `user_id` (nullable FK to `users.id`) - Meaning: initiator of the run (UI-triggered). `null` allowed for system/scheduled runs. **Relationships** - `InventorySyncRun belongsTo Tenant` - `InventorySyncRun belongsTo User` (new, nullable) **Validation rules (selection payload)** - `policy_types`: list of strings; filtered through `PolicyTypeResolver::filterRuntime(...)` - `categories`: list of strings (optional; currently not used for the UI-triggered “full inventory” run) - `include_foundations`: boolean - `include_dependencies`: boolean ### BulkOperationRun Existing table: `bulk_operation_runs` **Purpose**: Generic progress tracking for background operations. Used by the bottom-right progress widget. **Relevant fields** - `tenant_id`, `user_id` - `resource`, `action` (used for display) - `status` (`pending|running|completed|completed_with_errors|failed|aborted`) - Counters: `total_items`, `processed_items`, `succeeded`, `failed`, `skipped` - `audit_log_id` (FK) **Usage for Inventory Sync** - `resource = 'inventory'`, `action = 'sync'` - `total_items = 1` - `item_ids = [selection_hash]` (or `[inventory_sync_run_id]` after creation) ### AuditLog Existing table: `audit_logs` **Purpose**: Immutable audit trail with actor identity snapshot. **Usage for Inventory Sync** - Emit `inventory.sync.dispatched` and a terminal event like `inventory.sync.completed` / `inventory.sync.failed`. - `resource_type = 'inventory_sync_run'`, `resource_id = (string) $run->id` - Actor fields filled from authenticated user. ## State transitions ### InventorySyncRun - `running` → `success|partial|failed` - `running` → `skipped` (lock/concurrency) ### BulkOperationRun - `pending` → `running` → `completed|completed_with_errors|failed|aborted`