feat: [공정관리] parent_id 트리 구조 도입 — 마이그레이션, 모델 관계, 2depth 검증

This commit is contained in:
김보곤
2026-03-21 15:23:54 +09:00
parent cce4798643
commit 1577d028dc
5 changed files with 88 additions and 2 deletions

View File

@@ -23,9 +23,11 @@ public function index(array $params)
$status = $params['status'] ?? null;
$processType = $params['process_type'] ?? null;
$eagerLoad = ['classificationRules', 'processItems.item:id,code,name', 'steps', 'documentTemplate:id,name,category', 'workLogTemplateRelation:id,name,category', 'parent:id,process_code,process_name', 'children:id,parent_id,process_code,process_name,is_active'];
$query = Process::query()
->where('tenant_id', $tenantId)
->with(['classificationRules', 'processItems.item:id,code,name', 'steps', 'documentTemplate:id,name,category', 'workLogTemplateRelation:id,name,category']);
->with($eagerLoad);
// 검색어
if ($q !== '') {
@@ -62,7 +64,7 @@ public function show(int $id)
$tenantId = $this->tenantId();
$process = Process::where('tenant_id', $tenantId)
->with(['classificationRules', 'processItems.item:id,code,name', 'steps', 'documentTemplate:id,name,category', 'workLogTemplateRelation:id,name,category'])
->with(['classificationRules', 'processItems.item:id,code,name', 'steps', 'documentTemplate:id,name,category', 'workLogTemplateRelation:id,name,category', 'parent:id,process_code,process_name', 'children:id,parent_id,process_code,process_name,is_active'])
->find($id);
if (! $process) {
@@ -81,6 +83,16 @@ public function store(array $data)
$userId = $this->apiUserId();
return DB::transaction(function () use ($data, $tenantId, $userId) {
// 2depth 제한: 부모가 이미 자식이면 거부
if (! empty($data['parent_id'])) {
$parent = Process::find($data['parent_id']);
if ($parent && $parent->parent_id) {
throw \Illuminate\Validation\ValidationException::withMessages([
'parent_id' => ['2단계까지만 허용됩니다. 선택한 부모 공정이 이미 하위 공정입니다.'],
]);
}
}
// 공정코드 자동 생성
$data['process_code'] = $this->generateProcessCode($tenantId);
$data['tenant_id'] = $tenantId;
@@ -122,6 +134,22 @@ public function update(int $id, array $data)
}
return DB::transaction(function () use ($process, $data, $userId) {
// parent_id 변경 시 2depth + 순환 참조 검증
if (array_key_exists('parent_id', $data) && $data['parent_id']) {
$parent = Process::find($data['parent_id']);
if ($parent && $parent->parent_id) {
throw \Illuminate\Validation\ValidationException::withMessages([
'parent_id' => ['2단계까지만 허용됩니다.'],
]);
}
// 자기 자식을 부모로 설정하는 것 방지
if ($process->children()->where('id', $data['parent_id'])->exists()) {
throw \Illuminate\Validation\ValidationException::withMessages([
'parent_id' => ['하위 공정을 부모로 설정할 수 없습니다.'],
]);
}
}
$data['updated_by'] = $userId;
// work_steps가 문자열이면 배열로 변환
@@ -288,6 +316,7 @@ public function duplicate(int $id)
$newProcess = Process::create([
'tenant_id' => $tenantId,
'parent_id' => $source->parent_id,
'process_code' => $newCode,
'process_name' => $source->process_name.' (복사)',
'description' => $source->description,