Phase 1: Portal Duplication Cleanup - Delete apps/portal/src/lib/ directory (12 duplicate files) - Update imports to use canonical locations (core/, shared/) Phase 2: Domain Package Standardization - Add contract.ts to notifications and checkout modules - Update billing schema to derive enums from contract Phase 3: BFF Error Handling - Remove hardcoded test SIM number from SimValidationService - Use ConfigService for TEST_SIM_ACCOUNT env variable Phase 4: Circular Dependency Resolution - Create VoiceOptionsModule to break FreebitModule <-> SimManagementModule cycle - Remove forwardRef usage between these modules - Move SimVoiceOptionsService to new voice-options module Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
174 lines
5.9 KiB
TypeScript
174 lines
5.9 KiB
TypeScript
/**
|
|
* Notifications Contract
|
|
*
|
|
* Business constants, enums, and templates for in-app notifications.
|
|
*/
|
|
|
|
// =============================================================================
|
|
// Enums
|
|
// =============================================================================
|
|
|
|
export const NOTIFICATION_TYPE = {
|
|
ELIGIBILITY_ELIGIBLE: "ELIGIBILITY_ELIGIBLE",
|
|
ELIGIBILITY_INELIGIBLE: "ELIGIBILITY_INELIGIBLE",
|
|
VERIFICATION_VERIFIED: "VERIFICATION_VERIFIED",
|
|
VERIFICATION_REJECTED: "VERIFICATION_REJECTED",
|
|
ORDER_APPROVED: "ORDER_APPROVED",
|
|
ORDER_ACTIVATED: "ORDER_ACTIVATED",
|
|
ORDER_FAILED: "ORDER_FAILED",
|
|
CANCELLATION_SCHEDULED: "CANCELLATION_SCHEDULED",
|
|
CANCELLATION_COMPLETE: "CANCELLATION_COMPLETE",
|
|
PAYMENT_METHOD_EXPIRING: "PAYMENT_METHOD_EXPIRING",
|
|
INVOICE_DUE: "INVOICE_DUE",
|
|
SYSTEM_ANNOUNCEMENT: "SYSTEM_ANNOUNCEMENT",
|
|
} as const;
|
|
|
|
export type NotificationTypeValue = (typeof NOTIFICATION_TYPE)[keyof typeof NOTIFICATION_TYPE];
|
|
|
|
export const NOTIFICATION_SOURCE = {
|
|
SALESFORCE: "SALESFORCE",
|
|
WHMCS: "WHMCS",
|
|
PORTAL: "PORTAL",
|
|
SYSTEM: "SYSTEM",
|
|
} as const;
|
|
|
|
export type NotificationSourceValue =
|
|
(typeof NOTIFICATION_SOURCE)[keyof typeof NOTIFICATION_SOURCE];
|
|
|
|
// =============================================================================
|
|
// Notification Templates
|
|
// =============================================================================
|
|
|
|
export interface NotificationTemplate {
|
|
type: NotificationTypeValue;
|
|
title: string;
|
|
message: string;
|
|
actionUrl?: string;
|
|
actionLabel?: string;
|
|
priority: "low" | "medium" | "high";
|
|
}
|
|
|
|
export const NOTIFICATION_TEMPLATES: Record<NotificationTypeValue, NotificationTemplate> = {
|
|
[NOTIFICATION_TYPE.ELIGIBILITY_ELIGIBLE]: {
|
|
type: NOTIFICATION_TYPE.ELIGIBILITY_ELIGIBLE,
|
|
title: "Good news! Internet service is available",
|
|
message:
|
|
"We've confirmed internet service is available at your address. You can now select a plan and complete your order.",
|
|
actionUrl: "/account/services/internet",
|
|
actionLabel: "View Plans",
|
|
priority: "high",
|
|
},
|
|
[NOTIFICATION_TYPE.ELIGIBILITY_INELIGIBLE]: {
|
|
type: NOTIFICATION_TYPE.ELIGIBILITY_INELIGIBLE,
|
|
title: "Internet service not available",
|
|
message:
|
|
"Unfortunately, internet service is not currently available at your address. We'll notify you if this changes.",
|
|
actionUrl: "/account/support",
|
|
actionLabel: "Contact Support",
|
|
priority: "high",
|
|
},
|
|
[NOTIFICATION_TYPE.VERIFICATION_VERIFIED]: {
|
|
type: NOTIFICATION_TYPE.VERIFICATION_VERIFIED,
|
|
title: "ID verification complete",
|
|
message: "Your identity has been verified. You can now complete your order.",
|
|
actionUrl: "/account/order",
|
|
actionLabel: "Continue Checkout",
|
|
priority: "high",
|
|
},
|
|
[NOTIFICATION_TYPE.VERIFICATION_REJECTED]: {
|
|
type: NOTIFICATION_TYPE.VERIFICATION_REJECTED,
|
|
title: "ID verification requires attention",
|
|
message: "We couldn't verify your ID. Please review the feedback and resubmit.",
|
|
actionUrl: "/account/settings/verification",
|
|
actionLabel: "Resubmit",
|
|
priority: "high",
|
|
},
|
|
[NOTIFICATION_TYPE.ORDER_APPROVED]: {
|
|
type: NOTIFICATION_TYPE.ORDER_APPROVED,
|
|
title: "Order approved",
|
|
message: "Your order has been approved and is being processed.",
|
|
actionUrl: "/account/orders",
|
|
actionLabel: "View Order",
|
|
priority: "medium",
|
|
},
|
|
[NOTIFICATION_TYPE.ORDER_ACTIVATED]: {
|
|
type: NOTIFICATION_TYPE.ORDER_ACTIVATED,
|
|
title: "Service activated",
|
|
message: "Your service is now active and ready to use.",
|
|
actionUrl: "/account/services",
|
|
actionLabel: "View Service",
|
|
priority: "high",
|
|
},
|
|
[NOTIFICATION_TYPE.ORDER_FAILED]: {
|
|
type: NOTIFICATION_TYPE.ORDER_FAILED,
|
|
title: "Order requires attention",
|
|
message: "There was an issue processing your order. Please contact support.",
|
|
actionUrl: "/account/support",
|
|
actionLabel: "Contact Support",
|
|
priority: "high",
|
|
},
|
|
[NOTIFICATION_TYPE.CANCELLATION_SCHEDULED]: {
|
|
type: NOTIFICATION_TYPE.CANCELLATION_SCHEDULED,
|
|
title: "Cancellation scheduled",
|
|
message: "Your cancellation request has been received and scheduled.",
|
|
actionUrl: "/account/services",
|
|
actionLabel: "View Details",
|
|
priority: "medium",
|
|
},
|
|
[NOTIFICATION_TYPE.CANCELLATION_COMPLETE]: {
|
|
type: NOTIFICATION_TYPE.CANCELLATION_COMPLETE,
|
|
title: "Service cancelled",
|
|
message: "Your service has been successfully cancelled.",
|
|
actionUrl: "/account/services",
|
|
actionLabel: "View Details",
|
|
priority: "medium",
|
|
},
|
|
[NOTIFICATION_TYPE.PAYMENT_METHOD_EXPIRING]: {
|
|
type: NOTIFICATION_TYPE.PAYMENT_METHOD_EXPIRING,
|
|
title: "Payment method expiring soon",
|
|
message:
|
|
"Your payment method is expiring soon. Please update it to avoid service interruption.",
|
|
actionUrl: "/account/billing/payments",
|
|
actionLabel: "Update Payment",
|
|
priority: "high",
|
|
},
|
|
[NOTIFICATION_TYPE.INVOICE_DUE]: {
|
|
type: NOTIFICATION_TYPE.INVOICE_DUE,
|
|
title: "Invoice due",
|
|
message: "You have an invoice due. Please make a payment to keep your service active.",
|
|
actionUrl: "/account/billing/invoices",
|
|
actionLabel: "Pay Now",
|
|
priority: "high",
|
|
},
|
|
[NOTIFICATION_TYPE.SYSTEM_ANNOUNCEMENT]: {
|
|
type: NOTIFICATION_TYPE.SYSTEM_ANNOUNCEMENT,
|
|
title: "System announcement",
|
|
message: "Important information about your service.",
|
|
priority: "low",
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Get notification template by type with optional overrides
|
|
*/
|
|
export function getNotificationTemplate(
|
|
type: NotificationTypeValue,
|
|
overrides?: Partial<NotificationTemplate>
|
|
): NotificationTemplate {
|
|
const template = NOTIFICATION_TEMPLATES[type];
|
|
if (!template) {
|
|
throw new Error(`Unknown notification type: ${type}`);
|
|
}
|
|
return { ...template, ...overrides };
|
|
}
|
|
|
|
// Re-export types from schema
|
|
export type {
|
|
Notification,
|
|
CreateNotificationRequest,
|
|
NotificationListResponse,
|
|
NotificationUnreadCountResponse,
|
|
NotificationQuery,
|
|
NotificationIdParam,
|
|
} from "./schema.js";
|