import 'package:freezed_annotation/freezed_annotation.dart'; part 'user_model.freezed.dart'; part 'user_model.g.dart'; /// 사용자 도메인 엔티티 (백엔드 호환 + UI 필드) /// 백엔드 users 테이블: id, name, phone, email, companies_id @freezed class User with _$User { const factory User({ /// 사용자 ID (자동 생성) int? id, /// 이름 (필수) required String name, /// 이메일 (선택) String? email, /// 전화번호 (선택, "010-1234-5678" 형태) String? phone, /// 소속 회사명 (UI 표시용, 백엔드 미저장) String? companyName, /// UI용 필드들 (백엔드 저장하지 않음) @Default('') String username, // UI 호환용 @Default(UserRole.staff) UserRole role, // UI 호환용 @Default(true) bool isActive, // UI 호환용 DateTime? createdAt, // UI 호환용 DateTime? updatedAt, // UI 호환용 }) = _User; factory User.fromJson(Map json) => _$UserFromJson(json); } /// 사용자 권한 열거형 (UI 호환용) @JsonEnum() enum UserRole { @JsonValue('admin') admin, @JsonValue('manager') manager, @JsonValue('staff') staff; String get displayName { switch (this) { case UserRole.admin: return '관리자'; case UserRole.manager: return '매니저'; case UserRole.staff: return '직원'; } } /// 문자열로부터 UserRole 생성 static UserRole fromString(String value) { switch (value.toLowerCase()) { case 'admin': return UserRole.admin; case 'manager': return UserRole.manager; case 'staff': return UserRole.staff; default: return UserRole.staff; } } } /// 전화번호 유틸리티 class PhoneNumberUtil { /// 전화번호 형식 검증 (010-1234-5678) static bool isValidFormat(String phone) { final regex = RegExp(r'^\d{3}-\d{3,4}-\d{4}$'); return regex.hasMatch(phone); } /// 전화번호 포맷팅 (01012345678 → 010-1234-5678) static String format(String phone) { final cleanPhone = phone.replaceAll(RegExp(r'[^\d]'), ''); if (cleanPhone.length == 10) { return '${cleanPhone.substring(0, 3)}-${cleanPhone.substring(3, 6)}-${cleanPhone.substring(6)}'; } else if (cleanPhone.length == 11) { return '${cleanPhone.substring(0, 3)}-${cleanPhone.substring(3, 7)}-${cleanPhone.substring(7)}'; } return phone; // 형식이 맞지 않으면 원본 반환 } /// UI용 전화번호 분리 (010-1234-5678 → {prefix: "010", number: "12345678"}) static Map splitForUI(String? phone) { if (phone == null || phone.isEmpty) { return {'prefix': '010', 'number': ''}; } final parts = phone.split('-'); if (parts.length >= 2) { return { 'prefix': parts[0], 'number': parts.sublist(1).join(''), }; } return {'prefix': '010', 'number': phone}; } /// UI에서 서버용 전화번호 조합 ({prefix: "010", number: "12345678"} → "010-1234-5678") static String combineFromUI(String? prefix, String? number) { if (prefix == null || prefix.isEmpty || number == null || number.isEmpty) return ''; final cleanNumber = number.replaceAll(RegExp(r'[^\d]'), ''); if (cleanNumber.length == 7) { return '$prefix-${cleanNumber.substring(0, 3)}-${cleanNumber.substring(3)}'; } else if (cleanNumber.length == 8) { return '$prefix-${cleanNumber.substring(0, 4)}-${cleanNumber.substring(4)}'; } return '$prefix-$cleanNumber'; } }