feat: 공정 단계(ProcessStep) CRUD API 구현

- process_steps 테이블 마이그레이션 생성 (step_code, sort_order, boolean 플래그 등)
- ProcessStep 모델 생성 (child entity 패턴, HasFactory만 사용)
- ProcessStepService: CRUD + reorder + STP-001 자동채번
- ProcessStepController: DI + ApiResponse::handle 패턴
- FormRequest 3개: Store, Update, Reorder
- Process 모델에 steps() HasMany 관계 추가
- ProcessService eager-load에 steps 추가 (5곳)
- Nested routes: /processes/{processId}/steps

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-03 18:59:12 +09:00
parent 529c587023
commit 3d20c6979d
10 changed files with 441 additions and 5 deletions

View File

@@ -25,7 +25,7 @@ public function index(array $params)
$query = Process::query()
->where('tenant_id', $tenantId)
->with(['classificationRules', 'processItems.item:id,code,name']);
->with(['classificationRules', 'processItems.item:id,code,name', 'steps']);
// 검색어
if ($q !== '') {
@@ -62,7 +62,7 @@ public function show(int $id)
$tenantId = $this->tenantId();
$process = Process::where('tenant_id', $tenantId)
->with(['classificationRules', 'processItems.item:id,code,name'])
->with(['classificationRules', 'processItems.item:id,code,name', 'steps'])
->find($id);
if (! $process) {
@@ -104,7 +104,7 @@ public function store(array $data)
// 개별 품목 연결
$this->syncProcessItems($process, $itemIds);
return $process->load(['classificationRules', 'processItems.item:id,code,name']);
return $process->load(['classificationRules', 'processItems.item:id,code,name', 'steps']);
});
}
@@ -145,7 +145,7 @@ public function update(int $id, array $data)
$this->syncProcessItems($process, $itemIds);
}
return $process->fresh(['classificationRules', 'processItems.item:id,code,name']);
return $process->fresh(['classificationRules', 'processItems.item:id,code,name', 'steps']);
});
}
@@ -201,7 +201,7 @@ public function toggleActive(int $id)
'updated_by' => $userId,
]);
return $process->fresh(['classificationRules', 'processItems.item:id,code,name']);
return $process->fresh(['classificationRules', 'processItems.item:id,code,name', 'steps']);
}
/**