feat(ST-702): vendor Scrum4Me schema via submodule + sync script
- Add vendor/scrum4me as a git submodule (read-only source of truth) - scripts/sync-schema.sh copies schema.prisma into prisma/, stripping the upstream prisma-erd-generator block we don't ship - Track the synced schema in git so a fresh clone works after 'git submodule update --init && npm install' - postinstall runs 'prisma generate' so @prisma/client is ready Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ea00736a13
commit
992a4ad5e1
5 changed files with 273 additions and 0 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "vendor/scrum4me"]
|
||||||
|
path = vendor/scrum4me
|
||||||
|
url = https://github.com/madhura68/Scrum4Me.git
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"start": "node dist/index.js",
|
"start": "node dist/index.js",
|
||||||
"prisma:generate": "prisma generate",
|
"prisma:generate": "prisma generate",
|
||||||
|
"postinstall": "prisma generate || true",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"sync-schema": "bash scripts/sync-schema.sh"
|
"sync-schema": "bash scripts/sync-schema.sh"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
240
prisma/schema.prisma
Normal file
240
prisma/schema.prisma
Normal file
|
|
@ -0,0 +1,240 @@
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
datasource db {
|
||||||
|
provider = "postgresql"
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Role {
|
||||||
|
PRODUCT_OWNER
|
||||||
|
SCRUM_MASTER
|
||||||
|
DEVELOPER
|
||||||
|
}
|
||||||
|
|
||||||
|
enum StoryStatus {
|
||||||
|
OPEN
|
||||||
|
IN_SPRINT
|
||||||
|
DONE
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TaskStatus {
|
||||||
|
TO_DO
|
||||||
|
IN_PROGRESS
|
||||||
|
REVIEW
|
||||||
|
DONE
|
||||||
|
}
|
||||||
|
|
||||||
|
enum LogType {
|
||||||
|
IMPLEMENTATION_PLAN
|
||||||
|
TEST_RESULT
|
||||||
|
COMMIT
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TestStatus {
|
||||||
|
PASSED
|
||||||
|
FAILED
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SprintStatus {
|
||||||
|
ACTIVE
|
||||||
|
COMPLETED
|
||||||
|
}
|
||||||
|
|
||||||
|
model User {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
username String @unique
|
||||||
|
email String? @unique
|
||||||
|
password_hash String
|
||||||
|
is_demo Boolean @default(false)
|
||||||
|
bio String? @db.VarChar(160)
|
||||||
|
bio_detail String? @db.VarChar(2000)
|
||||||
|
avatar_data Bytes?
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
roles UserRole[]
|
||||||
|
api_tokens ApiToken[]
|
||||||
|
products Product[]
|
||||||
|
todos Todo[]
|
||||||
|
product_members ProductMember[]
|
||||||
|
assigned_stories Story[] @relation("StoryAssignee")
|
||||||
|
|
||||||
|
@@map("users")
|
||||||
|
}
|
||||||
|
|
||||||
|
model UserRole {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
|
||||||
|
user_id String
|
||||||
|
role Role
|
||||||
|
|
||||||
|
@@unique([user_id, role])
|
||||||
|
@@map("user_roles")
|
||||||
|
}
|
||||||
|
|
||||||
|
model ApiToken {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
|
||||||
|
user_id String
|
||||||
|
token_hash String @unique
|
||||||
|
label String?
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
revoked_at DateTime?
|
||||||
|
|
||||||
|
@@index([token_hash])
|
||||||
|
@@map("api_tokens")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Product {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
|
||||||
|
user_id String
|
||||||
|
name String
|
||||||
|
code String? @db.VarChar(30)
|
||||||
|
description String?
|
||||||
|
repo_url String?
|
||||||
|
definition_of_done String
|
||||||
|
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])
|
||||||
|
@@unique([user_id, code])
|
||||||
|
@@index([user_id, archived])
|
||||||
|
@@map("products")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Pbi {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
product Product @relation(fields: [product_id], references: [id], onDelete: Cascade)
|
||||||
|
product_id String
|
||||||
|
code String? @db.VarChar(30)
|
||||||
|
title String
|
||||||
|
description String?
|
||||||
|
priority Int
|
||||||
|
sort_order Float
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
stories Story[]
|
||||||
|
|
||||||
|
@@unique([product_id, code])
|
||||||
|
@@index([product_id, priority, sort_order])
|
||||||
|
@@map("pbis")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Story {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
pbi Pbi @relation(fields: [pbi_id], references: [id], onDelete: Cascade)
|
||||||
|
pbi_id String
|
||||||
|
product Product @relation(fields: [product_id], references: [id])
|
||||||
|
product_id String
|
||||||
|
sprint Sprint? @relation(fields: [sprint_id], references: [id])
|
||||||
|
sprint_id String?
|
||||||
|
assignee User? @relation("StoryAssignee", fields: [assignee_id], references: [id], onDelete: SetNull)
|
||||||
|
assignee_id String?
|
||||||
|
code String? @db.VarChar(30)
|
||||||
|
title String
|
||||||
|
description String?
|
||||||
|
acceptance_criteria String?
|
||||||
|
priority Int
|
||||||
|
sort_order Float
|
||||||
|
status StoryStatus @default(OPEN)
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
logs StoryLog[]
|
||||||
|
tasks Task[]
|
||||||
|
|
||||||
|
@@unique([product_id, code])
|
||||||
|
@@index([pbi_id, priority, sort_order])
|
||||||
|
@@index([sprint_id, sort_order])
|
||||||
|
@@index([product_id, status])
|
||||||
|
@@index([sprint_id, assignee_id])
|
||||||
|
@@map("stories")
|
||||||
|
}
|
||||||
|
|
||||||
|
model StoryLog {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
story Story @relation(fields: [story_id], references: [id], onDelete: Cascade)
|
||||||
|
story_id String
|
||||||
|
type LogType
|
||||||
|
content String
|
||||||
|
status TestStatus?
|
||||||
|
commit_hash String?
|
||||||
|
commit_message String?
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
|
||||||
|
@@index([story_id, created_at])
|
||||||
|
@@map("story_logs")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Sprint {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
product Product @relation(fields: [product_id], references: [id], onDelete: Cascade)
|
||||||
|
product_id String
|
||||||
|
sprint_goal String
|
||||||
|
status SprintStatus @default(ACTIVE)
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
completed_at DateTime?
|
||||||
|
stories Story[]
|
||||||
|
tasks Task[]
|
||||||
|
|
||||||
|
@@index([product_id, status])
|
||||||
|
@@map("sprints")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Task {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
story Story @relation(fields: [story_id], references: [id], onDelete: Cascade)
|
||||||
|
story_id String
|
||||||
|
sprint Sprint? @relation(fields: [sprint_id], references: [id])
|
||||||
|
sprint_id String?
|
||||||
|
title String
|
||||||
|
description String?
|
||||||
|
implementation_plan String?
|
||||||
|
priority Int
|
||||||
|
sort_order Float
|
||||||
|
status TaskStatus @default(TO_DO)
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
|
||||||
|
@@index([story_id, priority, sort_order])
|
||||||
|
@@index([sprint_id, status])
|
||||||
|
@@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)
|
||||||
|
user_id String
|
||||||
|
product Product? @relation(fields: [product_id], references: [id], onDelete: SetNull)
|
||||||
|
product_id String?
|
||||||
|
title String
|
||||||
|
description String? @db.VarChar(2000)
|
||||||
|
done Boolean @default(false)
|
||||||
|
archived Boolean @default(false)
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
|
||||||
|
@@index([user_id, done, archived])
|
||||||
|
@@index([user_id, product_id])
|
||||||
|
@@map("todos")
|
||||||
|
}
|
||||||
28
scripts/sync-schema.sh
Executable file
28
scripts/sync-schema.sh
Executable file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Sync prisma/schema.prisma from the vendored Scrum4Me submodule.
|
||||||
|
#
|
||||||
|
# Strips the `generator erd` block — that generator depends on
|
||||||
|
# prisma-erd-generator which we don't ship in this MCP package. The
|
||||||
|
# schema is otherwise byte-identical with upstream.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
|
SRC="$ROOT/vendor/scrum4me/prisma/schema.prisma"
|
||||||
|
DST="$ROOT/prisma/schema.prisma"
|
||||||
|
|
||||||
|
if [ ! -f "$SRC" ]; then
|
||||||
|
echo "error: $SRC not found — run 'git submodule update --init' first" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$ROOT/prisma"
|
||||||
|
|
||||||
|
# Strip the `generator erd { ... }` block (multi-line, balanced braces).
|
||||||
|
awk '
|
||||||
|
/^generator erd \{/ { skip = 1; next }
|
||||||
|
skip && /^\}/ { skip = 0; next }
|
||||||
|
skip { next }
|
||||||
|
{ print }
|
||||||
|
' "$SRC" > "$DST"
|
||||||
|
|
||||||
|
echo "synced schema from $(cd "$ROOT/vendor/scrum4me" && git rev-parse --short HEAD) to prisma/schema.prisma"
|
||||||
1
vendor/scrum4me
vendored
Submodule
1
vendor/scrum4me
vendored
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit a8adac127fc09486d0b3e63544b5ddf8791f3c04
|
||||||
Loading…
Add table
Add a link
Reference in a new issue