feat: ProductMember — team management for product backlogs
- Add ProductMember model (many-to-many User ↔ Product) - Add productAccessFilter helper (owner OR member OR clause) - Replace all ownership checks across actions and API routes - Add addProductMemberAction / removeProductMemberAction / leaveProductAction - Add TeamManager component in product settings (owner adds/removes Developers) - Add LeaveProductButton in user settings (member leaves a product team) - Regenerate Prisma Client after schema migration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fc12e3cc64
commit
357b1e32e8
18 changed files with 370 additions and 82 deletions
|
|
@ -0,0 +1,2 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "tasks" ADD COLUMN "implementation_plan" TEXT;
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
-- CreateTable
|
||||
CREATE TABLE "product_members" (
|
||||
"id" TEXT NOT NULL,
|
||||
"product_id" TEXT NOT NULL,
|
||||
"user_id" TEXT NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "product_members_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "product_members_user_id_idx" ON "product_members"("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "product_members_product_id_user_id_key" ON "product_members"("product_id", "user_id");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "product_members" ADD CONSTRAINT "product_members_product_id_fkey" FOREIGN KEY ("product_id") REFERENCES "products"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "product_members" ADD CONSTRAINT "product_members_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
|
@ -41,16 +41,17 @@ enum SprintStatus {
|
|||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
username String @unique
|
||||
password_hash String
|
||||
is_demo Boolean @default(false)
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
roles UserRole[]
|
||||
api_tokens ApiToken[]
|
||||
products Product[]
|
||||
todos Todo[]
|
||||
id String @id @default(cuid())
|
||||
username String @unique
|
||||
password_hash String
|
||||
is_demo Boolean @default(false)
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
roles UserRole[]
|
||||
api_tokens ApiToken[]
|
||||
products Product[]
|
||||
todos Todo[]
|
||||
product_members ProductMember[]
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
|
|
@ -79,20 +80,21 @@ model ApiToken {
|
|||
}
|
||||
|
||||
model Product {
|
||||
id String @id @default(cuid())
|
||||
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
|
||||
id String @id @default(cuid())
|
||||
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
|
||||
user_id String
|
||||
name String
|
||||
description String?
|
||||
repo_url String?
|
||||
definition_of_done String
|
||||
archived Boolean @default(false)
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
archived Boolean @default(false)
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
pbis Pbi[]
|
||||
sprints Sprint[]
|
||||
stories Story[]
|
||||
todos Todo[]
|
||||
members ProductMember[]
|
||||
|
||||
@@unique([user_id, name])
|
||||
@@index([user_id, archived])
|
||||
|
|
@ -190,6 +192,19 @@ model Task {
|
|||
@@map("tasks")
|
||||
}
|
||||
|
||||
model ProductMember {
|
||||
id String @id @default(cuid())
|
||||
product Product @relation(fields: [product_id], references: [id], onDelete: Cascade)
|
||||
product_id String
|
||||
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
|
||||
user_id String
|
||||
created_at DateTime @default(now())
|
||||
|
||||
@@unique([product_id, user_id])
|
||||
@@index([user_id])
|
||||
@@map("product_members")
|
||||
}
|
||||
|
||||
model Todo {
|
||||
id String @id @default(cuid())
|
||||
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue