Skip to content

Commit f76efdb

Browse files
committed
feat(shared): add AdminOverviewDTO for admin overview dashboard
1 parent 701f9a7 commit f76efdb

2 files changed

Lines changed: 65 additions & 0 deletions

File tree

packages/shared/src/admin.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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>

packages/shared/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export * from "./users"
44
export * from "./settings"
55
export * from "./reports"
66
export * from "./github"
7+
export * from "./admin"

0 commit comments

Comments
 (0)