// Sharing a resource with other people on this site. // // A resource was private to its author with no way out but the author's own // Nextcloud. A share is a row per (resource, person): the person can open, // preview and download it — not modify, re-skin or delete it — and the author // can withdraw it. shared_with_all opens a resource to every signed-in account // without naming them. // // Rows go with the resource and with the person: a deleted account leaves no // dangling grant, and a deleted resource leaves no orphan share. exports.up = pgm => pgm.sql(` ALTER TABLE user_resources ADD COLUMN IF NOT EXISTS shared_with_all BOOLEAN NOT NULL DEFAULT FALSE; CREATE TABLE IF NOT EXISTS user_resource_shares ( resource_id INTEGER NOT NULL REFERENCES user_resources(id) ON DELETE CASCADE, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, shared_by INTEGER REFERENCES users(id) ON DELETE SET NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), PRIMARY KEY (resource_id, user_id) ); CREATE INDEX IF NOT EXISTS idx_resource_shares_user ON user_resource_shares (user_id); `); exports.down = pgm => pgm.sql(` DROP TABLE IF EXISTS user_resource_shares; ALTER TABLE user_resources DROP COLUMN IF EXISTS shared_with_all; `);