CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) NOT NULL UNIQUE, username VARCHAR(255) NOT NULL, password_hash VARCHAR(255) NOT NULL, role VARCHAR(50) NOT NULL DEFAULT 'user', storage_used BIGINT NOT NULL DEFAULT 0, storage_quota BIGINT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE files ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, file_type VARCHAR(50) NOT NULL, mime_type VARCHAR(255), size BIGINT NOT NULL DEFAULT 0, owner_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, parent_id UUID REFERENCES files(id) ON DELETE CASCADE, path_depth INT NOT NULL DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT valid_path_depth CHECK (path_depth >= 0 AND path_depth <= 20) ); CREATE INDEX idx_files_parent_id ON files(parent_id); CREATE INDEX idx_files_owner_id ON files(owner_id); CREATE TABLE permissions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(50) NOT NULL UNIQUE, can_read BOOLEAN NOT NULL DEFAULT TRUE, can_write BOOLEAN NOT NULL DEFAULT FALSE, can_share BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE shares ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), file_id UUID NOT NULL REFERENCES files(id) ON DELETE CASCADE, owner_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, recipient_id UUID REFERENCES users(id) ON DELETE CASCADE, permission_id UUID NOT NULL REFERENCES permissions(id), access_key VARCHAR(255) NOT NULL UNIQUE, expires_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_shares_file_id ON shares(file_id); CREATE INDEX idx_shares_owner_id ON shares(owner_id); CREATE INDEX idx_shares_recipient_id ON shares(recipient_id); CREATE INDEX idx_shares_access_key ON shares(access_key); INSERT INTO permissions (name, can_read, can_write, can_share) VALUES ('viewer', TRUE, FALSE, FALSE), ('editor', TRUE, TRUE, FALSE), ('owner', TRUE, TRUE, TRUE);