Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
217 lines
9.5 KiB
TypeScript
217 lines
9.5 KiB
TypeScript
import { z } from 'zod';
|
|
import { BaseDomainEventPayloadSchema, uuidSchema } from './commonEventPayloadSchemas';
|
|
|
|
const appointmentIdSchema = uuidSchema('Appointment ID');
|
|
const ticketIdSchema = uuidSchema('Ticket ID');
|
|
const scheduleBlockIdSchema = uuidSchema('Schedule Block ID');
|
|
const scheduleEntryIdSchema = uuidSchema('Schedule Entry ID');
|
|
const teamIdSchema = uuidSchema('Team ID');
|
|
const userIdSchema = uuidSchema('User ID');
|
|
const appointmentRequestIdSchema = uuidSchema('Appointment Request ID');
|
|
const serviceIdSchema = uuidSchema('Service ID');
|
|
|
|
const assigneeTypeSchema = z.enum(['user', 'team']).describe('Assignee type');
|
|
const partySchema = z.enum(['customer', 'agent']).describe('No-show party');
|
|
|
|
export const appointmentCreatedEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
appointmentId: appointmentIdSchema,
|
|
ticketId: ticketIdSchema.optional(),
|
|
startAt: z.string().datetime(),
|
|
endAt: z.string().datetime(),
|
|
timezone: z.string().min(1),
|
|
assigneeId: z.string().uuid().optional(),
|
|
assigneeType: assigneeTypeSchema.optional(),
|
|
createdByUserId: userIdSchema.optional(),
|
|
createdAt: z.string().datetime().optional(),
|
|
location: z.string().optional(),
|
|
}).describe('Payload for APPOINTMENT_CREATED');
|
|
|
|
export type AppointmentCreatedEventPayload = z.infer<typeof appointmentCreatedEventPayloadSchema>;
|
|
|
|
export const appointmentRescheduledEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
appointmentId: appointmentIdSchema,
|
|
ticketId: ticketIdSchema.optional(),
|
|
previousStartAt: z.string().datetime(),
|
|
previousEndAt: z.string().datetime(),
|
|
newStartAt: z.string().datetime(),
|
|
newEndAt: z.string().datetime(),
|
|
timezone: z.string().min(1),
|
|
rescheduledAt: z.string().datetime().optional(),
|
|
reason: z.string().optional(),
|
|
}).describe('Payload for APPOINTMENT_RESCHEDULED');
|
|
|
|
export type AppointmentRescheduledEventPayload = z.infer<typeof appointmentRescheduledEventPayloadSchema>;
|
|
|
|
export const appointmentCanceledEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
appointmentId: appointmentIdSchema,
|
|
ticketId: ticketIdSchema.optional(),
|
|
canceledAt: z.string().datetime().optional(),
|
|
reason: z.string().optional(),
|
|
}).describe('Payload for APPOINTMENT_CANCELED');
|
|
|
|
export type AppointmentCanceledEventPayload = z.infer<typeof appointmentCanceledEventPayloadSchema>;
|
|
|
|
export const appointmentCompletedEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
appointmentId: appointmentIdSchema,
|
|
ticketId: ticketIdSchema.optional(),
|
|
completedAt: z.string().datetime().optional(),
|
|
outcome: z.string().optional(),
|
|
}).describe('Payload for APPOINTMENT_COMPLETED');
|
|
|
|
export type AppointmentCompletedEventPayload = z.infer<typeof appointmentCompletedEventPayloadSchema>;
|
|
|
|
export const appointmentNoShowEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
appointmentId: appointmentIdSchema,
|
|
ticketId: ticketIdSchema.optional(),
|
|
markedAt: z.string().datetime().optional(),
|
|
party: partySchema,
|
|
}).describe('Payload for APPOINTMENT_NO_SHOW');
|
|
|
|
export type AppointmentNoShowEventPayload = z.infer<typeof appointmentNoShowEventPayloadSchema>;
|
|
|
|
export const appointmentAssignedEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
appointmentId: appointmentIdSchema,
|
|
ticketId: ticketIdSchema.optional(),
|
|
previousAssigneeId: z.string().uuid().optional(),
|
|
previousAssigneeType: assigneeTypeSchema.optional(),
|
|
newAssigneeId: z.string().uuid(),
|
|
newAssigneeType: assigneeTypeSchema,
|
|
assignedAt: z.string().datetime().optional(),
|
|
}).describe('Payload for APPOINTMENT_ASSIGNED');
|
|
|
|
export type AppointmentAssignedEventPayload = z.infer<typeof appointmentAssignedEventPayloadSchema>;
|
|
|
|
const ownerTypeSchema = z.enum(['user', 'team']).describe('Owner type');
|
|
|
|
export const scheduleBlockCreatedEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
scheduleBlockId: scheduleBlockIdSchema,
|
|
ownerId: z.string().uuid(),
|
|
ownerType: ownerTypeSchema,
|
|
startAt: z.string().datetime(),
|
|
endAt: z.string().datetime(),
|
|
timezone: z.string().min(1),
|
|
createdAt: z.string().datetime().optional(),
|
|
reason: z.string().optional(),
|
|
}).describe('Payload for SCHEDULE_BLOCK_CREATED');
|
|
|
|
export type ScheduleBlockCreatedEventPayload = z.infer<typeof scheduleBlockCreatedEventPayloadSchema>;
|
|
|
|
export const scheduleBlockDeletedEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
scheduleBlockId: scheduleBlockIdSchema,
|
|
deletedAt: z.string().datetime().optional(),
|
|
reason: z.string().optional(),
|
|
}).describe('Payload for SCHEDULE_BLOCK_DELETED');
|
|
|
|
export type ScheduleBlockDeletedEventPayload = z.infer<typeof scheduleBlockDeletedEventPayloadSchema>;
|
|
|
|
export const capacityThresholdReachedEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
teamId: teamIdSchema,
|
|
date: z.string().min(1).describe('Local date (YYYY-MM-DD)'),
|
|
capacityLimit: z.number().nonnegative(),
|
|
currentBooked: z.number().nonnegative(),
|
|
triggeredAt: z.string().datetime().optional(),
|
|
}).describe('Payload for CAPACITY_THRESHOLD_REACHED');
|
|
|
|
export type CapacityThresholdReachedEventPayload = z.infer<typeof capacityThresholdReachedEventPayloadSchema>;
|
|
|
|
export const technicianDispatchedEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
appointmentId: appointmentIdSchema,
|
|
ticketId: ticketIdSchema.optional(),
|
|
technicianUserId: userIdSchema,
|
|
dispatchedByUserId: userIdSchema.optional(),
|
|
dispatchedAt: z.string().datetime().optional(),
|
|
}).describe('Payload for TECHNICIAN_DISPATCHED');
|
|
|
|
export type TechnicianDispatchedEventPayload = z.infer<typeof technicianDispatchedEventPayloadSchema>;
|
|
|
|
export const technicianEnRouteEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
appointmentId: appointmentIdSchema,
|
|
ticketId: ticketIdSchema.optional(),
|
|
technicianUserId: userIdSchema,
|
|
startedAt: z.string().datetime().optional(),
|
|
eta: z.string().datetime().optional(),
|
|
}).describe('Payload for TECHNICIAN_EN_ROUTE');
|
|
|
|
export type TechnicianEnRouteEventPayload = z.infer<typeof technicianEnRouteEventPayloadSchema>;
|
|
|
|
export const technicianArrivedEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
appointmentId: appointmentIdSchema,
|
|
ticketId: ticketIdSchema.optional(),
|
|
technicianUserId: userIdSchema,
|
|
arrivedAt: z.string().datetime().optional(),
|
|
location: z.string().optional(),
|
|
}).describe('Payload for TECHNICIAN_ARRIVED');
|
|
|
|
export type TechnicianArrivedEventPayload = z.infer<typeof technicianArrivedEventPayloadSchema>;
|
|
|
|
export const technicianCheckedOutEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
appointmentId: appointmentIdSchema,
|
|
ticketId: ticketIdSchema.optional(),
|
|
technicianUserId: userIdSchema,
|
|
checkedOutAt: z.string().datetime().optional(),
|
|
workSummary: z.string().optional(),
|
|
}).describe('Payload for TECHNICIAN_CHECKED_OUT');
|
|
|
|
export type TechnicianCheckedOutEventPayload = z.infer<typeof technicianCheckedOutEventPayloadSchema>;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Legacy scheduling events (still used in harness fixtures)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const scheduleEntryEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
entryId: scheduleEntryIdSchema,
|
|
userId: userIdSchema,
|
|
changes: z.record(z.unknown()).optional(),
|
|
}).describe('Payload for schedule entry events (SCHEDULE_ENTRY_*)');
|
|
|
|
export type ScheduleEntryEventPayload = z.infer<typeof scheduleEntryEventPayloadSchema>;
|
|
|
|
export const scheduleEntryCreatedEventPayloadSchema = scheduleEntryEventPayloadSchema.describe(
|
|
'Payload for SCHEDULE_ENTRY_CREATED'
|
|
);
|
|
export const scheduleEntryUpdatedEventPayloadSchema = scheduleEntryEventPayloadSchema.describe(
|
|
'Payload for SCHEDULE_ENTRY_UPDATED'
|
|
);
|
|
export const scheduleEntryDeletedEventPayloadSchema = scheduleEntryEventPayloadSchema.describe(
|
|
'Payload for SCHEDULE_ENTRY_DELETED'
|
|
);
|
|
|
|
export const appointmentRequestEventPayloadSchema = BaseDomainEventPayloadSchema.extend({
|
|
appointmentRequestId: appointmentRequestIdSchema,
|
|
serviceId: serviceIdSchema,
|
|
serviceName: z.string().min(1),
|
|
requestedDate: z.string().min(1),
|
|
requestedTime: z.string().min(1),
|
|
requestedDuration: z.number().int().positive(),
|
|
isAuthenticated: z.boolean(),
|
|
requesterEmail: z.string().email(),
|
|
requesterName: z.string().nullable().optional(),
|
|
requesterPhone: z.string().nullable().optional(),
|
|
clientId: z.string().uuid().optional(),
|
|
contactId: z.string().uuid().optional(),
|
|
clientUserId: z.string().uuid().optional(),
|
|
preferredAssignedUserId: z.string().uuid().optional(),
|
|
companyName: z.string().optional(),
|
|
ticketId: z.string().uuid().optional(),
|
|
description: z.string().optional(),
|
|
approvedByUserId: z.string().uuid().optional(),
|
|
assignedUserId: z.string().uuid().optional(),
|
|
scheduleEntryId: z.string().uuid().optional(),
|
|
declineReason: z.string().optional(),
|
|
}).describe('Payload for appointment request events (APPOINTMENT_REQUEST_*)');
|
|
|
|
export type AppointmentRequestEventPayload = z.infer<typeof appointmentRequestEventPayloadSchema>;
|
|
|
|
export const appointmentRequestCreatedEventPayloadSchema = appointmentRequestEventPayloadSchema.describe(
|
|
'Payload for APPOINTMENT_REQUEST_CREATED'
|
|
);
|
|
export const appointmentRequestApprovedEventPayloadSchema = appointmentRequestEventPayloadSchema.describe(
|
|
'Payload for APPOINTMENT_REQUEST_APPROVED'
|
|
);
|
|
export const appointmentRequestDeclinedEventPayloadSchema = appointmentRequestEventPayloadSchema.describe(
|
|
'Payload for APPOINTMENT_REQUEST_DECLINED'
|
|
);
|
|
export const appointmentRequestCancelledEventPayloadSchema = appointmentRequestEventPayloadSchema.describe(
|
|
'Payload for APPOINTMENT_REQUEST_CANCELLED'
|
|
);
|