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
100 lines
3.2 KiB
TypeScript
100 lines
3.2 KiB
TypeScript
function requireNonEmpty(value: string, field: string): string {
|
|
if (!value) throw new Error(`${field} is required`);
|
|
return value;
|
|
}
|
|
|
|
function withOptionalTimestamp(field: string, value?: string): Record<string, unknown> {
|
|
return value ? { [field]: value } : {};
|
|
}
|
|
|
|
export type NotificationChannel = 'email' | 'sms' | 'in_app' | 'push' | 'teams';
|
|
|
|
export function buildNotificationSentPayload(params: {
|
|
notificationId: string;
|
|
channel: NotificationChannel;
|
|
recipientId: string;
|
|
sentAt?: string;
|
|
templateId?: string;
|
|
contextType?: string;
|
|
contextId?: string;
|
|
}): Record<string, unknown> {
|
|
requireNonEmpty(params.notificationId, 'notificationId');
|
|
requireNonEmpty(params.channel, 'channel');
|
|
requireNonEmpty(params.recipientId, 'recipientId');
|
|
|
|
return {
|
|
notificationId: params.notificationId,
|
|
channel: params.channel,
|
|
recipientId: params.recipientId,
|
|
...withOptionalTimestamp('sentAt', params.sentAt),
|
|
...(params.templateId ? { templateId: params.templateId } : {}),
|
|
...(params.contextType ? { contextType: params.contextType } : {}),
|
|
...(params.contextId ? { contextId: params.contextId } : {}),
|
|
};
|
|
}
|
|
|
|
export function buildNotificationDeliveredPayload(params: {
|
|
notificationId: string;
|
|
channel: NotificationChannel;
|
|
recipientId: string;
|
|
deliveredAt?: string;
|
|
providerMessageId?: string;
|
|
}): Record<string, unknown> {
|
|
requireNonEmpty(params.notificationId, 'notificationId');
|
|
requireNonEmpty(params.channel, 'channel');
|
|
requireNonEmpty(params.recipientId, 'recipientId');
|
|
|
|
return {
|
|
notificationId: params.notificationId,
|
|
channel: params.channel,
|
|
recipientId: params.recipientId,
|
|
...withOptionalTimestamp('deliveredAt', params.deliveredAt),
|
|
...(params.providerMessageId ? { providerMessageId: params.providerMessageId } : {}),
|
|
};
|
|
}
|
|
|
|
export function buildNotificationFailedPayload(params: {
|
|
notificationId: string;
|
|
channel: NotificationChannel;
|
|
recipientId: string;
|
|
failedAt?: string;
|
|
errorCode?: string;
|
|
errorMessage: string;
|
|
retryable?: boolean;
|
|
}): Record<string, unknown> {
|
|
requireNonEmpty(params.notificationId, 'notificationId');
|
|
requireNonEmpty(params.channel, 'channel');
|
|
requireNonEmpty(params.recipientId, 'recipientId');
|
|
requireNonEmpty(params.errorMessage, 'errorMessage');
|
|
|
|
return {
|
|
notificationId: params.notificationId,
|
|
channel: params.channel,
|
|
recipientId: params.recipientId,
|
|
...withOptionalTimestamp('failedAt', params.failedAt),
|
|
...(params.errorCode ? { errorCode: params.errorCode } : {}),
|
|
errorMessage: params.errorMessage,
|
|
...(typeof params.retryable === 'boolean' ? { retryable: params.retryable } : {}),
|
|
};
|
|
}
|
|
|
|
export function buildNotificationReadPayload(params: {
|
|
notificationId: string;
|
|
channel: NotificationChannel;
|
|
recipientId: string;
|
|
readAt?: string;
|
|
client?: string;
|
|
}): Record<string, unknown> {
|
|
requireNonEmpty(params.notificationId, 'notificationId');
|
|
requireNonEmpty(params.channel, 'channel');
|
|
requireNonEmpty(params.recipientId, 'recipientId');
|
|
|
|
return {
|
|
notificationId: params.notificationId,
|
|
channel: params.channel,
|
|
recipientId: params.recipientId,
|
|
...withOptionalTimestamp('readAt', params.readAt),
|
|
...(params.client ? { client: params.client } : {}),
|
|
};
|
|
}
|