12 KiB
Iron Database Schema
1. Overview
This document defines the initial SQLite schema for Iron MVP.
Goals:
- support a single logical file namespace
- separate logical metadata from physical storage placement
- track replicas and background jobs durably
- support
tusresumable uploads - keep the schema portable enough for future migration to PostgreSQL
Conventions:
- IDs are stored as
TEXT - timestamps are stored as UTC datetimes
- soft delete is preferred for logical user-facing entities in MVP
- provider-specific details belong in JSON columns only when no stable relational shape exists
2. Entity Overview
Main tables:
usersauth_sessionsdirectoriesfile_entriesfile_versionsblobsblob_replicasbackendsupload_sessionsupload_session_partsjobsplacement_policiespreview_artifactscache_entries
3. Table Definitions
3.1 users
Purpose:
- local gateway login identity
Columns:
idTEXT PRIMARY KEYusernameTEXT NOT NULL UNIQUEpassword_hashTEXT NOT NULLcreated_atDATETIME NOT NULLupdated_atDATETIME NOT NULL
3.2 auth_sessions
Purpose:
- persisted login sessions for bearer-token auth
Columns:
idTEXT PRIMARY KEYuser_idTEXT NOT NULL REFERENCESusers(id)token_hashTEXT NOT NULL UNIQUEexpires_atDATETIME NOT NULLrevoked_atDATETIME NULLcreated_atDATETIME NOT NULLupdated_atDATETIME NOT NULL
Indexes:
idx_auth_sessions_user_statuson (user_id,revoked_at,expires_at)- unique
idx_auth_sessions_token_hashontoken_hash
Notes:
- raw session tokens should never be stored directly
- the current implementation stores a SHA-256 token hash and returns the raw bearer token only at login time
3.3 directories
Purpose:
- logical folder hierarchy
Columns:
idTEXT PRIMARY KEYparent_idTEXT NULL REFERENCESdirectories(id)nameTEXT NOT NULLpath_keyTEXT NOT NULL UNIQUEcreated_atDATETIME NOT NULLupdated_atDATETIME NOT NULLdeleted_atDATETIME NULL
Constraints:
- unique sibling name constraint should be enforced in application logic or by an additional composite unique index later
Indexes:
idx_directories_parent_idonparent_ididx_directories_path_keyonpath_key
3.4 file_entries
Purpose:
- logical files visible to users
Columns:
idTEXT PRIMARY KEYdirectory_idTEXT NOT NULL REFERENCESdirectories(id)nameTEXT NOT NULLmime_typeTEXT NULLsize_bytesINTEGER NOT NULLcurrent_version_idTEXT NULLis_deletedBOOLEAN NOT NULL DEFAULT 0deleted_atDATETIME NULLcreated_atDATETIME NOT NULLupdated_atDATETIME NOT NULL
Constraints:
- unique active filename per directory
Indexes:
- unique
idx_file_entries_directory_nameon (directory_id,name,is_deleted) idx_file_entries_current_version_idoncurrent_version_ididx_file_entries_deleted_atondeleted_at
Notes:
- file deletion uses recycle-bin semantics in MVP
- active and deleted files may temporarily share the same logical name in one directory because the uniqueness rule only protects active entries
3.5 file_versions
Purpose:
- immutable snapshots of file content
Columns:
idTEXT PRIMARY KEYfile_entry_idTEXT NOT NULL REFERENCESfile_entries(id)content_hashTEXT NOT NULLsize_bytesINTEGER NOT NULLstorage_layoutTEXT NOT NULLcreated_atDATETIME NOT NULL
Recommended enum values:
singlechunked
Indexes:
idx_file_versions_file_entry_idonfile_entry_ididx_file_versions_content_hashoncontent_hash
3.5 blobs
Purpose:
- physical storage units referenced by file versions
Columns:
idTEXT PRIMARY KEYfile_version_idTEXT NOT NULL REFERENCESfile_versions(id)blob_indexINTEGER NOT NULLkindTEXT NOT NULLcontent_hashTEXT NOT NULLsize_bytesINTEGER NOT NULLlogical_offsetINTEGER NOT NULL DEFAULT 0created_atDATETIME NOT NULL
Recommended enum values:
filechunkthumbnailposter
Indexes:
- unique
idx_blobs_file_version_indexon (file_version_id,blob_index) idx_blobs_content_hashoncontent_hash
3.6 blob_replicas
Purpose:
- one row per physical copy of a blob on one backend
Columns:
idTEXT PRIMARY KEYblob_idTEXT NOT NULL REFERENCESblobs(id)backend_idTEXT NOT NULL REFERENCESbackends(id)storage_keyTEXT NOT NULLstatusTEXT NOT NULLetagTEXT NULLchecksumTEXT NULLsize_bytesINTEGER NOT NULLlast_verified_atDATETIME NULLcreated_atDATETIME NOT NULLupdated_atDATETIME NOT NULL
Recommended enum values:
pendingreadymissingcorruptofflinefailed
Indexes:
- unique
idx_blob_replicas_blob_backendon (blob_id,backend_id) idx_blob_replicas_backend_statuson (backend_id,status)idx_blob_replicas_storage_keyonstorage_key
Current implementation status:
- local backend writes now create
blob_replicasrows during upload finalize - initial persisted replica status is
ready
3.7 backends
Purpose:
- configured storage targets and their policy attributes
Columns:
idTEXT PRIMARY KEYnameTEXT NOT NULL UNIQUEtypeTEXT NOT NULLstability_classTEXT NOT NULLread_priorityINTEGER NOT NULLwrite_priorityINTEGER NOT NULLis_enabledBOOLEAN NOT NULL DEFAULT 1config_jsonTEXT NOT NULLcapacity_hint_bytesINTEGER NULLlast_health_statusTEXT NULLlast_health_checked_atDATETIME NULLcreated_atDATETIME NOT NULLupdated_atDATETIME NOT NULL
Recommended type values:
locals3
3.8 placement_policies
Purpose:
- persist file-class placement intent separately from backend rows
Columns:
idTEXT PRIMARY KEYfile_classTEXT NOT NULL UNIQUErequire_localBOOLEAN NOT NULL DEFAULT 1stable_replica_countINTEGER NOT NULL DEFAULT 1opportunistic_replica_countINTEGER NOT NULL DEFAULT 0preferred_backend_ids_jsonTEXT NOT NULL DEFAULT[]excluded_backend_ids_jsonTEXT NOT NULL DEFAULT[]max_non_local_size_bytesINTEGER NULLcreated_atDATETIME NOT NULLupdated_atDATETIME NOT NULL
Notes:
- the current backend persists preferred and excluded backend ids as JSON lists
max_non_local_size_bytescan force large files to remain local-only even when stable backends exist- this table is actively used by reconcile jobs and by
/api/policies/placement/preview aliyunbaidubridge
Recommended stability_class values:
localstableopportunistic
Indexes:
idx_backends_enabledonis_enabledidx_backends_priorityon (write_priority,read_priority)
Current implementation status:
- the gateway currently bootstraps one default local backend record automatically
3.8 upload_sessions
Purpose:
- durable record for
tusupload lifecycle
Columns:
idTEXT PRIMARY KEYdirectory_idTEXT NULL REFERENCESdirectories(id)filenameTEXT NULLtotal_size_bytesINTEGER NOT NULLreceived_size_bytesINTEGER NOT NULLstatusTEXT NOT NULLtemp_pathTEXT NOT NULLtus_upload_urlTEXT NULLupload_metadata_jsonTEXT NULLcreated_atDATETIME NOT NULLupdated_atDATETIME NOT NULL
Recommended enum values:
createduploadinguploadedfinalizingfinalizedfailedexpired
Indexes:
idx_upload_sessions_statusonstatusidx_upload_sessions_updated_atonupdated_at
3.9 upload_session_parts
Purpose:
- optional upload-part detail for resumable recovery and diagnostics
Columns:
idTEXT PRIMARY KEYupload_session_idTEXT NOT NULL REFERENCESupload_sessions(id)part_numberINTEGER NOT NULLbyte_offsetINTEGER NOT NULLsize_bytesINTEGER NOT NULLchecksumTEXT NULLstatusTEXT NOT NULLcreated_atDATETIME NOT NULLupdated_atDATETIME NOT NULL
Indexes:
- unique
idx_upload_session_parts_uniqueon (upload_session_id,part_number) idx_upload_session_parts_upload_idonupload_session_id
3.10 jobs
Purpose:
- durable background task queue
Columns:
idTEXT PRIMARY KEYkindTEXT NOT NULLstatusTEXT NOT NULLpayload_jsonTEXT NOT NULLattempt_countINTEGER NOT NULL DEFAULT 0max_attemptsINTEGER NOT NULL DEFAULT 5run_afterDATETIME NOT NULLlast_errorTEXT NULLcreated_atDATETIME NOT NULLupdated_atDATETIME NOT NULL
Recommended enum values:
- kinds:
replicate_blob,generate_thumbnail,verify_replica,repair_blob,health_check_backend - status:
queued,running,succeeded,failed,dead
Indexes:
idx_jobs_status_run_afteron (status,run_after)idx_jobs_kind_statuson (kind,status)
3.11 preview_artifacts
Purpose:
- preview resources such as thumbnails and poster images
Columns:
idTEXT PRIMARY KEYfile_version_idTEXT NOT NULL REFERENCESfile_versions(id)artifact_typeTEXT NOT NULLblob_idTEXT NOT NULL REFERENCESblobs(id)statusTEXT NOT NULLcreated_atDATETIME NOT NULLupdated_atDATETIME NOT NULL
Recommended enum values:
thumbnailposterpdf_preview
Indexes:
- unique
idx_preview_artifacts_version_typeon (file_version_id,artifact_type)
3.12 cache_entries
Purpose:
- local cache state for blobs and derivatives
Columns:
idTEXT PRIMARY KEYblob_idTEXT NOT NULL REFERENCESblobs(id)local_pathTEXT NOT NULLcache_kindTEXT NOT NULLsize_bytesINTEGER NOT NULLstatusTEXT NOT NULLlast_accessed_atDATETIME NOT NULLexpires_atDATETIME NULLcreated_atDATETIME NOT NULLupdated_atDATETIME NOT NULL
Recommended enum values:
- cache kinds:
blob,preview,temp - status:
ready,partial,evicted,invalid
Indexes:
idx_cache_entries_blob_idonblob_ididx_cache_entries_last_accessed_atonlast_accessed_atidx_cache_entries_expires_atonexpires_at
4. Relationship Summary
- one
directoryhas many childdirectories - one
directoryhas manyfile_entries - one
file_entryhas manyfile_versions - one
file_versionhas manyblobs - one
blobhas manyblob_replicas - one
backendhas manyblob_replicas - one
upload_sessionmay become onefile_entry - one
jobtargets one logical task payload
5. Migration Guidance
Recommended migration order:
usersdirectoriesfile_entriesfile_versionsbackendsblobsblob_replicasupload_sessionsupload_session_partsjobsplacement_policiespreview_artifactscache_entries
Guidelines:
- create foreign keys only after referenced tables exist
- add indexes in the same migration as table creation where practical
- keep enum values in application constants for SQLite MVP
6. SQLite Notes
- enable foreign keys explicitly
- use WAL mode for better concurrent read behavior
- keep transactions short around upload finalization and job claiming
- avoid long-lived write transactions during file streaming
7. Future Schema Evolution
Likely future additions:
file_tagsshare_linksdevice_clientssync_rulessearch_documentsbackend_metricsreplica_verification_events
Likely future changes:
- introduce true version history controls
- move some JSON config into typed backend-specific tables if the surface becomes stable
- expand
placement_policiesif policy shape grows beyond file-class controls, preferred/excluded backend sets, and size-aware replica caps