barsa 464f98284a feat(eligibility): add address key field for Salesforce Flow duplicate detection
Add Eligibility_Address_Key__c field (postcode:streetAddress format) to Case records
for eligibility check requests. Salesforce Flow will use this field to detect duplicate
requests for the same address within a time period.

Changes:
- Add eligibilityAddressKey to CreateCaseParams and CASE_FIELDS mapping
- Add streetAddress param to EligibilityCheckCaseParams for passing from callers
- Add createAddressKey() helper in WorkflowCaseManager to generate the key
- Update raw.types.ts schema with new field
- Note in internet-eligibility.service.ts that basic flow skips duplicate detection
2026-01-20 19:00:09 +09:00

125 lines
4.5 KiB
TypeScript

/**
* Get Started Domain - Contract
*
* Types and constants for the unified "Get Started" flow that handles:
* - Email verification (OTP)
* - Account status detection
* - Guest eligibility check (no OTP required)
* - Account completion for SF-only accounts
* - Signup with eligibility (full flow)
*/
import type { z } from "zod";
import type {
sendVerificationCodeRequestSchema,
sendVerificationCodeResponseSchema,
verifyCodeRequestSchema,
verifyCodeResponseSchema,
bilingualEligibilityAddressSchema,
guestEligibilityRequestSchema,
guestEligibilityResponseSchema,
guestHandoffTokenSchema,
completeAccountRequestSchema,
signupWithEligibilityRequestSchema,
signupWithEligibilityResponseSchema,
migrateWhmcsAccountRequestSchema,
getStartedSessionSchema,
} from "./schema.js";
// ============================================================================
// Constants
// ============================================================================
/**
* Account status after email verification
* Determines which flow the user should follow
*/
export const ACCOUNT_STATUS = {
/** User has a portal account - redirect to login */
PORTAL_EXISTS: "portal_exists",
/** User has WHMCS account but no portal - migrate flow */
WHMCS_UNMAPPED: "whmcs_unmapped",
/** User has SF account but no WHMCS/portal - complete account flow */
SF_UNMAPPED: "sf_unmapped",
/** No account exists - full signup flow */
NEW_CUSTOMER: "new_customer",
} as const;
export type AccountStatus = (typeof ACCOUNT_STATUS)[keyof typeof ACCOUNT_STATUS];
/**
* OTP verification error codes
*/
export const OTP_ERROR_CODE = {
/** Code has expired */
EXPIRED: "otp_expired",
/** Invalid code entered */
INVALID: "otp_invalid",
/** Too many failed attempts */
MAX_ATTEMPTS: "otp_max_attempts",
/** Rate limit exceeded for sending codes */
RATE_LIMITED: "otp_rate_limited",
} as const;
export type OtpErrorCode = (typeof OTP_ERROR_CODE)[keyof typeof OTP_ERROR_CODE];
/**
* Get Started flow error codes
*/
export const GET_STARTED_ERROR_CODE = {
/** Session token is invalid or expired */
INVALID_SESSION: "invalid_session",
/** Email not verified yet */
EMAIL_NOT_VERIFIED: "email_not_verified",
/** SF account creation failed */
SF_CREATION_FAILED: "sf_creation_failed",
/** WHMCS account creation failed */
WHMCS_CREATION_FAILED: "whmcs_creation_failed",
} as const;
export type GetStartedErrorCode =
(typeof GET_STARTED_ERROR_CODE)[keyof typeof GET_STARTED_ERROR_CODE];
// ============================================================================
// Request Types
// ============================================================================
export type SendVerificationCodeRequest = z.infer<typeof sendVerificationCodeRequestSchema>;
export type VerifyCodeRequest = z.infer<typeof verifyCodeRequestSchema>;
export type BilingualEligibilityAddress = z.infer<typeof bilingualEligibilityAddressSchema>;
export type GuestEligibilityRequest = z.infer<typeof guestEligibilityRequestSchema>;
export type CompleteAccountRequest = z.infer<typeof completeAccountRequestSchema>;
export type SignupWithEligibilityRequest = z.infer<typeof signupWithEligibilityRequestSchema>;
export type MigrateWhmcsAccountRequest = z.infer<typeof migrateWhmcsAccountRequestSchema>;
// ============================================================================
// Response Types
// ============================================================================
export type SendVerificationCodeResponse = z.infer<typeof sendVerificationCodeResponseSchema>;
export type VerifyCodeResponse = z.infer<typeof verifyCodeResponseSchema>;
export type GuestEligibilityResponse = z.infer<typeof guestEligibilityResponseSchema>;
export type SignupWithEligibilityResponse = z.infer<typeof signupWithEligibilityResponseSchema>;
// ============================================================================
// Handoff Token Types
// ============================================================================
export type GuestHandoffToken = z.infer<typeof guestHandoffTokenSchema>;
// ============================================================================
// Session Types
// ============================================================================
export type GetStartedSession = z.infer<typeof getStartedSessionSchema>;
// ============================================================================
// Error Types
// ============================================================================
export interface GetStartedError {
code: OtpErrorCode | GetStartedErrorCode;
message: string;
}