Files
Jason Woltje 244e50c806 feat(multi-tenant): add Team model and RLS policies
Implements #9, #10
- Team model with workspace membership
- TeamMember model with role-based access (OWNER, ADMIN, MEMBER)
- Row-Level Security policies for tenant isolation on 19 tables
- Helper functions: current_user_id(), is_workspace_member(), is_workspace_admin()
- Developer utilities in src/lib/db-context.ts for easy RLS integration
- Comprehensive documentation in docs/design/multi-tenant-rls.md

Database migrations:
- 20260129220941_add_team_model: Adds Team and TeamMember tables
- 20260129221004_add_rls_policies: Enables RLS and creates policies

Security features:
- Complete database-level tenant isolation
- Automatic query filtering based on workspace membership
- Defense-in-depth security with application and database layers
- Performance-optimized with indexes on workspace_id
2026-01-29 16:13:09 -06:00

41 lines
1.4 KiB
SQL

-- CreateEnum
CREATE TYPE "TeamMemberRole" AS ENUM ('OWNER', 'ADMIN', 'MEMBER');
-- CreateTable
CREATE TABLE "teams" (
"id" UUID NOT NULL,
"workspace_id" UUID NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"metadata" JSONB NOT NULL DEFAULT '{}',
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL,
CONSTRAINT "teams_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "team_members" (
"team_id" UUID NOT NULL,
"user_id" UUID NOT NULL,
"role" "TeamMemberRole" NOT NULL DEFAULT 'MEMBER',
"joined_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "team_members_pkey" PRIMARY KEY ("team_id","user_id")
);
-- CreateIndex
CREATE INDEX "teams_workspace_id_idx" ON "teams"("workspace_id");
-- CreateIndex
CREATE INDEX "team_members_user_id_idx" ON "team_members"("user_id");
-- AddForeignKey
ALTER TABLE "teams" ADD CONSTRAINT "teams_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "team_members" ADD CONSTRAINT "team_members_team_id_fkey" FOREIGN KEY ("team_id") REFERENCES "teams"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "team_members" ADD CONSTRAINT "team_members_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;