Files
sam-manage/app/Http/Controllers/Sales/InterviewScenarioController.php
김보곤 a507f7dc69 feat:인터뷰 시나리오 관리 기능 추가
- InterviewScenarioController: 카테고리/항목/질문 CRUD + 세션 관리 API
- InterviewScenarioService: 비즈니스 로직 (트리 조회, 세션 시작/토글/완료)
- MNG 모델 5개: InterviewCategory, InterviewTemplate, InterviewQuestion, InterviewSession, InterviewAnswer
- React 뷰: 2-패널 레이아웃 (카테고리 사이드바 + 항목/질문 관리)
- 인터뷰 실시 모달: 카테고리 선택 → 체크리스트 → 완료
- 인터뷰 기록 모달: 기록 목록 + 상세 보기
- InterviewMenuSeeder: 영업관리 > 인터뷰 시나리오 메뉴 추가
- 라우트 18개 추가 (sales/interviews/api/*)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:01:35 +09:00

209 lines
6.3 KiB
PHP

<?php
namespace App\Http\Controllers\Sales;
use App\Http\Controllers\Controller;
use App\Services\Sales\InterviewScenarioService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;
class InterviewScenarioController extends Controller
{
public function __construct(
private InterviewScenarioService $service,
) {}
// ============================================================
// 페이지
// ============================================================
public function index(Request $request): View|Response
{
if ($request->header('HX-Request')) {
return response('', 200)->header('HX-Redirect', route('sales.interviews.index'));
}
return view('sales.interviews.index');
}
// ============================================================
// 카테고리 API
// ============================================================
public function categories(): JsonResponse
{
return response()->json($this->service->getCategories());
}
public function storeCategory(Request $request): JsonResponse
{
$validated = $request->validate([
'name' => 'required|string|max:100',
'description' => 'nullable|string',
]);
$category = $this->service->createCategory($validated);
return response()->json($category, 201);
}
public function updateCategory(Request $request, int $id): JsonResponse
{
$validated = $request->validate([
'name' => 'required|string|max:100',
'description' => 'nullable|string',
]);
$category = $this->service->updateCategory($id, $validated);
return response()->json($category);
}
public function destroyCategory(int $id): JsonResponse
{
$this->service->deleteCategory($id);
return response()->json(['message' => '삭제되었습니다.']);
}
// ============================================================
// 트리 API
// ============================================================
public function tree(): JsonResponse
{
return response()->json($this->service->getTree());
}
// ============================================================
// 템플릿(항목) API
// ============================================================
public function storeTemplate(Request $request): JsonResponse
{
$validated = $request->validate([
'interview_category_id' => 'required|integer|exists:interview_categories,id',
'name' => 'required|string|max:200',
'description' => 'nullable|string',
]);
$template = $this->service->createTemplate($validated);
return response()->json($template, 201);
}
public function updateTemplate(Request $request, int $id): JsonResponse
{
$validated = $request->validate([
'name' => 'required|string|max:200',
'description' => 'nullable|string',
]);
$template = $this->service->updateTemplate($id, $validated);
return response()->json($template);
}
public function destroyTemplate(int $id): JsonResponse
{
$this->service->deleteTemplate($id);
return response()->json(['message' => '삭제되었습니다.']);
}
// ============================================================
// 질문 API
// ============================================================
public function storeQuestion(Request $request): JsonResponse
{
$validated = $request->validate([
'interview_template_id' => 'required|integer|exists:interview_templates,id',
'question_text' => 'required|string|max:500',
'question_type' => 'nullable|string|in:checkbox,text',
'is_required' => 'nullable|boolean',
]);
$question = $this->service->createQuestion($validated);
return response()->json($question, 201);
}
public function updateQuestion(Request $request, int $id): JsonResponse
{
$validated = $request->validate([
'question_text' => 'required|string|max:500',
'question_type' => 'nullable|string|in:checkbox,text',
'is_required' => 'nullable|boolean',
]);
$question = $this->service->updateQuestion($id, $validated);
return response()->json($question);
}
public function destroyQuestion(int $id): JsonResponse
{
$this->service->deleteQuestion($id);
return response()->json(['message' => '삭제되었습니다.']);
}
// ============================================================
// 세션 API
// ============================================================
public function sessions(Request $request): JsonResponse
{
$filters = $request->only(['status', 'category_id']);
$sessions = $this->service->getSessions($filters);
return response()->json($sessions);
}
public function storeSession(Request $request): JsonResponse
{
$validated = $request->validate([
'interview_category_id' => 'required|integer|exists:interview_categories,id',
'interviewee_name' => 'nullable|string|max:100',
'interviewee_company' => 'nullable|string|max:200',
'interview_date' => 'nullable|date',
'memo' => 'nullable|string',
]);
$session = $this->service->startSession($validated);
return response()->json($session, 201);
}
public function showSession(int $id): JsonResponse
{
$session = $this->service->getSessionDetail($id);
return response()->json($session);
}
public function toggleAnswer(Request $request): JsonResponse
{
$validated = $request->validate([
'session_id' => 'required|integer',
'question_id' => 'required|integer',
'answer_text' => 'nullable|string',
'memo' => 'nullable|string',
]);
$answer = $this->service->toggleAnswer($validated);
return response()->json($answer);
}
public function completeSession(int $id): JsonResponse
{
$session = $this->service->completeSession($id);
return response()->json($session);
}
}