Files
gallery-organizer-web/specs/001-archive-curator/data-model.md
Danilo Reyes 070a3633d8 init
2026-02-07 06:01:29 -06:00

93 lines
3.0 KiB
Markdown

# 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