notXCS/migrations/0008_organizations.sql

57 lines
2.5 KiB
SQL

-- Organizations replace per-place shared access: every place belongs to an organization, and access
-- to it is determined by the caller's role/membership in that organization rather than by direct
-- ownership or one-off per-place grants (see the now-dropped place_access table, below).
CREATE TABLE IF NOT EXISTS organizations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
ownerId INTEGER,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY(ownerId) REFERENCES users(id)
);
-- Membership roles are scoped to the organization only (independent of the platform-wide role in
-- users.role): 1 = View (read-only), 2 = Edit (manage places/readers/ACL/access groups), 3 = Admin
-- (Edit, plus manage organization membership/roles and rename/delete the organization itself).
CREATE TABLE IF NOT EXISTS organization_members (
id INTEGER PRIMARY KEY AUTOINCREMENT,
orgId INTEGER NOT NULL,
userId INTEGER NOT NULL,
role INTEGER NOT NULL DEFAULT 1,
invitedBy INTEGER,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY(orgId) REFERENCES organizations(id),
FOREIGN KEY(userId) REFERENCES users(id),
FOREIGN KEY(invitedBy) REFERENCES users(id),
UNIQUE(orgId, userId)
);
CREATE INDEX IF NOT EXISTS idx_org_members_userId ON organization_members(userId);
CREATE INDEX IF NOT EXISTS idx_org_members_orgId ON organization_members(orgId);
ALTER TABLE places ADD COLUMN orgId INTEGER REFERENCES organizations(id);
-- Auto-create a default personal organization for every existing user.
INSERT INTO organizations (name, ownerId)
SELECT 'Personal (' || username || ')', id FROM users;
-- Make every user an Admin member of their own new default organization.
INSERT INTO organization_members (orgId, userId, role, invitedBy)
SELECT organizations.id, organizations.ownerId, 3, organizations.ownerId
FROM organizations;
-- Move every personally-owned place into its owner's new default organization.
UPDATE places
SET orgId = (SELECT id FROM organizations WHERE organizations.ownerId = places.ownerId)
WHERE ownerId IS NOT NULL;
-- Carry over any existing per-place shared access grants as Edit members of the place's new
-- organization, then drop the now-unused table - organizations replace this feature entirely.
INSERT OR IGNORE INTO organization_members (orgId, userId, role, invitedBy, createdAt)
SELECT places.orgId, place_access.userId, 2, place_access.grantedBy, place_access.createdAt
FROM place_access
JOIN places ON places.id = place_access.placeId
WHERE places.orgId IS NOT NULL;
DROP TABLE IF EXISTS place_access;