// User types export const UserType = Object.freeze({ CUSTOMER: 'customer', MITRA: 'mitra', CC_USER: 'cc_user', }) // Chat session statuses export const SessionStatus = Object.freeze({ SEARCHING: 'searching', PENDING_ACCEPTANCE: 'pending_acceptance', PENDING_PAYMENT: 'pending_payment', ACTIVE: 'active', EXTENDING: 'extending', CLOSING: 'closing', COMPLETED: 'completed', CANCELLED: 'cancelled', EXPIRED: 'expired', }) // Chat message statuses export const MessageStatus = Object.freeze({ SENT: 'sent', DELIVERED: 'delivered', READ: 'read', }) // Chat message types export const MessageType = Object.freeze({ TEXT: 'text', }) // Chat request notification responses export const NotificationResponse = Object.freeze({ ACCEPTED: 'accepted', DECLINED: 'declined', MISSED: 'missed', IGNORED: 'ignored', }) // Session extension statuses export const ExtensionStatus = Object.freeze({ PENDING: 'pending', ACCEPTED: 'accepted', REJECTED: 'rejected', TIMEOUT: 'timeout', }) // Customer transaction types export const TransactionType = Object.freeze({ FREE_TRIAL: 'free_trial', PAID: 'paid', EXTENSION: 'extension', }) // Payment session lifecycle export const PaymentSessionStatus = Object.freeze({ PENDING: 'pending', CONFIRMED: 'confirmed', CONSUMED: 'consumed', FAILED_PAIRING: 'failed_pairing', ABANDONED: 'abandoned', EXPIRED: 'expired', }) // Pairing failure cause tags export const PairingFailureCause = Object.freeze({ NO_MITRA_AVAILABLE: 'no_mitra_available', ALL_MITRAS_REJECTED: 'all_mitras_rejected', TARGETED_MITRA_OFFLINE: 'targeted_mitra_offline', TARGETED_MITRA_REJECTED: 'targeted_mitra_rejected', TARGETED_MITRA_TIMEOUT: 'targeted_mitra_timeout', PAYMENT_SESSION_EXPIRED: 'payment_session_expired', CUSTOMER_CANCELLED: 'customer_cancelled', EXTENSION_REJECTED: 'extension_rejected', EXTENSION_SAFEGUARD_TRIPPED: 'extension_safeguard_tripped', }) // Operator actions on failed-pairing rows export const PairingFailureOperatorAction = Object.freeze({ REFUNDED: 'refunded', CREDITED: 'credited', NO_ACTION: 'no_action', }) // Default action when extension request times out (configurable) export const ExtensionTimeoutAction = Object.freeze({ AUTO_APPROVE: 'auto_approve', AUTO_REJECT: 'auto_reject', }) // Pairing request type — distinguishes general blast from targeted "Curhat lagi" export const PairingRequestType = Object.freeze({ GENERAL: 'general', RETURNING: 'returning', }) // Who ended a session export const EndedBy = Object.freeze({ SYSTEM: 'system', SYSTEM_AUTO_CLOSE: 'system_auto_close', CUSTOMER: 'customer', MITRA: 'mitra', }) // Session topic sensitivity export const TopicSensitivity = Object.freeze({ REGULAR: 'regular', SENSITIVE: 'sensitive', }) // Auth provider used to establish a session export const AuthProvider = Object.freeze({ ANONYMOUS: 'anonymous', PHONE: 'phone', GOOGLE: 'google', APPLE: 'apple', PASSWORD: 'password', }) // OTP delivery channel export const OtpChannel = Object.freeze({ WHATSAPP: 'whatsapp', SMS: 'sms', }) // WebSocket message types export const WsMessage = Object.freeze({ // Auth AUTH: 'auth', AUTH_OK: 'auth_ok', ERROR: 'error', // Chat MESSAGE: 'message', MESSAGE_ACK: 'message_ack', MESSAGE_STATUS: 'message_status', TYPING: 'typing', // Pairing CHAT_REQUEST: 'chat_request', CHAT_REQUEST_CLOSED: 'chat_request_closed', PAIRED: 'paired', // Session lifecycle SESSION_TIMER: 'session_timer', SESSION_EXPIRED: 'session_expired', SESSION_CLOSING: 'session_closing', SESSION_COMPLETED: 'session_completed', SESSION_ENDED: 'session_ended', SESSION_PAUSED: 'session_paused', SESSION_RESUMED: 'session_resumed', SESSION_ASSIGNED: 'session_assigned', SESSION_REROUTED: 'session_rerouted', REROUTED: 'rerouted', // Extension EXTENSION_REQUEST: 'extension_request', EXTENSION_RESPONSE: 'extension_response', // Returning-chat RETURNING_CHAT_TIMEOUT: 'returning_chat_timeout', RETURNING_CHAT_REJECTED: 'returning_chat_rejected', // Sent when the customer is sitting in a searching/waiting state and the server terminates // the payment session out from under them (general blast exhausts, payment expires mid-search, // etc). NOT used for intermediate failures like targeted reject/timeout — those use // RETURNING_CHAT_* events instead. PAIRING_FAILED: 'pairing_failed', // Topic sensitivity SESSION_TOPIC_UPDATED: 'session_topic_updated', // Early end EARLY_END: 'early_end', // Delivery DELIVERED: 'delivered', READ: 'read', })