/// 메뉴 엔티티 /// /// - 계층 구조를 표현하기 위해 상위 메뉴 정보를 포함한다. /// - presentation/data 레이어 세부 구현에 의존하지 않는다. class MenuItem { MenuItem({ this.id, required this.menuCode, required this.menuName, this.parent, this.path, this.displayOrder, this.isActive = true, this.isDeleted = false, this.note, this.createdAt, this.updatedAt, }); /// PK (null 이면 신규 생성) final int? id; /// 메뉴 코드 (고유) final String menuCode; /// 메뉴명 final String menuName; /// 상위 메뉴 정보 final MenuSummary? parent; /// 라우트 경로 final String? path; /// 표시 순서 final int? displayOrder; /// 사용 여부 final bool isActive; /// 소프트 삭제 여부 final bool isDeleted; /// 비고 final String? note; /// 생성/수정 일시 final DateTime? createdAt; final DateTime? updatedAt; MenuItem copyWith({ int? id, String? menuCode, String? menuName, MenuSummary? parent, String? path, int? displayOrder, bool? isActive, bool? isDeleted, String? note, DateTime? createdAt, DateTime? updatedAt, }) { return MenuItem( id: id ?? this.id, menuCode: menuCode ?? this.menuCode, menuName: menuName ?? this.menuName, parent: parent ?? this.parent, path: path ?? this.path, displayOrder: displayOrder ?? this.displayOrder, isActive: isActive ?? this.isActive, isDeleted: isDeleted ?? this.isDeleted, note: note ?? this.note, createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? this.updatedAt, ); } } /// 상위 메뉴 요약 정보 class MenuSummary { MenuSummary({required this.id, required this.menuName}); final int id; final String menuName; } /// 메뉴 생성/수정 입력 모델 class MenuInput { MenuInput({ required this.menuCode, required this.menuName, this.parentMenuId, this.path, this.displayOrder, this.isActive = true, this.note, }); final String menuCode; final String menuName; final int? parentMenuId; final String? path; final int? displayOrder; final bool isActive; final String? note; Map toPayload() { return { 'menu_code': menuCode, 'menu_name': menuName, 'parent_menu_id': parentMenuId, 'path': path, 'display_order': displayOrder, 'is_active': isActive, 'note': note, }; } }