me: call report email (hourly, daily, weekly), with call summaries
ci / check (push) Successful in 1m14s
ci / images (push) Successful in 40s
ci / check (pull_request) Successful in 59s
ci / images (pull_request) Successful in 4s

My settings → Call report: each user's calls of the last hour, day (at a time) or week (on a
day at a time), company time zone: numbers, status, talk time, recorded, and optionally each
recorded call's summary (10 §3). No calls, no email. Job callReports every minute, 5 min after
the period ends; periods computed in PostgreSQL (DST-safe). Migration 0008_call_reports.
This commit is contained in:
iamdoubz committed 2026-10-23 13:55:47 -05:00
1 parent 46cc8c2002
commit 4c006f2388
16 files changed
+4691 -9

No files matched your search

+18
View File
@@ -10,6 +10,10 @@ const ForwardInput = z
.regex(/^[0-9*#+()\s.-]*[0-9][0-9*#+()\s.-]*$/, 'A number like 101 or (312) 555-1234')
.nullable();
/** How often the call report email goes out (05 §4), in the company time zone. */
export const CALL_REPORTS = ['off', 'hourly', 'daily', 'weekly'] as const;
export type CallReport = (typeof CALL_REPORTS)[number];
export const MeUpdateSchema = z.object({
dnd: z.boolean().optional(),
/** Forward always / when busy / when not answered. */
@@ -23,6 +27,16 @@ export const MeUpdateSchema = z.object({
.string()
.regex(/^\d{4,10}$/, 'Use 4 to 10 digits')
.optional(),
callReport: z.enum(CALL_REPORTS).optional(),
/** HH:MM, for daily and weekly. */
callReportTime: z
.string()
.regex(/^([01]\d|2[0-3]):[0-5]\d$/, 'A time like 08:00')
.optional(),
/** 0 = Sunday, for weekly. */
callReportWeekday: z.number().int().min(0).max(6).optional(),
/** Each recorded call's summary too (spec 10 §3). */
callReportSummaries: z.boolean().optional(),
});
export type MeUpdate = z.input<typeof MeUpdateSchema>;
@@ -37,4 +51,8 @@ export type MeDto = {
voicemailEmail: boolean;
voicemailAttachAudio: boolean;
voicemailDeleteAfterEmail: boolean;
callReport: CallReport;
callReportTime: string;
callReportWeekday: number;
callReportSummaries: boolean;
};