Visitenbuch/tests/helpers/generate-mockdata.ts
2024-05-14 00:40:10 +02:00

183 lines
5.1 KiB
TypeScript

/* eslint-disable no-await-in-loop */
import fs from "fs";
import path from "path";
import { performance } from "perf_hooks";
import { fileURLToPath } from "url";
import { faker } from "@faker-js/faker";
import { prisma } from "$lib/server/prisma";
import { CATEGORIES, STATIONS } from "./testdata";
type MockEntry = { category: string; description: string; result: string };
const CATEGORY_IDS: { [id: string]: number } = {
Laborabnahme: 1,
Untersuchungen: 2,
Medikationsumstellung: 3,
"Klinische Visite": 4,
Entlassung: 5,
Sonstiges: 6,
};
const refDate = new Date(Date.UTC(2023, 11, 1));
const N_USERS = 10;
const N_ROOMS = 20;
const N_PATIENTS = 50;
function randomId(len: number): number {
return faker.number.int({ min: 1, max: len - 1 });
}
function randomUserId(): number {
return randomId(N_USERS) + 1;
}
/** Reset database and create extensive test data for development and E2E tests */
export default async () => {
const startTime = performance.now();
// Reset database
await prisma.$transaction([
prisma.savedFilter.deleteMany(),
prisma.entryExecution.deleteMany(),
prisma.entryVersion.deleteMany(),
prisma.entry.deleteMany(),
prisma.patient.deleteMany(),
prisma.room.deleteMany(),
prisma.station.deleteMany(),
prisma.category.deleteMany(),
prisma.user.deleteMany(),
prisma.category.createMany({ data: CATEGORIES }),
prisma.station.createMany({ data: STATIONS }),
prisma.$executeRawUnsafe("alter sequence entries_id_seq restart with 1"),
prisma.$executeRawUnsafe("alter sequence entry_executions_id_seq restart with 1"),
prisma.$executeRawUnsafe("alter sequence entry_versions_id_seq restart with 1"),
]);
// Make generated data reproducible
faker.seed(42);
const filepath = path.join(
fileURLToPath(import.meta.url),
"../mockdata_entries.jsonl",
);
const file = fs.readFileSync(filepath).toString();
const entryMockdata: MockEntry[] = file
.trim()
.split("\n")
.map((l) => JSON.parse(l) as MockEntry);
await prisma.user.create({
data: {
id: 1,
name: "Tico Testboy",
email: "t.testboy@example.com",
},
});
for (let i = 2; i <= N_USERS + 1; i++) {
const firstName = faker.person.firstName();
const lastName = faker.person.lastName();
await prisma.user.create({
data: {
id: i,
name: `${firstName} ${lastName}`,
email: faker.internet.email({ firstName, lastName }),
},
});
}
let i = 1;
for (let sId = 1; sId <= 2; sId++) {
for (let rId = 1; rId <= 10; rId++) {
await prisma.room.create({
data: { id: i, name: `R${sId}.${rId}`, station_id: sId },
});
i += 1;
}
}
for (let i = 1; i <= N_PATIENTS; i++) {
await prisma.patient.create({
data: {
id: i,
first_name: faker.person.firstName(),
last_name: faker.person.lastName(),
age: faker.number.int({ min: 16, max: 100 }),
room_id: randomId(N_ROOMS),
},
});
}
for (let i = 0; i < entryMockdata.length; i++) {
const e = entryMockdata[i];
const created_at = faker.date.soon({ refDate, days: 30 });
const todo_date = faker.date.soon({ refDate: created_at, days: 30 });
const priority = faker.datatype.boolean({ probability: 0.05 });
const entry = await prisma.entry.create({
data: {
patient_id: randomId(N_PATIENTS),
created_at,
},
});
await prisma.entryVersion.create({
data: {
entry_id: entry.id,
author_id: randomUserId(),
category_id: CATEGORY_IDS[e.category],
date: todo_date,
priority,
text: e.description,
},
});
// Add additional version(s) with some extra text
for (let n = 0; n < faker.number.int({ min: 0, max: 3 }); n++) {
const extraText = `\n\n> ${faker.lorem.paragraph()}`;
await prisma.entryVersion.create({
data: {
entry_id: entry.id,
author_id: randomUserId(),
category_id: CATEGORY_IDS[e.category],
date: todo_date,
priority,
text: e.description + extraText,
},
});
}
// 30% of entries are done
if (faker.datatype.boolean({ probability: 0.3 })) {
await prisma.entryExecution.create({
data: {
entry_id: entry.id,
author_id: randomUserId(),
text: e.result,
created_at: faker.date.soon({ refDate: todo_date, days: 2 }),
},
});
}
await prisma.$transaction([
prisma.$executeRawUnsafe(
`alter sequence users_id_seq restart with ${N_USERS + 2}`,
),
prisma.$executeRawUnsafe(
`alter sequence categories_id_seq restart with ${CATEGORIES.length + 1}`,
),
prisma.$executeRawUnsafe(
`alter sequence stations_id_seq restart with ${STATIONS.length + 1}`,
),
prisma.$executeRawUnsafe(
`alter sequence rooms_id_seq restart with ${N_ROOMS + 1}`,
),
prisma.$executeRawUnsafe(
`alter sequence patients_id_seq restart with ${N_PATIENTS + 1}`,
),
]);
}
// eslint-disable-next-line no-console
console.log(`Generated mock data in ${performance.now() - startTime} ms`);
};