35 lines
1.1 KiB
TypeScript
35 lines
1.1 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
const CapturePayload = z.object({
|
|
noteId: z.string().min(1),
|
|
rawTextLength: z.number().int().nonnegative(),
|
|
hasMedia: z.boolean()
|
|
}).strict();
|
|
|
|
const AiSucceededPayload = z.object({
|
|
noteId: z.string().min(1),
|
|
durationMs: z.number().nonnegative(),
|
|
attempts: z.number().int().nonnegative()
|
|
}).strict();
|
|
|
|
const AiFailedReason = z.enum(['unreachable', 'schema', 'timeout', 'other']);
|
|
|
|
const AiFailedPayload = z.object({
|
|
noteId: z.string().min(1),
|
|
reason: AiFailedReason,
|
|
attempts: z.number().int().nonnegative()
|
|
}).strict();
|
|
|
|
export const TelemetryEventSchema = z.discriminatedUnion('kind', [
|
|
z.object({ ts: z.string(), kind: z.literal('capture'), payload: CapturePayload }).strict(),
|
|
z.object({ ts: z.string(), kind: z.literal('ai_succeeded'), payload: AiSucceededPayload }).strict(),
|
|
z.object({ ts: z.string(), kind: z.literal('ai_failed'), payload: AiFailedPayload }).strict()
|
|
]);
|
|
|
|
export type TelemetryEvent = z.infer<typeof TelemetryEventSchema>;
|
|
export type TelemetryKind = TelemetryEvent['kind'];
|
|
|
|
export function validateEvent(raw: unknown): TelemetryEvent {
|
|
return TelemetryEventSchema.parse(raw);
|
|
}
|