# Data Model: Archive Curator ## Entities ### UserDirectory - **Fields**: id, name, absolute_path, relative_path, total_size_bytes, file_count, state, created_at, updated_at - **Validation**: - state MUST be one of Untagged, Whitelisted, Blacklisted, Kept - absolute_path MUST be within configured roots - relative_path MUST be stable and derived from root + name - **Relationships**: - has many MediaItem - has many DecisionRecord ### MediaItem - **Fields**: id, user_directory_id, absolute_path, relative_path, size_bytes, media_type, created_at - **Validation**: - absolute_path MUST be within parent directory - media_type MUST be one of image/video/other - **Relationships**: - belongs to UserDirectory - may appear in TriageQueue ### DirectoryState - **Fields**: user_directory_id, state, updated_at - **Validation**: - state MUST be one of Untagged, Whitelisted, Blacklisted, Kept - **Relationships**: - one-to-one with UserDirectory ### DecisionRecord - **Fields**: id, user_directory_id, decision_type, decision_scope, operator, preview_id, confirmed_at, outcome - **Validation**: - decision_type MUST be Keep or Delete - decision_scope MUST be Directory or File - **Relationships**: - belongs to UserDirectory - references PreviewAction ### PreviewAction - **Fields**: id, action_type, target_paths, list_file_changes_preview, created_at, expires_at - **Validation**: - action_type MUST be DirectoryDelete or FileDelete - target_paths MUST be within configured roots - **Relationships**: - linked to DecisionRecord on confirmation ### AuditEntry - **Fields**: id, timestamp, action_type, affected_paths, list_file_changes, outcome, preview_id - **Validation**: - action_type MUST match destructive or state-change actions - affected_paths MUST be within configured roots ### DownloadListEntry - **Fields**: raw_line, normalized_value, matched - **Validation**: - default matching is case-insensitive after trimming surrounding whitespace ### Configuration - **Fields**: untagged_root, whitelisted_root, kept_root, trash_root, download_list_path, audit_log_path, state_db_path, read_only_mode, hard_delete_enabled, excluded_patterns - **Validation**: - roots MUST be explicit and non-overlapping - read_only_mode MUST block all mutations ## State Transitions ### UserDirectory State - Untagged → Kept (keep decision; move to kept root) - Untagged → Blacklisted (delete decision, prior to deletion) - Untagged → Whitelisted (manual curation) - Whitelisted → Kept (explicit preserve; move to kept root) - Blacklisted → Deleted (after confirmation and action) ### Deletion Workflow - PreviewAction created (dry-run) - User confirms → DecisionRecord created - Action executed → AuditEntry appended ## Derived Views ### UntaggedCollage - **Fields**: user_directory_id, sample_media_items[], total_size_bytes, file_count ### WhitelistTriageItem - **Fields**: media_item_id, user_directory_id, size_bytes, media_type, relative_path