- Create comprehensive test suite for PrismaService (10 tests) - Fix AppController tests with proper PrismaService mocking - Wrap seed operations in transaction for atomicity - Replace N+1 pattern with batch operations (createMany) - Add concurrency warning to seed script - All tests passing (14/14) - Build successful - Test coverage >85% Fixes #3 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
160 lines
4.1 KiB
TypeScript
160 lines
4.1 KiB
TypeScript
import {
|
|
PrismaClient,
|
|
TaskStatus,
|
|
TaskPriority,
|
|
ProjectStatus,
|
|
WorkspaceMemberRole,
|
|
} from "@prisma/client";
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
async function main() {
|
|
console.log("Seeding database...");
|
|
|
|
// IMPORTANT: This seed script should not be run concurrently
|
|
// If running in CI/CD, ensure serialization of seed operations
|
|
// to prevent race conditions and data corruption
|
|
|
|
// Create test user
|
|
const user = await prisma.user.upsert({
|
|
where: { email: "dev@mosaic.local" },
|
|
update: {},
|
|
create: {
|
|
email: "dev@mosaic.local",
|
|
name: "Development User",
|
|
preferences: {
|
|
theme: "system",
|
|
notifications: true,
|
|
},
|
|
},
|
|
});
|
|
|
|
console.log(`Created user: ${user.email}`);
|
|
|
|
// Create workspace
|
|
const workspace = await prisma.workspace.upsert({
|
|
where: { id: "00000000-0000-0000-0000-000000000001" },
|
|
update: {},
|
|
create: {
|
|
id: "00000000-0000-0000-0000-000000000001",
|
|
name: "Development Workspace",
|
|
ownerId: user.id,
|
|
settings: {
|
|
timezone: "America/New_York",
|
|
},
|
|
},
|
|
});
|
|
|
|
console.log(`Created workspace: ${workspace.name}`);
|
|
|
|
// Add user as workspace owner
|
|
await prisma.workspaceMember.upsert({
|
|
where: {
|
|
workspaceId_userId: {
|
|
workspaceId: workspace.id,
|
|
userId: user.id,
|
|
},
|
|
},
|
|
update: {},
|
|
create: {
|
|
workspaceId: workspace.id,
|
|
userId: user.id,
|
|
role: WorkspaceMemberRole.OWNER,
|
|
},
|
|
});
|
|
|
|
// Use transaction for atomic seed data reset and creation
|
|
await prisma.$transaction(async (tx) => {
|
|
// Delete existing seed data for idempotency (avoids duplicates on re-run)
|
|
await tx.task.deleteMany({ where: { workspaceId: workspace.id } });
|
|
await tx.event.deleteMany({ where: { workspaceId: workspace.id } });
|
|
await tx.project.deleteMany({ where: { workspaceId: workspace.id } });
|
|
|
|
// Create sample project
|
|
const project = await tx.project.create({
|
|
data: {
|
|
workspaceId: workspace.id,
|
|
name: "Sample Project",
|
|
description: "A sample project for development",
|
|
status: ProjectStatus.ACTIVE,
|
|
creatorId: user.id,
|
|
color: "#3B82F6",
|
|
},
|
|
});
|
|
|
|
console.log(`Created project: ${project.name}`);
|
|
|
|
// Create sample tasks
|
|
const tasks = [
|
|
{
|
|
title: "Set up development environment",
|
|
status: TaskStatus.COMPLETED,
|
|
priority: TaskPriority.HIGH,
|
|
},
|
|
{
|
|
title: "Review project requirements",
|
|
status: TaskStatus.IN_PROGRESS,
|
|
priority: TaskPriority.MEDIUM,
|
|
},
|
|
{
|
|
title: "Design database schema",
|
|
status: TaskStatus.COMPLETED,
|
|
priority: TaskPriority.HIGH,
|
|
},
|
|
{
|
|
title: "Implement NestJS integration",
|
|
status: TaskStatus.COMPLETED,
|
|
priority: TaskPriority.HIGH,
|
|
},
|
|
{
|
|
title: "Create seed data",
|
|
status: TaskStatus.IN_PROGRESS,
|
|
priority: TaskPriority.MEDIUM,
|
|
},
|
|
];
|
|
|
|
// Use createMany for batch insertion (better performance)
|
|
await tx.task.createMany({
|
|
data: tasks.map((taskData) => ({
|
|
workspaceId: workspace.id,
|
|
title: taskData.title,
|
|
status: taskData.status,
|
|
priority: taskData.priority,
|
|
creatorId: user.id,
|
|
projectId: project.id,
|
|
})),
|
|
});
|
|
|
|
console.log(`Created ${tasks.length} sample tasks`);
|
|
|
|
// Create sample event
|
|
const tomorrow = new Date();
|
|
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
tomorrow.setHours(10, 0, 0, 0);
|
|
|
|
await tx.event.create({
|
|
data: {
|
|
workspaceId: workspace.id,
|
|
title: "Morning standup",
|
|
description: "Daily team sync",
|
|
startTime: tomorrow,
|
|
endTime: new Date(tomorrow.getTime() + 30 * 60000), // 30 minutes later
|
|
creatorId: user.id,
|
|
projectId: project.id,
|
|
},
|
|
});
|
|
|
|
console.log("Created sample event");
|
|
});
|
|
console.log("Seeding completed successfully!");
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error("Error seeding database:", e);
|
|
process.exit(1);
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect();
|
|
});
|