import 'package:freezed_annotation/freezed_annotation.dart'; import '../../../models/user_model.dart'; part 'user_dto.freezed.dart'; part 'user_dto.g.dart'; /// 사용자 데이터 전송 객체 (서버 API v0.2.1 대응) /// GET /api/v1/users/{id} 응답 형태 @freezed class UserDto with _$UserDto { const UserDto._(); const factory UserDto({ /// 사용자 ID (자동 생성) required int id, /// 사용자명 (유니크, 필수) required String username, /// 이름 (필수) required String name, /// 이메일 (유니크, 필수) required String email, /// 전화번호 (선택) String? phone, /// 권한 (admin, manager, staff) required String role, /// 활성화 상태 (기본값: true) @JsonKey(name: 'is_active') required bool isActive, /// 생성일시 (자동 입력) @JsonKey(name: 'created_at') required DateTime createdAt, /// 수정일시 (자동 갱신, 선택적) @JsonKey(name: 'updated_at') DateTime? updatedAt, }) = _UserDto; factory UserDto.fromJson(Map json) => _$UserDtoFromJson(json); /// DTO를 도메인 모델로 변환 User toDomainModel() { return User( id: id, username: username, email: email, name: name, phone: phone, role: UserRole.fromString(role), isActive: isActive, createdAt: createdAt, updatedAt: updatedAt, ); } } /// 사용자 생성 요청 DTO (POST /api/v1/users) @freezed class CreateUserRequest with _$CreateUserRequest { const factory CreateUserRequest({ /// 사용자명 (필수, 유니크, 3자 이상) required String username, /// 이메일 (필수, 유니크, 이메일 형식) required String email, /// 비밀번호 (필수, 6자 이상) required String password, /// 이름 (필수) required String name, /// 전화번호 (선택, "010-1234-5678" 형태) String? phone, /// 권한 (필수: admin, manager, staff) required String role, }) = _CreateUserRequest; factory CreateUserRequest.fromJson(Map json) => _$CreateUserRequestFromJson(json); /// 도메인 모델에서 생성 요청 DTO로 변환 factory CreateUserRequest.fromDomain(User user, String password) { return CreateUserRequest( username: user.username, email: user.email, password: password, name: user.name, phone: user.phone, role: user.role.name, ); } } /// 사용자 수정 요청 DTO (PUT /api/v1/users/{id}) @freezed class UpdateUserRequest with _$UpdateUserRequest { const factory UpdateUserRequest({ /// 이름 (선택) String? name, /// 이메일 (선택, 유니크, 이메일 형식) String? email, /// 비밀번호 (선택, 6자 이상) String? password, /// 전화번호 (선택) String? phone, /// 권한 (선택: admin, manager, staff) String? role, }) = _UpdateUserRequest; factory UpdateUserRequest.fromJson(Map json) => _$UpdateUserRequestFromJson(json); /// 도메인 모델에서 수정 요청 DTO로 변환 factory UpdateUserRequest.fromDomain(User user, {String? newPassword}) { return UpdateUserRequest( name: user.name, email: user.email, password: newPassword, phone: user.phone, role: user.role.name, ); } } /// 사용자명 중복 확인 응답 DTO @freezed class CheckUsernameResponse with _$CheckUsernameResponse { const factory CheckUsernameResponse({ required bool available, String? message, }) = _CheckUsernameResponse; factory CheckUsernameResponse.fromJson(Map json) => _$CheckUsernameResponseFromJson(json); } /// 사용자 목록 응답 DTO (기존 PaginatedResponse 형태 유지) @freezed class UserListDto with _$UserListDto { const UserListDto._(); const factory UserListDto({ required List users, required int total, required int page, @JsonKey(name: 'per_page') required int perPage, @JsonKey(name: 'total_pages') required int totalPages, }) = _UserListDto; // 페이지네이션 응답과 호환성을 위한 getter들 List get items => users; int get size => perPage; int get totalElements => total; bool get first => page <= 1; bool get last => page >= totalPages; factory UserListDto.fromJson(Map json) => _$UserListDtoFromJson(json); /// DTO 목록을 도메인 모델 목록으로 변환 List toDomainModels() { return users.map((dto) => dto.toDomainModel()).toList(); } } /// 사용자 상세 응답 DTO @freezed class UserDetailDto with _$UserDetailDto { const factory UserDetailDto({ required UserDto user, }) = _UserDetailDto; factory UserDetailDto.fromJson(Map json) => _$UserDetailDtoFromJson(json); } /// 일반적인 사용자 API 응답 DTO @freezed class UserResponse with _$UserResponse { const factory UserResponse({ required UserDto user, String? message, }) = _UserResponse; factory UserResponse.fromJson(Map json) => _$UserResponseFromJson(json); }