CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, username TEXT NOT NULL UNIQUE, email TEXT NOT NULL UNIQUE, api_key TEXT UNIQUE, storage_limit_bytes BIGINT DEFAULT 1073741824, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS buckets ( id SERIAL PRIMARY KEY, name TEXT NOT NULL UNIQUE, owner_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE, storage_used_bytes BIGINT DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS objects ( id BIGSERIAL PRIMARY KEY, bucket_id INT NOT NULL REFERENCES buckets(id) ON DELETE CASCADE, key TEXT NOT NULL, size_bytes BIGINT NOT NULL, content_type TEXT, last_modified TIMESTAMPTZ DEFAULT NOW(), version_id TEXT UNIQUE, md5_checksum TEXT, custom_metadata JSONB DEFAULT '{}', UNIQUE (bucket_id, key) ); CREATE INDEX IF NOT EXISTS idx_objects_bucket_id_key ON objects (bucket_id, key); CREATE INDEX IF NOT EXISTS idx_objects_bucket_id_last_modified ON objects (bucket_id, last_modified DESC); CREATE INDEX IF NOT EXISTS idx_objects_custom_metadata_gin ON objects USING GIN (custom_metadata);