diff --git a/backend/app/database.py b/backend/app/database.py index 3a686d9..d6f6673 100644 --- a/backend/app/database.py +++ b/backend/app/database.py @@ -285,6 +285,60 @@ def _run_migrations(): END IF; END $$; """, + # Teams and multi-tenancy migration (009_teams.sql) + """ + CREATE TABLE IF NOT EXISTS teams ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + name VARCHAR(255) NOT NULL, + slug VARCHAR(255) NOT NULL UNIQUE, + description TEXT, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + created_by VARCHAR(255) NOT NULL, + settings JSONB DEFAULT '{}' + ); + """, + """ + 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 VARCHAR(50) NOT NULL DEFAULT 'member', + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + invited_by VARCHAR(255), + CONSTRAINT team_memberships_unique UNIQUE (team_id, user_id), + CONSTRAINT team_memberships_role_check CHECK (role IN ('owner', 'admin', 'member')) + ); + """, + """ + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'projects' AND column_name = 'team_id' + ) THEN + ALTER TABLE projects ADD COLUMN team_id UUID REFERENCES teams(id) ON DELETE SET NULL; + CREATE INDEX IF NOT EXISTS idx_projects_team_id ON projects(team_id); + END IF; + END $$; + """, + """ + DO $$ + BEGIN + IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_teams_slug') THEN + CREATE INDEX idx_teams_slug ON teams(slug); + END IF; + IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_teams_created_by') THEN + CREATE INDEX idx_teams_created_by ON teams(created_by); + END IF; + IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_team_memberships_team_id') THEN + CREATE INDEX idx_team_memberships_team_id ON team_memberships(team_id); + END IF; + IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_team_memberships_user_id') THEN + CREATE INDEX idx_team_memberships_user_id ON team_memberships(user_id); + END IF; + END $$; + """, ] with engine.connect() as conn: