mirror of
https://github.com/Sea-Haven-Industries/seahaven-ap.git
synced 2026-09-30 03:23:16 +00:00
* feat(api): stand up Hono Drizzle foundation with auth and Redocly * fix(api): bump drizzle-orm and hono node-server past audit highs * fix(api): harden auth upsert and Cognito token verification
161 lines
4.1 KiB
TypeScript
161 lines
4.1 KiB
TypeScript
import { faker } from "@faker-js/faker";
|
|
import { closeDb, createDb } from "./client.js";
|
|
import { loadEnv, USER_ROLES, type UserRole } from "../env.js";
|
|
import {
|
|
activityLog,
|
|
approvalPolicies,
|
|
approvalSteps,
|
|
departments,
|
|
documents,
|
|
glAccounts,
|
|
invoiceComments,
|
|
invoiceLines,
|
|
invoices,
|
|
payRuns,
|
|
payments,
|
|
users,
|
|
vendors,
|
|
} from "./schema/index.js";
|
|
|
|
/** Stable UUIDs so re-seeds and docs stay deterministic. */
|
|
const IDS = {
|
|
users: {
|
|
admin: "11111111-1111-4111-8111-111111111111",
|
|
ap_processor: "22222222-2222-4222-8222-222222222222",
|
|
approver: "33333333-3333-4333-8333-333333333333",
|
|
viewer: "44444444-4444-4444-8444-444444444444",
|
|
} satisfies Record<UserRole, string>,
|
|
vendor: "55555555-5555-4555-8555-555555555555",
|
|
gl: "66666666-6666-4666-8666-666666666666",
|
|
department: "77777777-7777-4777-8777-777777777777",
|
|
invoice: "88888888-8888-4888-8888-888888888888",
|
|
line: "99999999-9999-4999-8999-999999999999",
|
|
comment: "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
|
|
activity: "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
|
|
policy: "cccccccc-cccc-4ccc-8ccc-cccccccccccc",
|
|
document: "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
|
|
} as const;
|
|
|
|
const ROLE_EMAIL: Record<UserRole, string> = {
|
|
admin: "admin@seahavenind.com",
|
|
ap_processor: "ap.processor@seahavenind.com",
|
|
approver: "approver@seahavenind.com",
|
|
viewer: "viewer@seahavenind.com",
|
|
};
|
|
|
|
export async function seedDatabase(): Promise<void> {
|
|
faker.seed(14);
|
|
|
|
const env = loadEnv({
|
|
...process.env,
|
|
DEV_AUTH_BYPASS: process.env.DEV_AUTH_BYPASS ?? "true",
|
|
});
|
|
const handle = createDb(env);
|
|
const { db } = handle;
|
|
|
|
await db.delete(documents);
|
|
await db.delete(activityLog);
|
|
await db.delete(invoiceComments);
|
|
await db.delete(invoiceLines);
|
|
await db.delete(approvalSteps);
|
|
await db.delete(payments);
|
|
await db.delete(payRuns);
|
|
await db.delete(invoices);
|
|
await db.delete(approvalPolicies);
|
|
await db.delete(departments);
|
|
await db.delete(glAccounts);
|
|
await db.delete(vendors);
|
|
await db.delete(users);
|
|
|
|
await db.insert(users).values(
|
|
USER_ROLES.map((role) => ({
|
|
id: IDS.users[role],
|
|
cognitoSub: `seed-sub-${role}`,
|
|
email: ROLE_EMAIL[role],
|
|
name: faker.person.fullName(),
|
|
role,
|
|
})),
|
|
);
|
|
|
|
await db.insert(vendors).values({
|
|
id: IDS.vendor,
|
|
name: "Acme Facilities Supply",
|
|
email: "billing@acmefacilities.example",
|
|
defaultPaymentMethod: "check",
|
|
});
|
|
|
|
await db.insert(glAccounts).values({
|
|
id: IDS.gl,
|
|
code: "6100",
|
|
name: "Facilities Expense",
|
|
});
|
|
|
|
await db.insert(departments).values({
|
|
id: IDS.department,
|
|
code: "OPS",
|
|
name: "Operations",
|
|
});
|
|
|
|
await db.insert(approvalPolicies).values({
|
|
id: IDS.policy,
|
|
name: "Default approver policy",
|
|
priority: 10,
|
|
amountThreshold: "0.00",
|
|
skipBelowAmount: "25.00",
|
|
active: true,
|
|
});
|
|
|
|
await db.insert(invoices).values({
|
|
id: IDS.invoice,
|
|
vendorId: IDS.vendor,
|
|
invoiceNumber: "INV-1001",
|
|
amount: "1250.00",
|
|
amountDue: "1250.00",
|
|
dueDate: "2026-09-01",
|
|
payDate: null,
|
|
sendPaymentOn: null,
|
|
status: "pending_approval",
|
|
paymentMethod: "check",
|
|
memo: "Seed invoice for local smoke.",
|
|
});
|
|
|
|
await db.insert(invoiceLines).values({
|
|
id: IDS.line,
|
|
invoiceId: IDS.invoice,
|
|
description: "Monthly maintenance",
|
|
amount: "1250.00",
|
|
glAccountId: IDS.gl,
|
|
departmentId: IDS.department,
|
|
});
|
|
|
|
await db.insert(invoiceComments).values({
|
|
id: IDS.comment,
|
|
invoiceId: IDS.invoice,
|
|
authorUserId: IDS.users.ap_processor,
|
|
body: "Seed comment on INV-1001.",
|
|
});
|
|
|
|
await db.insert(activityLog).values({
|
|
id: IDS.activity,
|
|
invoiceId: IDS.invoice,
|
|
actorUserId: IDS.users.ap_processor,
|
|
message: "Invoice created from seed.",
|
|
});
|
|
|
|
await db.insert(documents).values({
|
|
id: IDS.document,
|
|
invoiceId: IDS.invoice,
|
|
objectKey: "seed/inv-1001.pdf",
|
|
contentType: "application/pdf",
|
|
fileName: "inv-1001.pdf",
|
|
uploadedByUserId: IDS.users.ap_processor,
|
|
});
|
|
|
|
await closeDb(handle);
|
|
console.log("Seed applied (faker seed=14).");
|
|
}
|
|
|
|
seedDatabase().catch((error: unknown) => {
|
|
console.error(error);
|
|
process.exitCode = 1;
|
|
});
|