update first - 84

This commit is contained in:
thanhnv
2026-06-30 02:21:39 +09:00
commit 07ac1bdcdd
561 changed files with 88164 additions and 0 deletions
Binary file not shown.
@@ -0,0 +1,53 @@
-- Initial OKR SQLite schema generated from prisma/schema.prisma via prisma migrate diff.
CREATE TABLE "User" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" TEXT NOT NULL,
"username" TEXT NOT NULL,
"email" TEXT NOT NULL,
"passwordHash" TEXT NOT NULL,
"role" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
CREATE TABLE "Objective" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"title" TEXT NOT NULL,
"description" TEXT,
"ownerId" INTEGER NOT NULL,
"quarter" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'NOT_STARTED',
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "Objective_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
CREATE TABLE "KeyResult" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"objectiveId" INTEGER NOT NULL,
"title" TEXT NOT NULL,
"progress" INTEGER NOT NULL DEFAULT 0,
"startValue" INTEGER NOT NULL,
"targetValue" INTEGER NOT NULL,
"deadline" DATETIME NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "KeyResult_objectiveId_fkey" FOREIGN KEY ("objectiveId") REFERENCES "Objective" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE "ProgressUpdate" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"keyResultId" INTEGER NOT NULL,
"progress" INTEGER NOT NULL,
"comment" TEXT,
"createdById" INTEGER NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ProgressUpdate_keyResultId_fkey" FOREIGN KEY ("keyResultId") REFERENCES "KeyResult" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
CREATE INDEX "Objective_ownerId_idx" ON "Objective"("ownerId");
CREATE INDEX "Objective_quarter_idx" ON "Objective"("quarter");
CREATE INDEX "Objective_status_idx" ON "Objective"("status");
CREATE INDEX "KeyResult_objectiveId_idx" ON "KeyResult"("objectiveId");
@@ -0,0 +1,63 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
name String
username String @unique
email String @unique
passwordHash String
role String
objectives Objective[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Objective {
id Int @id @default(autoincrement())
title String
description String?
ownerId Int
owner User @relation(fields: [ownerId], references: [id])
quarter String
status String @default("NOT_STARTED")
keyResults KeyResult[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([ownerId])
@@index([quarter])
@@index([status])
}
model KeyResult {
id Int @id @default(autoincrement())
objectiveId Int
objective Objective @relation(fields: [objectiveId], references: [id], onDelete: Cascade)
title String
progress Int @default(0)
startValue Int
targetValue Int
deadline DateTime
updates ProgressUpdate[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([objectiveId])
}
model ProgressUpdate {
id Int @id @default(autoincrement())
keyResultId Int
keyResult KeyResult @relation(fields: [keyResultId], references: [id], onDelete: Cascade)
progress Int
comment String?
createdById Int
createdAt DateTime @default(now())
}
+205
View File
@@ -0,0 +1,205 @@
import { PrismaClient } from '@prisma/client';
import bcrypt from 'bcrypt';
const prisma = new PrismaClient();
async function main(): Promise<void> {
const passwordHash = await bcrypt.hash('Password@123', 12);
const admin = await prisma.user.upsert({
where: { email: 'admin@okr.local' },
update: { passwordHash },
create: {
name: 'System Admin',
username: 'admin',
email: 'admin@okr.local',
passwordHash,
role: 'ADMIN',
},
});
const manager = await prisma.user.upsert({
where: { email: 'manager@okr.local' },
update: { passwordHash },
create: {
name: 'Nguyen Van Manager',
username: 'manager',
email: 'manager@okr.local',
passwordHash,
role: 'MANAGER',
},
});
const employee = await prisma.user.upsert({
where: { email: 'employee@okr.local' },
update: { passwordHash },
create: {
name: 'Nguyen Van A',
username: 'employee',
email: 'employee@okr.local',
passwordHash,
role: 'EMPLOYEE',
},
});
const employeeTwo = await prisma.user.upsert({
where: { email: 'employee2@okr.local' },
update: { passwordHash },
create: {
name: 'Tran Thi B',
username: 'employee2',
email: 'employee2@okr.local',
passwordHash,
role: 'EMPLOYEE',
},
});
const securityObjective = await prisma.objective.upsert({
where: { id: 1 },
update: {
ownerId: employee.id,
title: 'POC AI for SQL Injection prevention',
description: 'Evaluate AI tools for automated SQL injection detection.',
quarter: 'Q2/2026',
status: 'IN_PROGRESS',
},
create: {
id: 1,
ownerId: employee.id,
title: 'POC AI for SQL Injection prevention',
description: 'Evaluate AI tools for automated SQL injection detection.',
quarter: 'Q2/2026',
status: 'IN_PROGRESS',
},
});
const adoptionObjective = await prisma.objective.upsert({
where: { id: 2 },
update: {
ownerId: employeeTwo.id,
title: 'AI for All enablement across department',
description: 'Train and certify department members on practical AI workflows.',
quarter: 'Q2/2026',
status: 'NOT_STARTED',
},
create: {
id: 2,
ownerId: employeeTwo.id,
title: 'AI for All enablement across department',
description: 'Train and certify department members on practical AI workflows.',
quarter: 'Q2/2026',
status: 'NOT_STARTED',
},
});
const managerObjective = await prisma.objective.upsert({
where: { id: 3 },
update: {
ownerId: manager.id,
title: 'Improve OKR operating cadence',
description: 'Create weekly progress rhythm and reduce stale OKRs.',
quarter: 'Q2/2026',
status: 'IN_PROGRESS',
},
create: {
id: 3,
ownerId: manager.id,
title: 'Improve OKR operating cadence',
description: 'Create weekly progress rhythm and reduce stale OKRs.',
quarter: 'Q2/2026',
status: 'IN_PROGRESS',
},
});
await prisma.keyResult.upsert({
where: { id: 1 },
update: { objectiveId: securityObjective.id, progress: 33 },
create: {
id: 1,
objectiveId: securityObjective.id,
title: 'Complete 3 POC sessions with security team',
progress: 33,
startValue: 0,
targetValue: 3,
deadline: new Date('2026-06-30T00:00:00.000Z'),
},
});
await prisma.keyResult.upsert({
where: { id: 2 },
update: { objectiveId: securityObjective.id, progress: 60 },
create: {
id: 2,
objectiveId: securityObjective.id,
title: 'Reduce manual SQL injection review effort by 30%',
progress: 60,
startValue: 0,
targetValue: 30,
deadline: new Date('2026-06-30T00:00:00.000Z'),
},
});
await prisma.keyResult.upsert({
where: { id: 3 },
update: { objectiveId: adoptionObjective.id, progress: 0 },
create: {
id: 3,
objectiveId: adoptionObjective.id,
title: 'Certify 100 department members on AI for All',
progress: 0,
startValue: 0,
targetValue: 100,
deadline: new Date('2026-06-30T00:00:00.000Z'),
},
});
await prisma.keyResult.upsert({
where: { id: 4 },
update: { objectiveId: managerObjective.id, progress: 75 },
create: {
id: 4,
objectiveId: managerObjective.id,
title: 'Reach 90% weekly OKR update compliance',
progress: 75,
startValue: 40,
targetValue: 90,
deadline: new Date('2026-06-30T00:00:00.000Z'),
},
});
await prisma.keyResult.upsert({
where: { id: 5 },
update: { objectiveId: managerObjective.id, progress: 45 },
create: {
id: 5,
objectiveId: managerObjective.id,
title: 'Resolve stale OKR reports within two business days',
progress: 45,
startValue: 0,
targetValue: 10,
deadline: new Date('2026-06-30T00:00:00.000Z'),
},
});
await prisma.progressUpdate.deleteMany({ where: { keyResultId: { in: [1, 2, 3, 4, 5] } } });
await prisma.progressUpdate.create({
data: {
keyResultId: 2,
progress: 60,
comment: 'Two review workflows automated; third is in validation.',
createdById: employee.id,
},
});
void admin;
console.log('Seed completed successfully.');
}
main()
.catch((error: unknown) => {
console.error(error);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
Binary file not shown.