export const DEFAULT_USER_PASSWORD = '123456' export const MIN_PASSWORD_LENGTH = 8 export const MIN_FULL_NAME_LENGTH = 2 export const USERNAME_PATTERN = /^[a-z0-9._-]{3,32}$/ export const PHONE_NUMBER_PATTERN = /^\+?\d{8,15}$/ export const DEFAULT_PHONE_COUNTRY_CODE = '+60' export type UserRole = 'super_admin' | 'staff' export function normalizeUsername(value: string) { return value.trim().toLowerCase() } export function normalizeFullName(value: string) { return value.trim() } export function normalizePhoneNumber(value: string) { const trimmed = value.trim() if (!trimmed) { return '' } const hasPlusPrefix = trimmed.startsWith('+') const digitsOnly = trimmed.replace(/\D/g, '') if (!digitsOnly) { return '' } if (hasPlusPrefix) { return `+${digitsOnly}` } const defaultCountryDigits = DEFAULT_PHONE_COUNTRY_CODE.replace(/\D/g, '') if (digitsOnly.startsWith(defaultCountryDigits)) { return `+${digitsOnly}` } return `+${defaultCountryDigits}${digitsOnly.replace(/^0+/, '')}` } export function isValidPhoneNumber(value: string) { return PHONE_NUMBER_PATTERN.test(normalizePhoneNumber(value)) } export function isValidUsername(value: string) { return USERNAME_PATTERN.test(normalizeUsername(value)) } export function hasValidFullName(value: string) { return normalizeFullName(value).length >= MIN_FULL_NAME_LENGTH } export function isUserRole(value: string | null | undefined): value is UserRole { return value === 'super_admin' || value === 'staff' } export interface AuthUser { id: string username: string fullName: string phoneNumber: string | null role: UserRole isActive: boolean mustChangePassword: boolean needsPasskeySetup: boolean passkeyCount: number createdAt: string lastLoginAt: string | null } export interface ManagedUser extends AuthUser { createdBy: string | null } export interface PublicContact { id: string fullName: string phoneNumber: string role: UserRole } export interface PasskeySummary { id: string label: string createdAt: string lastUsedAt: string | null deviceType: 'singleDevice' | 'multiDevice' backedUp: boolean } export function needsUserOnboarding( user: Pick | null | undefined ) { return Boolean(user && (user.mustChangePassword || user.needsPasskeySetup)) } export function getDefaultAuthenticatedPath( user: Pick ) { if (needsUserOnboarding(user)) { return '/security' } return user.role === 'super_admin' ? '/management/users' : '/bookings' }