557 lines
13 KiB
TypeScript
557 lines
13 KiB
TypeScript
/**
|
|
* 🎮 제어관리 시스템 전용 타입 정의
|
|
*
|
|
* 버튼 액션, 데이터플로우, 조건부 실행, 트랜잭션 처리 등 제어관리에서만 사용하는 타입들
|
|
*/
|
|
|
|
import {
|
|
ButtonActionType,
|
|
ConditionOperator,
|
|
CompanyCode,
|
|
ActiveStatus,
|
|
TimestampFields,
|
|
BaseApiResponse,
|
|
} from "./v2-core";
|
|
import { FlowVisibilityConfig } from "./screen-management";
|
|
|
|
// ===== 버튼 제어 관련 =====
|
|
|
|
/**
|
|
* 확장된 버튼 설정 (화면관리의 ButtonTypeConfig 확장)
|
|
*/
|
|
export interface ExtendedButtonTypeConfig {
|
|
// 기본 버튼 설정
|
|
action_type: ButtonActionType;
|
|
text?: string;
|
|
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link";
|
|
size?: "sm" | "md" | "lg";
|
|
icon?: string;
|
|
|
|
// 확인 및 검증
|
|
confirm_message?: string;
|
|
requires_confirmation?: boolean;
|
|
|
|
// 모달 관련 설정
|
|
popup_title?: string;
|
|
popup_content?: string;
|
|
popup_screen_id?: number;
|
|
|
|
// 네비게이션 관련 설정
|
|
navigate_type?: "url" | "screen";
|
|
navigate_url?: string;
|
|
navigate_screen_id?: number;
|
|
navigate_target?: "_self" | "_blank";
|
|
|
|
// 커스텀 액션 설정
|
|
custom_action?: string;
|
|
|
|
// 🎯 제어관리 기능
|
|
enable_dataflow_control?: boolean;
|
|
dataflow_config?: ButtonDataflowConfig;
|
|
dataflow_timing?: "before" | "after" | "replace";
|
|
|
|
// 🆕 플로우 단계별 표시 제어
|
|
flow_visibility_config?: FlowVisibilityConfig;
|
|
|
|
// 스타일 설정
|
|
background_color?: string;
|
|
text_color?: string;
|
|
border_color?: string;
|
|
}
|
|
|
|
|
|
/**
|
|
* 🔥 단순화된 버튼 데이터플로우 설정
|
|
*/
|
|
export interface ButtonDataflowConfig {
|
|
// 제어 방식 선택 (관계 실행 + 🆕 노드 플로우)
|
|
control_mode: "relationship" | "flow" | "none";
|
|
|
|
// 관계 기반 제어
|
|
relationship_config?: {
|
|
relationship_id: string; // 관계 직접 선택
|
|
relationship_name: string; // 관계명 표시
|
|
execution_timing: "before" | "after" | "replace";
|
|
context_data?: Record<string, any>; // 실행 시 전달할 컨텍스트
|
|
};
|
|
|
|
// 🆕 노드 플로우 기반 제어
|
|
flow_config?: {
|
|
flow_id: number; // 노드 플로우 ID
|
|
flow_name: string; // 플로우명 표시
|
|
execution_timing: "before" | "after" | "replace";
|
|
context_data?: Record<string, any>; // 실행 시 전달할 컨텍스트
|
|
};
|
|
|
|
// 제어 데이터 소스 (기존 호환성 유지)
|
|
control_data_source?: ControlDataSource;
|
|
|
|
// 실행 옵션
|
|
execution_options?: ExecutionOptions;
|
|
|
|
// 🔧 기존 호환성을 위한 필드들 (deprecated)
|
|
selected_diagram_id?: number;
|
|
selected_relationship_id?: number;
|
|
direct_control?: DirectControlConfig;
|
|
|
|
// 🔧 제거된 필드들 (하위 호환성을 위해 optional로 유지)
|
|
external_call_config?: any; // deprecated
|
|
custom_config?: any; // deprecated
|
|
}
|
|
|
|
/**
|
|
* 제어 데이터 소스 타입
|
|
*
|
|
* - form: 폼 데이터만 사용
|
|
* - table-selection: 테이블에서 선택된 행 데이터만 사용
|
|
* - table-all: 테이블의 전체 데이터 사용 (페이징 무관, 모든 데이터)
|
|
* - flow-selection: 플로우에서 선택된 데이터만 사용
|
|
* - flow-step-all: 특정 플로우 스텝의 모든 데이터 사용
|
|
* - both: 폼 + 테이블 선택 데이터 결합
|
|
* - all-sources: 모든 소스 데이터 결합 (폼 + 테이블 전체 + 플로우)
|
|
*/
|
|
export type ControlDataSource =
|
|
| "form"
|
|
| "table-selection"
|
|
| "table-all"
|
|
| "flow-selection"
|
|
| "flow-step-all"
|
|
| "both"
|
|
| "all-sources";
|
|
|
|
/**
|
|
* 직접 제어 설정
|
|
*/
|
|
export interface DirectControlConfig {
|
|
conditions: DataflowCondition[];
|
|
actions: DataflowAction[];
|
|
logic?: "AND" | "OR" | "CUSTOM";
|
|
custom_logic?: string; // "(A AND B) OR (C AND D)"
|
|
}
|
|
|
|
/**
|
|
* 실행 옵션
|
|
*/
|
|
export interface ExecutionOptions {
|
|
timeout?: number; // ms
|
|
retry_count?: number;
|
|
parallel_execution?: boolean;
|
|
continue_on_error?: boolean;
|
|
}
|
|
|
|
// ===== 데이터플로우 조건 및 액션 =====
|
|
|
|
/**
|
|
* 데이터플로우 조건
|
|
*/
|
|
export interface DataflowCondition {
|
|
id: string;
|
|
type: "condition" | "group";
|
|
|
|
// 단일 조건
|
|
field?: string;
|
|
operator?: ConditionOperator;
|
|
value?: unknown;
|
|
data_source?: ControlDataSource;
|
|
|
|
// 그룹 조건
|
|
conditions?: DataflowCondition[];
|
|
logic?: "AND" | "OR";
|
|
|
|
// 메타데이터
|
|
name?: string;
|
|
description?: string;
|
|
}
|
|
|
|
/**
|
|
* 데이터플로우 액션
|
|
*/
|
|
export interface DataflowAction {
|
|
id: string;
|
|
name: string;
|
|
type: ActionType;
|
|
|
|
// 데이터베이스 액션
|
|
table_name?: string;
|
|
operation?: DatabaseOperation;
|
|
fields?: ActionField[];
|
|
conditions?: DataflowCondition[];
|
|
|
|
// API 액션
|
|
endpoint?: string;
|
|
method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
headers?: Record<string, string>;
|
|
body?: unknown;
|
|
|
|
// 알림 액션
|
|
notification_type?: NotificationType;
|
|
message?: string;
|
|
recipients?: string[];
|
|
|
|
// 리다이렉트 액션
|
|
redirect_url?: string;
|
|
redirect_target?: "_self" | "_blank";
|
|
|
|
// 실행 옵션
|
|
timeout?: number;
|
|
retry_count?: number;
|
|
rollbackable?: boolean;
|
|
|
|
// 메타데이터
|
|
description?: string;
|
|
order?: number;
|
|
}
|
|
|
|
/**
|
|
* 액션 타입
|
|
*/
|
|
export type ActionType = "database" | "api" | "notification" | "redirect" | "custom";
|
|
|
|
/**
|
|
* 데이터베이스 작업 타입
|
|
*/
|
|
export type DatabaseOperation = "INSERT" | "UPDATE" | "DELETE" | "SELECT";
|
|
|
|
/**
|
|
* 액션 필드
|
|
*/
|
|
export interface ActionField {
|
|
name: string;
|
|
value: unknown;
|
|
type?: "static" | "dynamic" | "computed";
|
|
source?: string; // 동적 값의 소스 (form field, selected row 등)
|
|
}
|
|
|
|
/**
|
|
* 알림 타입
|
|
*/
|
|
export type NotificationType = "success" | "error" | "warning" | "info" | "toast" | "modal" | "email";
|
|
|
|
// ===== 트랜잭션 관리 =====
|
|
|
|
/**
|
|
* 트랜잭션 그룹
|
|
*/
|
|
export interface TransactionGroup {
|
|
id: string;
|
|
name: string;
|
|
description?: string;
|
|
actions: DataflowAction[];
|
|
rollback_strategy: RollbackStrategy;
|
|
execution_mode: "sequential" | "parallel";
|
|
on_failure: FailureHandling;
|
|
}
|
|
|
|
/**
|
|
* 롤백 전략
|
|
*/
|
|
export type RollbackStrategy =
|
|
| "none" // 롤백 안함
|
|
| "partial" // 실패한 액션만 롤백
|
|
| "complete"; // 전체 트랜잭션 롤백
|
|
|
|
/**
|
|
* 실패 처리 방식
|
|
*/
|
|
export type FailureHandling =
|
|
| "stop" // 실패 시 중단
|
|
| "continue" // 실패해도 계속 진행
|
|
| "alternative"; // 대안 액션 실행
|
|
|
|
/**
|
|
* 조건부 실행 계획
|
|
*/
|
|
export interface ConditionalExecutionPlan {
|
|
id: string;
|
|
name: string;
|
|
conditions: ExecutionCondition[];
|
|
logic: "AND" | "OR" | "CUSTOM";
|
|
custom_logic?: string;
|
|
}
|
|
|
|
/**
|
|
* 실행 조건
|
|
*/
|
|
export interface ExecutionCondition {
|
|
id: string;
|
|
type: "action_group" | "validation" | "data_check";
|
|
|
|
// 액션 그룹 조건
|
|
action_group?: TransactionGroup;
|
|
|
|
// 검증 조건
|
|
validation?: {
|
|
field: string;
|
|
operator: ConditionOperator;
|
|
value: unknown;
|
|
};
|
|
|
|
// 성공/실패 조건
|
|
expected_result: "success" | "failure" | "any";
|
|
}
|
|
|
|
/**
|
|
* 조건부 액션 그룹
|
|
*/
|
|
export interface ConditionalActionGroup {
|
|
id: string;
|
|
name: string;
|
|
description?: string;
|
|
|
|
// 실행 조건
|
|
execution_condition: {
|
|
type: "always" | "conditional" | "fallback";
|
|
conditions?: DataflowCondition[];
|
|
logic?: "AND" | "OR";
|
|
};
|
|
|
|
// 액션들
|
|
actions: DataflowAction[];
|
|
|
|
// 성공/실패 조건 정의
|
|
success_criteria: {
|
|
type: "all_success" | "any_success" | "custom";
|
|
custom_logic?: string;
|
|
};
|
|
|
|
// 다음 단계 정의
|
|
on_success?: {
|
|
next_group?: string;
|
|
complete_transaction?: boolean;
|
|
};
|
|
|
|
on_failure?: {
|
|
retry_count?: number;
|
|
fallback_group?: string;
|
|
rollback_strategy?: RollbackStrategy;
|
|
};
|
|
}
|
|
|
|
// ===== 실행 결과 및 상태 =====
|
|
|
|
/**
|
|
* 액션 실행 결과
|
|
*/
|
|
export interface ActionExecutionResult {
|
|
action_id: string;
|
|
transaction_id?: string;
|
|
status: "pending" | "running" | "success" | "failed" | "rolled_back";
|
|
start_time: Date;
|
|
end_time?: Date;
|
|
result?: unknown;
|
|
error?: {
|
|
code: string;
|
|
message: string;
|
|
details?: unknown;
|
|
};
|
|
rollback_data?: unknown;
|
|
}
|
|
|
|
/**
|
|
* 트랜잭션 실행 상태
|
|
*/
|
|
export interface TransactionExecutionState {
|
|
transaction_id: string;
|
|
status: "pending" | "running" | "success" | "failed" | "rolling_back" | "rolled_back";
|
|
actions: ActionExecutionResult[];
|
|
rollback_actions?: ActionExecutionResult[];
|
|
start_time: Date;
|
|
end_time?: Date;
|
|
}
|
|
|
|
/**
|
|
* 트랜잭션 실행 결과
|
|
*/
|
|
export interface TransactionExecutionResult {
|
|
success: boolean;
|
|
message: string;
|
|
requires_rollback: boolean;
|
|
results: [string, boolean][];
|
|
transaction_id?: string;
|
|
}
|
|
|
|
/**
|
|
* 데이터플로우 실행 결과
|
|
*/
|
|
export interface DataflowExecutionResult {
|
|
success: boolean;
|
|
message: string;
|
|
data?: unknown;
|
|
executed_actions?: ActionExecutionResult[];
|
|
failed_actions?: ActionExecutionResult[];
|
|
total_actions?: number;
|
|
execution_time?: number;
|
|
}
|
|
|
|
// ===== 제어 컨텍스트 =====
|
|
|
|
/**
|
|
* 확장된 제어 컨텍스트
|
|
*/
|
|
export interface ExtendedControlContext {
|
|
// 기존 폼 데이터
|
|
form_data: Record<string, unknown>;
|
|
|
|
// 테이블 선택 데이터
|
|
selected_rows?: unknown[];
|
|
selected_rows_data?: Record<string, unknown>[];
|
|
|
|
// 플로우 선택 데이터
|
|
flow_selected_data?: Record<string, unknown>[];
|
|
flow_selected_step_id?: number | null;
|
|
|
|
// 제어 데이터 소스 타입
|
|
control_data_source: ControlDataSource;
|
|
|
|
// 기타 컨텍스트
|
|
button_id?: string;
|
|
component_data?: unknown;
|
|
timestamp?: string;
|
|
click_count?: number;
|
|
|
|
// 사용자 정보
|
|
user_id?: string;
|
|
company_code?: CompanyCode;
|
|
|
|
// 화면 정보
|
|
screen_id?: number;
|
|
screen_code?: string;
|
|
}
|
|
|
|
/**
|
|
* 빠른 검증 결과
|
|
*/
|
|
export interface QuickValidationResult {
|
|
success: boolean;
|
|
message?: string;
|
|
can_execute_immediately: boolean;
|
|
actions?: DataflowAction[];
|
|
}
|
|
|
|
// ===== 버튼 액션 표준 (DB 기반) =====
|
|
|
|
/**
|
|
* 버튼 액션 표준 정의 (DB의 button_action_standards 테이블)
|
|
*/
|
|
export interface ButtonActionStandard extends TimestampFields {
|
|
action_type: string;
|
|
action_name: string;
|
|
action_name_eng?: string;
|
|
description?: string;
|
|
category: string;
|
|
default_text?: string;
|
|
default_text_eng?: string;
|
|
default_icon?: string;
|
|
default_color?: string;
|
|
default_variant?: string;
|
|
confirmation_required: boolean;
|
|
confirmation_message?: string;
|
|
validation_rules?: unknown;
|
|
action_config?: unknown;
|
|
sort_order?: number;
|
|
is_active: ActiveStatus;
|
|
}
|
|
|
|
/**
|
|
* 버튼 액션 생성/수정 요청
|
|
*/
|
|
export interface ButtonActionFormData {
|
|
action_type: string;
|
|
action_name: string;
|
|
action_name_eng?: string;
|
|
description?: string;
|
|
category: string;
|
|
default_text?: string;
|
|
default_text_eng?: string;
|
|
default_icon?: string;
|
|
default_color?: string;
|
|
default_variant?: string;
|
|
confirmation_required: boolean;
|
|
confirmation_message?: string;
|
|
validation_rules?: unknown;
|
|
action_config?: unknown;
|
|
sort_order?: number;
|
|
is_active: ActiveStatus;
|
|
}
|
|
|
|
// ===== API 응답 타입들 =====
|
|
|
|
/**
|
|
* 버튼 액션 목록 응답
|
|
*/
|
|
export interface ButtonActionListResponse extends BaseApiResponse<ButtonActionStandard[]> {}
|
|
|
|
/**
|
|
* 데이터플로우 실행 응답
|
|
*/
|
|
export interface DataflowExecutionResponse extends BaseApiResponse<DataflowExecutionResult> {}
|
|
|
|
/**
|
|
* 트랜잭션 실행 응답
|
|
*/
|
|
export interface TransactionExecutionResponse extends BaseApiResponse<TransactionExecutionResult> {}
|
|
|
|
// ===== 유틸리티 타입들 =====
|
|
|
|
/**
|
|
* 롤백 핸들러
|
|
*/
|
|
export interface RollbackHandler {
|
|
action_id: string;
|
|
rollback_fn: () => Promise<void>;
|
|
}
|
|
|
|
/**
|
|
* 최적화된 실행 결과
|
|
*/
|
|
export interface OptimizedExecutionResult {
|
|
job_id: string;
|
|
immediate_result?: unknown;
|
|
is_background?: boolean;
|
|
timing?: "before" | "after" | "replace";
|
|
}
|
|
|
|
// ===== 타입 가드 및 유틸리티 함수들 =====
|
|
|
|
/**
|
|
* DataflowCondition이 단일 조건인지 확인
|
|
*/
|
|
export const isSingleCondition = (condition: DataflowCondition): boolean => {
|
|
return condition.type === "condition" && !!condition.field;
|
|
};
|
|
|
|
/**
|
|
* DataflowCondition이 그룹 조건인지 확인
|
|
*/
|
|
export const isGroupCondition = (condition: DataflowCondition): boolean => {
|
|
return condition.type === "group" && !!condition.conditions?.length;
|
|
};
|
|
|
|
/**
|
|
* DataflowAction이 데이터베이스 액션인지 확인
|
|
*/
|
|
export const isDatabaseAction = (action: DataflowAction): boolean => {
|
|
return action.type === "database" && !!action.table_name;
|
|
};
|
|
|
|
/**
|
|
* DataflowAction이 API 액션인지 확인
|
|
*/
|
|
export const isApiAction = (action: DataflowAction): boolean => {
|
|
return action.type === "api" && !!action.endpoint;
|
|
};
|
|
|
|
/**
|
|
* 액션 실행 결과가 성공인지 확인
|
|
*/
|
|
export const isActionSuccess = (result: ActionExecutionResult): boolean => {
|
|
return result.status === "success";
|
|
};
|
|
|
|
/**
|
|
* 트랜잭션이 완료되었는지 확인 (성공 또는 실패)
|
|
*/
|
|
export const isTransactionCompleted = (state: TransactionExecutionState): boolean => {
|
|
return ["success", "failed", "rolled_back"].includes(state.status);
|
|
};
|