feat: add prisma schema and migrations
- Define Task and State entities with relations - Add StateHistory for tracking state changes - Include seed script for initial data - Add initial and soft delete migrations
This commit is contained in:
parent
691c035130
commit
c539c9e01d
|
|
@ -0,0 +1,55 @@
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "State" (
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "State_pkey" PRIMARY KEY ("name")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "Task" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"title" TEXT NOT NULL,
|
||||||
|
"description" TEXT NOT NULL,
|
||||||
|
"dueDate" TEXT NOT NULL,
|
||||||
|
"completed" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "Task_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "StateHistory" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"state" TEXT NOT NULL,
|
||||||
|
"date" TEXT NOT NULL,
|
||||||
|
"taskId" TEXT NOT NULL,
|
||||||
|
"order" INTEGER NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "StateHistory_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "Note" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"content" TEXT NOT NULL,
|
||||||
|
"taskId" TEXT NOT NULL,
|
||||||
|
"order" INTEGER NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "Note_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "StateHistory_taskId_idx" ON "StateHistory"("taskId");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "Note_taskId_idx" ON "Note"("taskId");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "StateHistory" ADD CONSTRAINT "StateHistory_taskId_fkey" FOREIGN KEY ("taskId") REFERENCES "Task"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "StateHistory" ADD CONSTRAINT "StateHistory_state_fkey" FOREIGN KEY ("state") REFERENCES "State"("name") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Note" ADD CONSTRAINT "Note_taskId_fkey" FOREIGN KEY ("taskId") REFERENCES "Task"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Task" ADD COLUMN "deletedAt" TIMESTAMP(3);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "Task_deletedAt_idx" ON "Task"("deletedAt");
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Please do not edit this file manually
|
||||||
|
# It should be added in your version-control system (e.g., Git)
|
||||||
|
provider = "postgresql"
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client"
|
||||||
|
output = "../src/generated/prisma"
|
||||||
|
}
|
||||||
|
|
||||||
|
datasource db {
|
||||||
|
provider = "postgresql"
|
||||||
|
}
|
||||||
|
|
||||||
|
model State {
|
||||||
|
name String @id
|
||||||
|
|
||||||
|
tasks StateHistory[]
|
||||||
|
}
|
||||||
|
|
||||||
|
model Task {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
title String
|
||||||
|
description String
|
||||||
|
dueDate String
|
||||||
|
completed Boolean @default(false)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
deletedAt DateTime?
|
||||||
|
|
||||||
|
stateHistory StateHistory[]
|
||||||
|
notes Note[]
|
||||||
|
|
||||||
|
@@index([deletedAt])
|
||||||
|
}
|
||||||
|
|
||||||
|
model StateHistory {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
state String
|
||||||
|
date String
|
||||||
|
taskId String
|
||||||
|
order Int
|
||||||
|
|
||||||
|
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
||||||
|
stateRef State @relation(fields: [state], references: [name])
|
||||||
|
|
||||||
|
@@index([taskId])
|
||||||
|
}
|
||||||
|
|
||||||
|
model Note {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
content String
|
||||||
|
taskId String
|
||||||
|
order Int
|
||||||
|
|
||||||
|
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
@@index([taskId])
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
import "dotenv/config";
|
||||||
|
import { PrismaClient } from "../src/generated/prisma/client.js";
|
||||||
|
import { PrismaPg } from "@prisma/adapter-pg";
|
||||||
|
|
||||||
|
const connectionString = process.env.DATABASE_URL;
|
||||||
|
if (!connectionString) {
|
||||||
|
throw new Error("DATABASE_URL is not set");
|
||||||
|
}
|
||||||
|
|
||||||
|
const adapter = new PrismaPg({ connectionString });
|
||||||
|
const prisma = new PrismaClient({ adapter });
|
||||||
|
|
||||||
|
async function seed() {
|
||||||
|
console.log("Seeding database...");
|
||||||
|
|
||||||
|
await prisma.state.createMany({
|
||||||
|
data: [
|
||||||
|
{ name: "new" },
|
||||||
|
{ name: "active" },
|
||||||
|
{ name: "resolved" },
|
||||||
|
{ name: "closed" },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const tasks = [
|
||||||
|
{
|
||||||
|
title: "Complete Project Proposal",
|
||||||
|
description: "Prepare and submit the project proposal for approval.",
|
||||||
|
dueDate: "2023-12-15",
|
||||||
|
stateHistory: [
|
||||||
|
{ state: "new", date: "2023-12-01" },
|
||||||
|
{ state: "active", date: "2023-12-05" },
|
||||||
|
],
|
||||||
|
notes: ["Check proposal guidelines", "Include budget estimates"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Design Wireframes",
|
||||||
|
description: "Create wireframes for the user interface.",
|
||||||
|
dueDate: "2023-12-20",
|
||||||
|
stateHistory: [
|
||||||
|
{ state: "new", date: "2023-12-02" },
|
||||||
|
{ state: "active", date: "2023-12-06" },
|
||||||
|
],
|
||||||
|
notes: ["Review design patterns", "Seek feedback from the team"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Implement User Authentication",
|
||||||
|
description: "Develop user authentication functionality.",
|
||||||
|
dueDate: "2023-12-25",
|
||||||
|
stateHistory: [
|
||||||
|
{ state: "new", date: "2023-12-03" },
|
||||||
|
{ state: "active", date: "2023-12-07" },
|
||||||
|
],
|
||||||
|
notes: ["Research secure authentication methods", "Implement password hashing"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Write API Documentation",
|
||||||
|
description: "Document the RESTful API for external developers.",
|
||||||
|
dueDate: "2023-12-30",
|
||||||
|
stateHistory: [
|
||||||
|
{ state: "new", date: "2023-12-04" },
|
||||||
|
{ state: "active", date: "2023-12-08" },
|
||||||
|
],
|
||||||
|
notes: ["Use Swagger/OpenAPI for documentation", "Provide clear examples"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Bug Fixes and Testing",
|
||||||
|
description: "Address reported bugs and perform thorough testing.",
|
||||||
|
dueDate: "2024-01-05",
|
||||||
|
stateHistory: [
|
||||||
|
{ state: "new", date: "2023-12-05" },
|
||||||
|
{ state: "active", date: "2023-12-09" },
|
||||||
|
],
|
||||||
|
notes: ["Create test cases for critical scenarios", "Perform regression testing"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Project Deployment",
|
||||||
|
description: "Prepare for and deploy the project to production.",
|
||||||
|
dueDate: "2024-01-10",
|
||||||
|
stateHistory: [
|
||||||
|
{ state: "new", date: "2023-12-06" },
|
||||||
|
{ state: "active", date: "2023-12-10" },
|
||||||
|
],
|
||||||
|
notes: ["Coordinate with DevOps for deployment", "Monitor performance after deployment"],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const task of tasks) {
|
||||||
|
await prisma.task.create({
|
||||||
|
data: {
|
||||||
|
title: task.title,
|
||||||
|
description: task.description,
|
||||||
|
dueDate: task.dueDate,
|
||||||
|
stateHistory: {
|
||||||
|
create: task.stateHistory.map((entry, index) => ({
|
||||||
|
state: entry.state,
|
||||||
|
date: entry.date,
|
||||||
|
order: index,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
notes: {
|
||||||
|
create: task.notes.map((content, index) => ({
|
||||||
|
content,
|
||||||
|
order: index,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Seed completed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
seed()
|
||||||
|
.catch((e) => {
|
||||||
|
console.error(e);
|
||||||
|
process.exit(1);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await prisma.$disconnect();
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue