Skip to content

Commit 7eedb54

Browse files
chore: add backend seed script and root seed command
1 parent cde5445 commit 7eedb54

3 files changed

Lines changed: 129 additions & 15 deletions

File tree

apps/backend/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"lint": "tsc --noEmit",
1010
"test": "jest --runInBand --passWithNoTests",
1111
"prisma:generate": "prisma generate",
12-
"prisma:migrate": "prisma migrate dev"
12+
"prisma:migrate": "prisma migrate dev",
13+
"seed": "ts-node prisma/seed.ts"
1314
},
1415
"dependencies": {
1516
"@fairshare/shared-types": "workspace:*",

apps/backend/prisma/seed.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { PrismaClient } from '@prisma/client';
2+
import { hash } from 'bcrypt';
3+
4+
const prisma = new PrismaClient();
5+
6+
async function main(): Promise<void> {
7+
await prisma.$transaction([
8+
prisma.activity.deleteMany(),
9+
prisma.receipt.deleteMany(),
10+
prisma.settlement.deleteMany(),
11+
prisma.balance.deleteMany(),
12+
prisma.split.deleteMany(),
13+
prisma.expense.deleteMany(),
14+
prisma.groupMember.deleteMany(),
15+
prisma.group.deleteMany(),
16+
prisma.refreshToken.deleteMany(),
17+
prisma.pushToken.deleteMany(),
18+
prisma.user.deleteMany(),
19+
]);
20+
21+
const passwordHash = await hash('Password@123', 10);
22+
23+
const [u1, u2, u3] = await prisma.$transaction([
24+
prisma.user.create({
25+
data: { email: 'alice@fairshare.dev', name: 'Alice', passwordHash },
26+
}),
27+
prisma.user.create({
28+
data: { email: 'bob@fairshare.dev', name: 'Bob', passwordHash },
29+
}),
30+
prisma.user.create({
31+
data: { email: 'cara@fairshare.dev', name: 'Cara', passwordHash },
32+
}),
33+
]);
34+
35+
const [g1, g2] = await prisma.$transaction([
36+
prisma.group.create({ data: { name: 'Trip Squad', currency: 'USD', createdBy: u1.id } }),
37+
prisma.group.create({ data: { name: 'Flatmates', currency: 'USD', createdBy: u2.id } }),
38+
]);
39+
40+
await prisma.groupMember.createMany({
41+
data: [
42+
{ groupId: g1.id, userId: u1.id, role: 'OWNER' },
43+
{ groupId: g1.id, userId: u2.id, role: 'MEMBER' },
44+
{ groupId: g1.id, userId: u3.id, role: 'MEMBER' },
45+
{ groupId: g2.id, userId: u2.id, role: 'OWNER' },
46+
{ groupId: g2.id, userId: u1.id, role: 'MEMBER' },
47+
{ groupId: g2.id, userId: u3.id, role: 'MEMBER' },
48+
],
49+
});
50+
51+
const groups = [g1, g2];
52+
const users = [u1, u2, u3];
53+
54+
for (let i = 0; i < 10; i += 1) {
55+
const group = groups[i % 2];
56+
const payer = users[i % 3];
57+
const total = BigInt((i + 1) * 1000);
58+
const perHead = total / 3n;
59+
60+
const expense = await prisma.expense.create({
61+
data: {
62+
groupId: group.id,
63+
payerId: payer.id,
64+
description: `Seed expense ${i + 1}`,
65+
totalAmountCents: total,
66+
currency: 'USD',
67+
},
68+
});
69+
70+
await prisma.split.createMany({
71+
data: users.map((user) => ({
72+
expenseId: expense.id,
73+
userId: user.id,
74+
owedAmountCents: perHead,
75+
paidAmountCents: user.id === payer.id ? total : 0n,
76+
})),
77+
});
78+
79+
await prisma.activity.create({
80+
data: {
81+
groupId: group.id,
82+
actorUserId: payer.id,
83+
type: 'expense_created',
84+
entityId: expense.id,
85+
metadata: { totalAmountCents: total.toString() },
86+
},
87+
});
88+
}
89+
90+
// minimal baseline balances for demo visibility
91+
await prisma.balance.createMany({
92+
data: [
93+
{ groupId: g1.id, userId: u2.id, counterpartyUserId: u1.id, amountCents: -500n },
94+
{ groupId: g1.id, userId: u1.id, counterpartyUserId: u2.id, amountCents: 500n },
95+
{ groupId: g2.id, userId: u3.id, counterpartyUserId: u2.id, amountCents: -700n },
96+
{ groupId: g2.id, userId: u2.id, counterpartyUserId: u3.id, amountCents: 700n },
97+
],
98+
});
99+
100+
// eslint-disable-next-line no-console
101+
console.log('Seed complete: 3 users, 2 groups, 10 expenses');
102+
}
103+
104+
main()
105+
.catch(async (error) => {
106+
// eslint-disable-next-line no-console
107+
console.error(error);
108+
process.exitCode = 1;
109+
})
110+
.finally(async () => {
111+
await prisma.$disconnect();
112+
});

package.json

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
{
2-
"name": "fairshare",
3-
"private": true,
4-
"packageManager": "pnpm@10.6.1",
5-
"scripts": {
6-
"build": "turbo run build",
7-
"dev": "turbo run dev --parallel",
8-
"lint": "turbo run lint",
9-
"test": "turbo run test",
10-
"format": "turbo run format"
11-
},
12-
"devDependencies": {
13-
"turbo": "^2.5.0",
14-
"typescript": "^5.7.3"
15-
}
2+
"name": "fairshare",
3+
"private": true,
4+
"packageManager": "pnpm@10.6.1",
5+
"scripts": {
6+
"build": "turbo run build",
7+
"dev": "turbo run dev --parallel",
8+
"lint": "turbo run lint",
9+
"test": "turbo run test",
10+
"format": "turbo run format",
11+
"seed": "pnpm --filter backend seed"
12+
},
13+
"devDependencies": {
14+
"turbo": "^2.5.0",
15+
"typescript": "^5.7.3"
16+
}
1617
}

0 commit comments

Comments
 (0)