reports: calls per day, missed, busiest hours, queue table
GET /api/reports/summary and /api/reports/queues (company-time-zone days, last 30 by default, a year at most) and the Reports page: totals, stacked bars per day, missed per day, a weekday x hour heatmap and the queue table. Plain divs, no chart library. Task: M11-T6
This commit is contained in:
1 parent
60846afddd
commit
29ee4ba105
13 files changed
+714
-3
No files matched your search
@@ -78,3 +78,19 @@ export type RecordingDto = {
|
||||
toNumber: string | null;
|
||||
} | null;
|
||||
};
|
||||
|
||||
/** GET /api/reports/summary and /api/reports/queues (04 §7.3). Both default to the last 30 days. */
|
||||
export const ReportRangeSchema = z
|
||||
.object({ from: z.iso.date().optional(), to: z.iso.date().optional() })
|
||||
.refine((r) => !r.from || !r.to || r.from <= r.to, { message: 'From is after To' });
|
||||
export type ReportRange = z.input<typeof ReportRangeSchema>;
|
||||
|
||||
export type ReportSummary = {
|
||||
from: string;
|
||||
to: string;
|
||||
/** Every day in the range, empty ones too. Missed = missed, voicemail or abandoned. */
|
||||
days: { date: string; inbound: number; outbound: number; internal: number; missed: number }[];
|
||||
totals: { calls: number; missed: number; avgTalkSeconds: number | null };
|
||||
/** Calls by weekday (0 = Sunday) and hour, in the company time zone: hours[day][hour]. */
|
||||
hours: number[][];
|
||||
};
|
||||
@@ -81,3 +81,11 @@ export type QueueStats = {
|
||||
*/
|
||||
withinSlaPercent: number | null;
|
||||
};
|
||||
|
||||
/** GET /api/reports/queues: one row per queue. */
|
||||
export type QueueReportRow = QueueStats & {
|
||||
id: string;
|
||||
number: string;
|
||||
name: string;
|
||||
slaSeconds: number;
|
||||
};
|
||||
Reference in new issue
Block a user