181 lines
6.9 KiB
SQL
181 lines
6.9 KiB
SQL
-- +goose Up
|
|
|
|
CREATE TYPE instance_mode AS ENUM ('personal', 'organizational');
|
|
CREATE TYPE instance_access AS ENUM ('local', 'remote');
|
|
CREATE TYPE instance_protocol AS ENUM ('http', 'https');
|
|
CREATE TYPE workspace_kind AS ENUM ('organization', 'department', 'team', 'project');
|
|
CREATE TYPE membership_role AS ENUM ('owner', 'admin', 'member');
|
|
|
|
CREATE TABLE IF NOT EXISTS installations (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
singleton BOOLEAN NOT NULL DEFAULT TRUE UNIQUE,
|
|
mode instance_mode NOT NULL,
|
|
access instance_access NOT NULL,
|
|
protocol instance_protocol NOT NULL DEFAULT 'http',
|
|
host TEXT NOT NULL,
|
|
is_bootstrapped BOOLEAN NOT NULL DEFAULT FALSE,
|
|
bootstrapped_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
email TEXT NOT NULL,
|
|
display_name TEXT NOT NULL,
|
|
password_hash TEXT NOT NULL,
|
|
is_instance_admin BOOLEAN NOT NULL DEFAULT FALSE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email_unique ON users (LOWER(email));
|
|
|
|
CREATE TABLE IF NOT EXISTS user_homes (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL UNIQUE REFERENCES users(id) ON DELETE CASCADE,
|
|
title TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
ALTER TABLE organizations
|
|
ADD COLUMN IF NOT EXISTS created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL;
|
|
|
|
CREATE TABLE IF NOT EXISTS organization_memberships (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
role membership_role NOT NULL DEFAULT 'member',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE (organization_id, user_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_organization_memberships_user_id ON organization_memberships (user_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS departments (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
slug TEXT NOT NULL,
|
|
created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE (organization_id, slug)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_departments_organization_id ON departments (organization_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS teams (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
department_id UUID REFERENCES departments(id) ON DELETE SET NULL,
|
|
name TEXT NOT NULL,
|
|
slug TEXT NOT NULL,
|
|
created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE (organization_id, slug)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_teams_organization_id ON teams (organization_id);
|
|
CREATE INDEX IF NOT EXISTS idx_teams_department_id ON teams (department_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS team_memberships (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
team_id UUID NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
role membership_role NOT NULL DEFAULT 'member',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE (team_id, user_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_team_memberships_user_id ON team_memberships (user_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS projects (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
department_id UUID REFERENCES departments(id) ON DELETE SET NULL,
|
|
team_id UUID REFERENCES teams(id) ON DELETE SET NULL,
|
|
name TEXT NOT NULL,
|
|
slug TEXT NOT NULL,
|
|
created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE (organization_id, slug)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_projects_organization_id ON projects (organization_id);
|
|
CREATE INDEX IF NOT EXISTS idx_projects_department_id ON projects (department_id);
|
|
CREATE INDEX IF NOT EXISTS idx_projects_team_id ON projects (team_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS project_memberships (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
role membership_role NOT NULL DEFAULT 'member',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE (project_id, user_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_project_memberships_user_id ON project_memberships (user_id);
|
|
|
|
ALTER TABLE workspaces
|
|
ADD COLUMN IF NOT EXISTS kind workspace_kind NOT NULL DEFAULT 'organization',
|
|
ADD COLUMN IF NOT EXISTS created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
ADD COLUMN IF NOT EXISTS department_id UUID REFERENCES departments(id) ON DELETE SET NULL,
|
|
ADD COLUMN IF NOT EXISTS team_id UUID REFERENCES teams(id) ON DELETE SET NULL,
|
|
ADD COLUMN IF NOT EXISTS project_id UUID REFERENCES projects(id) ON DELETE SET NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_workspaces_department_id ON workspaces (department_id);
|
|
CREATE INDEX IF NOT EXISTS idx_workspaces_team_id ON workspaces (team_id);
|
|
CREATE INDEX IF NOT EXISTS idx_workspaces_project_id ON workspaces (project_id);
|
|
|
|
-- +goose Down
|
|
|
|
DROP INDEX IF EXISTS idx_workspaces_project_id;
|
|
DROP INDEX IF EXISTS idx_workspaces_team_id;
|
|
DROP INDEX IF EXISTS idx_workspaces_department_id;
|
|
|
|
ALTER TABLE workspaces
|
|
DROP COLUMN IF EXISTS project_id,
|
|
DROP COLUMN IF EXISTS team_id,
|
|
DROP COLUMN IF EXISTS department_id,
|
|
DROP COLUMN IF EXISTS created_by_user_id,
|
|
DROP COLUMN IF EXISTS kind;
|
|
|
|
DROP INDEX IF EXISTS idx_project_memberships_user_id;
|
|
DROP TABLE IF EXISTS project_memberships;
|
|
|
|
DROP INDEX IF EXISTS idx_projects_team_id;
|
|
DROP INDEX IF EXISTS idx_projects_department_id;
|
|
DROP INDEX IF EXISTS idx_projects_organization_id;
|
|
DROP TABLE IF EXISTS projects;
|
|
|
|
DROP INDEX IF EXISTS idx_team_memberships_user_id;
|
|
DROP TABLE IF EXISTS team_memberships;
|
|
|
|
DROP INDEX IF EXISTS idx_teams_department_id;
|
|
DROP INDEX IF EXISTS idx_teams_organization_id;
|
|
DROP TABLE IF EXISTS teams;
|
|
|
|
DROP INDEX IF EXISTS idx_departments_organization_id;
|
|
DROP TABLE IF EXISTS departments;
|
|
|
|
DROP INDEX IF EXISTS idx_organization_memberships_user_id;
|
|
DROP TABLE IF EXISTS organization_memberships;
|
|
|
|
ALTER TABLE organizations
|
|
DROP COLUMN IF EXISTS created_by_user_id;
|
|
|
|
DROP TABLE IF EXISTS user_homes;
|
|
DROP INDEX IF EXISTS idx_users_email_unique;
|
|
DROP TABLE IF EXISTS users;
|
|
DROP TABLE IF EXISTS installations;
|
|
|
|
DROP TYPE IF EXISTS membership_role;
|
|
DROP TYPE IF EXISTS workspace_kind;
|
|
DROP TYPE IF EXISTS instance_protocol;
|
|
DROP TYPE IF EXISTS instance_access;
|
|
DROP TYPE IF EXISTS instance_mode;
|