2025-11-23 16:10:27 +09:00
|
|
|
// 품목기준관리 API 타입 정의
|
|
|
|
|
// API 응답 기준 snake_case 사용
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// 공통 타입
|
|
|
|
|
// ============================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 표준 API 응답 래퍼
|
|
|
|
|
*/
|
|
|
|
|
export interface ApiResponse<T> {
|
|
|
|
|
success: boolean;
|
|
|
|
|
message: string;
|
|
|
|
|
data: T;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 페이지네이션 메타데이터
|
|
|
|
|
*/
|
|
|
|
|
export interface PaginationMeta {
|
|
|
|
|
current_page: number;
|
|
|
|
|
per_page: number;
|
|
|
|
|
total: number;
|
|
|
|
|
last_page: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// 초기화 API
|
|
|
|
|
// ============================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 초기화 API 응답 - 화면 진입 시 전체 데이터 로드
|
|
|
|
|
* GET /v1/item-master/init
|
|
|
|
|
*/
|
|
|
|
|
export interface InitResponse {
|
|
|
|
|
pages: ItemPageResponse[];
|
|
|
|
|
sectionTemplates: SectionTemplateResponse[];
|
|
|
|
|
masterFields: MasterFieldResponse[];
|
|
|
|
|
customTabs: CustomTabResponse[];
|
|
|
|
|
tabColumns: Record<number, TabColumnResponse[]>; // tab_id를 key로 사용
|
|
|
|
|
unitOptions: UnitOptionResponse[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// 페이지 관리
|
|
|
|
|
// ============================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 페이지 생성/수정 요청
|
|
|
|
|
* POST /v1/item-master/pages
|
|
|
|
|
* PUT /v1/item-master/pages/{id}
|
|
|
|
|
*/
|
|
|
|
|
export interface ItemPageRequest {
|
|
|
|
|
page_name: string;
|
|
|
|
|
item_type: 'FG' | 'PT' | 'SM' | 'RM' | 'CS';
|
|
|
|
|
absolute_path?: string;
|
|
|
|
|
is_active?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 페이지 응답
|
|
|
|
|
*/
|
|
|
|
|
export interface ItemPageResponse {
|
|
|
|
|
id: number;
|
|
|
|
|
tenant_id: number;
|
|
|
|
|
page_name: string;
|
|
|
|
|
item_type: string;
|
|
|
|
|
absolute_path: string | null;
|
|
|
|
|
is_active: boolean;
|
|
|
|
|
created_by: number | null;
|
|
|
|
|
updated_by: number | null;
|
|
|
|
|
created_at: string;
|
|
|
|
|
updated_at: string;
|
|
|
|
|
sections?: ItemSectionResponse[]; // Nested 조회 시 포함
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 페이지 순서 변경 요청
|
|
|
|
|
* PUT /v1/item-master/pages/reorder (향후 구현 가능성)
|
|
|
|
|
*/
|
|
|
|
|
export interface PageReorderRequest {
|
|
|
|
|
page_orders: Array<{
|
|
|
|
|
id: number;
|
|
|
|
|
order_no: number;
|
|
|
|
|
}>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// 섹션 관리
|
|
|
|
|
// ============================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 섹션 생성/수정 요청
|
|
|
|
|
* POST /v1/item-master/pages/{pageId}/sections
|
|
|
|
|
* PUT /v1/item-master/sections/{id}
|
|
|
|
|
*/
|
|
|
|
|
export interface ItemSectionRequest {
|
|
|
|
|
title: string;
|
|
|
|
|
type: 'fields' | 'bom';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 섹션 응답
|
|
|
|
|
*/
|
|
|
|
|
export interface ItemSectionResponse {
|
|
|
|
|
id: number;
|
|
|
|
|
tenant_id: number;
|
|
|
|
|
page_id: number;
|
|
|
|
|
title: string;
|
|
|
|
|
type: 'fields' | 'bom';
|
|
|
|
|
order_no: number;
|
|
|
|
|
created_by: number | null;
|
|
|
|
|
updated_by: number | null;
|
|
|
|
|
created_at: string;
|
|
|
|
|
updated_at: string;
|
|
|
|
|
fields?: ItemFieldResponse[]; // Nested 조회 시 포함
|
|
|
|
|
bomItems?: BomItemResponse[]; // Nested 조회 시 포함
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 섹션 순서 변경 요청
|
|
|
|
|
* PUT /v1/item-master/pages/{pageId}/sections/reorder
|
|
|
|
|
*/
|
|
|
|
|
export interface SectionReorderRequest {
|
|
|
|
|
section_orders: Array<{
|
|
|
|
|
id: number;
|
|
|
|
|
order_no: number;
|
|
|
|
|
}>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// 필드 관리
|
|
|
|
|
// ============================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 필드 생성/수정 요청
|
|
|
|
|
* POST /v1/item-master/sections/{sectionId}/fields
|
|
|
|
|
* PUT /v1/item-master/fields/{id}
|
|
|
|
|
*/
|
|
|
|
|
export interface ItemFieldRequest {
|
|
|
|
|
field_name: string;
|
|
|
|
|
field_type: 'textbox' | 'number' | 'dropdown' | 'checkbox' | 'date' | 'textarea';
|
|
|
|
|
is_required?: boolean;
|
|
|
|
|
placeholder?: string;
|
|
|
|
|
default_value?: string;
|
|
|
|
|
display_condition?: Record<string, any>; // {"field_id": "1", "operator": "equals", "value": "true"}
|
|
|
|
|
validation_rules?: Record<string, any>; // {"min": 0, "max": 100, "pattern": "regex"}
|
|
|
|
|
options?: Array<{ label: string; value: string }>; // dropdown 옵션
|
|
|
|
|
properties?: Record<string, any>; // {"unit": "mm", "precision": 2, "format": "YYYY-MM-DD"}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 필드 응답
|
|
|
|
|
*/
|
|
|
|
|
export interface ItemFieldResponse {
|
|
|
|
|
id: number;
|
|
|
|
|
tenant_id: number;
|
|
|
|
|
section_id: number;
|
2025-11-25 21:07:10 +09:00
|
|
|
master_field_id?: number | null; // 마스터 항목 ID (마스터에서 가져온 경우)
|
2025-11-23 16:10:27 +09:00
|
|
|
field_name: string;
|
|
|
|
|
field_type: 'textbox' | 'number' | 'dropdown' | 'checkbox' | 'date' | 'textarea';
|
|
|
|
|
order_no: number;
|
|
|
|
|
is_required: boolean;
|
|
|
|
|
placeholder: string | null;
|
|
|
|
|
default_value: string | null;
|
|
|
|
|
display_condition: Record<string, any> | null;
|
|
|
|
|
validation_rules: Record<string, any> | null;
|
|
|
|
|
options: Array<{ label: string; value: string }> | null;
|
|
|
|
|
properties: Record<string, any> | null;
|
|
|
|
|
created_by: number | null;
|
|
|
|
|
updated_by: number | null;
|
|
|
|
|
created_at: string;
|
|
|
|
|
updated_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 필드 순서 변경 요청
|
|
|
|
|
* PUT /v1/item-master/sections/{sectionId}/fields/reorder
|
|
|
|
|
*/
|
|
|
|
|
export interface FieldReorderRequest {
|
|
|
|
|
field_orders: Array<{
|
|
|
|
|
id: number;
|
|
|
|
|
order_no: number;
|
|
|
|
|
}>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// BOM 관리
|
|
|
|
|
// ============================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* BOM 항목 생성/수정 요청
|
|
|
|
|
* POST /v1/item-master/sections/{sectionId}/bom-items
|
|
|
|
|
* PUT /v1/item-master/bom-items/{id}
|
|
|
|
|
*/
|
|
|
|
|
export interface BomItemRequest {
|
|
|
|
|
item_code?: string;
|
|
|
|
|
item_name: string;
|
|
|
|
|
quantity: number;
|
|
|
|
|
unit?: string;
|
|
|
|
|
unit_price?: number;
|
|
|
|
|
total_price?: number;
|
|
|
|
|
spec?: string;
|
|
|
|
|
note?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* BOM 항목 응답
|
|
|
|
|
*/
|
|
|
|
|
export interface BomItemResponse {
|
|
|
|
|
id: number;
|
|
|
|
|
tenant_id: number;
|
|
|
|
|
section_id: number;
|
|
|
|
|
item_code: string | null;
|
|
|
|
|
item_name: string;
|
|
|
|
|
quantity: number;
|
|
|
|
|
unit: string | null;
|
|
|
|
|
unit_price: number | null;
|
|
|
|
|
total_price: number | null;
|
|
|
|
|
spec: string | null;
|
|
|
|
|
note: string | null;
|
|
|
|
|
created_by: number | null;
|
|
|
|
|
updated_by: number | null;
|
|
|
|
|
created_at: string;
|
|
|
|
|
updated_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// 섹션 템플릿
|
|
|
|
|
// ============================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 섹션 템플릿 생성/수정 요청
|
|
|
|
|
* POST /v1/item-master/section-templates
|
|
|
|
|
* PUT /v1/item-master/section-templates/{id}
|
|
|
|
|
*/
|
|
|
|
|
export interface SectionTemplateRequest {
|
|
|
|
|
title: string;
|
|
|
|
|
type: 'fields' | 'bom';
|
|
|
|
|
description?: string;
|
|
|
|
|
is_default?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 섹션 템플릿 응답
|
|
|
|
|
*/
|
|
|
|
|
export interface SectionTemplateResponse {
|
|
|
|
|
id: number;
|
|
|
|
|
tenant_id: number;
|
|
|
|
|
title: string;
|
|
|
|
|
type: 'fields' | 'bom';
|
|
|
|
|
description: string | null;
|
|
|
|
|
is_default: boolean;
|
|
|
|
|
created_by: number | null;
|
|
|
|
|
updated_by: number | null;
|
|
|
|
|
created_at: string;
|
|
|
|
|
updated_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// 마스터 필드
|
|
|
|
|
// ============================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 마스터 필드 생성/수정 요청
|
|
|
|
|
* POST /v1/item-master/master-fields
|
|
|
|
|
* PUT /v1/item-master/master-fields/{id}
|
|
|
|
|
*/
|
|
|
|
|
export interface MasterFieldRequest {
|
|
|
|
|
field_name: string;
|
|
|
|
|
field_type: 'textbox' | 'number' | 'dropdown' | 'checkbox' | 'date' | 'textarea';
|
|
|
|
|
category?: string;
|
|
|
|
|
description?: string;
|
|
|
|
|
is_common?: boolean;
|
|
|
|
|
default_value?: string;
|
|
|
|
|
options?: Array<{ label: string; value: string }>;
|
|
|
|
|
validation_rules?: Record<string, any>;
|
|
|
|
|
properties?: Record<string, any>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 마스터 필드 응답
|
|
|
|
|
*/
|
|
|
|
|
export interface MasterFieldResponse {
|
|
|
|
|
id: number;
|
|
|
|
|
tenant_id: number;
|
|
|
|
|
field_name: string;
|
|
|
|
|
field_type: 'textbox' | 'number' | 'dropdown' | 'checkbox' | 'date' | 'textarea';
|
|
|
|
|
category: string | null;
|
|
|
|
|
description: string | null;
|
|
|
|
|
is_common: boolean;
|
|
|
|
|
default_value: string | null;
|
|
|
|
|
options: Array<{ label: string; value: string }> | null;
|
|
|
|
|
validation_rules: Record<string, any> | null;
|
|
|
|
|
properties: Record<string, any> | null;
|
|
|
|
|
created_by: number | null;
|
|
|
|
|
updated_by: number | null;
|
|
|
|
|
created_at: string;
|
|
|
|
|
updated_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// 커스텀 탭
|
|
|
|
|
// ============================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 커스텀 탭 생성/수정 요청
|
|
|
|
|
* POST /v1/item-master/custom-tabs
|
|
|
|
|
* PUT /v1/item-master/custom-tabs/{id}
|
|
|
|
|
*/
|
|
|
|
|
export interface CustomTabRequest {
|
|
|
|
|
label: string;
|
|
|
|
|
icon?: string;
|
|
|
|
|
is_default?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 커스텀 탭 응답
|
|
|
|
|
*/
|
|
|
|
|
export interface CustomTabResponse {
|
|
|
|
|
id: number;
|
|
|
|
|
tenant_id: number;
|
|
|
|
|
label: string;
|
|
|
|
|
icon: string | null;
|
|
|
|
|
is_default: boolean;
|
|
|
|
|
order_no: number;
|
|
|
|
|
created_by: number | null;
|
|
|
|
|
updated_by: number | null;
|
|
|
|
|
created_at: string;
|
|
|
|
|
updated_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 탭 순서 변경 요청
|
|
|
|
|
* PUT /v1/item-master/custom-tabs/reorder
|
|
|
|
|
*/
|
|
|
|
|
export interface TabReorderRequest {
|
|
|
|
|
tab_orders: Array<{
|
|
|
|
|
id: number;
|
|
|
|
|
order_no: number;
|
|
|
|
|
}>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 탭 컬럼 설정 업데이트 요청
|
|
|
|
|
* PUT /v1/item-master/custom-tabs/{id}/columns
|
|
|
|
|
*/
|
|
|
|
|
export interface TabColumnUpdateRequest {
|
|
|
|
|
columns: Array<{
|
|
|
|
|
key: string;
|
|
|
|
|
label: string;
|
|
|
|
|
visible: boolean;
|
|
|
|
|
order: number;
|
|
|
|
|
}>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 탭 컬럼 응답
|
|
|
|
|
*/
|
|
|
|
|
export interface TabColumnResponse {
|
|
|
|
|
key: string;
|
|
|
|
|
label: string;
|
|
|
|
|
visible: boolean;
|
|
|
|
|
order: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// 단위 옵션
|
|
|
|
|
// ============================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 단위 옵션 생성 요청
|
|
|
|
|
* POST /v1/item-master/units
|
|
|
|
|
*/
|
|
|
|
|
export interface UnitOptionRequest {
|
|
|
|
|
label: string;
|
|
|
|
|
value: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 단위 옵션 응답
|
|
|
|
|
*/
|
|
|
|
|
export interface UnitOptionResponse {
|
|
|
|
|
id: number;
|
|
|
|
|
tenant_id: number;
|
|
|
|
|
label: string;
|
|
|
|
|
value: string;
|
|
|
|
|
created_by: number | null;
|
|
|
|
|
created_at: string;
|
|
|
|
|
updated_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// 에러 타입
|
|
|
|
|
// ============================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API 에러 응답
|
|
|
|
|
*/
|
|
|
|
|
export interface ApiErrorResponse {
|
|
|
|
|
success: false;
|
|
|
|
|
message: string;
|
|
|
|
|
errors?: Record<string, string[]>; // Validation 에러
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* API 에러 클래스용 타입
|
|
|
|
|
*/
|
|
|
|
|
export interface ApiErrorData {
|
|
|
|
|
status: number;
|
|
|
|
|
message: string;
|
|
|
|
|
errors?: Record<string, string[]>;
|
|
|
|
|
}
|