ObjectStorageSchema now declares a foreign key for each join and table
possible value (fk_<table>_<column>): capabilities, folders, objects,
versions, references and usage cascade from their bucket or object;
object.folder_id and object_reference.object_id are set null; a bucket's
connection, its header and protection rules and the operation log
restrict. Each key is added by an idempotent DO block that first records
orphans in qqq_fk_quarantine and clears (nullable) or deletes (required)
them, so the same statements upgrade an existing schema. Three new
indexes back keys that had none.
PostgresIndexTest gains the guardrail (every relation has a database
foreign key with its rule, every key column leads an index), the
upgrade path with orphans run twice, and the delete paths the scan uses.
Builds on #19 (feature/object-id-indexes).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The folder -> objects, object -> versions and object -> references child
lists filter on the parent id alone, but every existing index on those
tables leads with bucket_id. The generated schema now adds
ix_object_storage_object_7 (folder_id), ix_object_storage_object_version_2
(object_id) and ix_object_storage_object_reference_3 (object_id). They are
appended, so existing generated index names keep their numbers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>