|
| 1 | +import { z } from "zod" |
| 2 | +import { ReportEventKind, ReportPriority, ReportStatus } from "./reports" |
| 3 | + |
| 4 | +// Minimal per-row shape for /admin's recent-reports list. Purpose-built |
| 5 | +// (NOT an extension of ReportSummaryDTO) because the admin row only |
| 6 | +// renders title + priority + project + timestamp — there's no need to |
| 7 | +// ship context/pageUrl/tags/assignee for a 10-row glance list. |
| 8 | +export const AdminRecentReportDTO = z.object({ |
| 9 | + id: z.uuid(), |
| 10 | + projectId: z.uuid(), |
| 11 | + projectName: z.string(), |
| 12 | + title: z.string(), |
| 13 | + status: ReportStatus, |
| 14 | + priority: ReportPriority, |
| 15 | + receivedAt: z.string(), |
| 16 | +}) |
| 17 | +export type AdminRecentReportDTO = z.infer<typeof AdminRecentReportDTO> |
| 18 | + |
| 19 | +// Mirrors ProjectOverviewDTO.recentEvents but carries project context per row. |
| 20 | +// Kind enum matches the per-project overview exactly. |
| 21 | +export const AdminRecentEventDTO = z.object({ |
| 22 | + id: z.uuid(), |
| 23 | + reportId: z.uuid(), |
| 24 | + reportTitle: z.string(), |
| 25 | + projectId: z.uuid(), |
| 26 | + projectName: z.string(), |
| 27 | + kind: ReportEventKind, |
| 28 | + payload: z.record(z.string(), z.unknown()), |
| 29 | + actor: z |
| 30 | + .object({ |
| 31 | + id: z.string(), |
| 32 | + email: z.email(), |
| 33 | + name: z.string().nullable(), |
| 34 | + }) |
| 35 | + .nullable(), |
| 36 | + createdAt: z.string(), |
| 37 | +}) |
| 38 | +export type AdminRecentEventDTO = z.infer<typeof AdminRecentEventDTO> |
| 39 | + |
| 40 | +export const AdminProjectBreakdownDTO = z.object({ |
| 41 | + id: z.uuid(), |
| 42 | + name: z.string(), |
| 43 | + openCount: z.number().int(), |
| 44 | + newLast7Count: z.number().int(), |
| 45 | + totalCount: z.number().int(), |
| 46 | +}) |
| 47 | +export type AdminProjectBreakdownDTO = z.infer<typeof AdminProjectBreakdownDTO> |
| 48 | + |
| 49 | +export const AdminOverviewDTO = z.object({ |
| 50 | + counts: z.object({ |
| 51 | + total: z.number().int(), |
| 52 | + byStatus: z.record(ReportStatus, z.number().int()), |
| 53 | + byPriority: z.record(ReportPriority, z.number().int()), |
| 54 | + last7Days: z.number().int(), |
| 55 | + }), |
| 56 | + projects: z.object({ |
| 57 | + total: z.number().int(), |
| 58 | + withGithub: z.number().int(), |
| 59 | + }), |
| 60 | + recentReports: z.array(AdminRecentReportDTO), |
| 61 | + recentEvents: z.array(AdminRecentEventDTO), |
| 62 | + perProject: z.array(AdminProjectBreakdownDTO), |
| 63 | +}) |
| 64 | +export type AdminOverviewDTO = z.infer<typeof AdminOverviewDTO> |
0 commit comments