125 lines
4.5 KiB
TypeScript
Raw Normal View History

/**
* 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,
2026-01-15 12:38:16 +09:00
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>;
2026-01-15 12:38:16 +09:00
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;
}