feat: implement security report generation backend (task 21)
- Add report-schedules DB schema table - Create reports tRPC router with getReports, generateReport, getReport, deleteReport, getScheduledReports, updateSchedule procedures - Create reports service with async report generation lifecycle - Create report generator (compileData, renderHTML, generatePDF, uploadPDF) - Add HTML templates for monthly-plus, annual-premium, weekly-digest - Add Valibot schemas for input validation - Wire router into root.ts and update DB schema exports/relations - Install puppeteer for HTML-to-PDF conversion - Write unit tests for router (11 tests) and service (12 tests)
This commit is contained in:
18
web/src/server/db/schema/report-schedules.ts
Normal file
18
web/src/server/db/schema/report-schedules.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { pgTable, text, timestamp, index, uuid, boolean } from "drizzle-orm/pg-core";
|
||||
import { users } from "./auth";
|
||||
import { reportType } from "./enums";
|
||||
|
||||
export const reportSchedules = pgTable("report_schedules", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
||||
enabled: boolean("enabled").default(true).notNull(),
|
||||
frequency: text("frequency").notNull(),
|
||||
reportType: reportType("report_type").notNull(),
|
||||
lastGeneratedAt: timestamp("last_generated_at", { withTimezone: true, mode: "date" }),
|
||||
nextScheduledAt: timestamp("next_scheduled_at", { withTimezone: true, mode: "date" }),
|
||||
createdAt: timestamp("created_at", { withTimezone: true, mode: "date" }).defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at", { withTimezone: true, mode: "date" }).defaultNow().notNull().$onUpdate(() => new Date()),
|
||||
}, (table) => ({
|
||||
userIdIdx: index("report_schedules_user_id_idx").on(table.userId),
|
||||
enabledIdx: index("report_schedules_enabled_idx").on(table.enabled),
|
||||
}));
|
||||
Reference in New Issue
Block a user