templateService->findByIdentifier($templateName); if (! $template) { return $this->notFound('common.not_found'); } $list = $this->service->getList( $template->id, $request->input('layout_name'), $request->input('status'), ); return $this->success( 'common.success', TemplateCustomTranslationResource::collection($list), ); } /** * 커스텀 다국어 키 생성 (인라인 편집 확정) * * @param StoreCustomTranslationRequest $request 생성 요청 * @param string $templateName 템플릿 identifier * @return JsonResponse 생성된 커스텀 키 응답 */ public function store(StoreCustomTranslationRequest $request, string $templateName): JsonResponse { $template = $this->templateService->findByIdentifier($templateName); if (! $template) { return $this->notFound('common.not_found'); } try { DB::beginTransaction(); $model = $this->service->createKey( templateId: $template->id, layoutName: $request->input('layout_name'), locale: $request->input('locale'), value: $request->input('value'), createdBy: $this->getCurrentUser()?->id, ); DB::commit(); return $this->success( 'common.success', new TemplateCustomTranslationResource($model), 201, ); } catch (\Exception $e) { DB::rollBack(); return $this->error('common.failed', 500, ['error' => $e->getMessage()]); } } /** * 커스텀 다국어 키 수정 (번역 탭 일괄 편집, 낙관적 잠금) * * @param UpdateCustomTranslationRequest $request 수정 요청 * @param string $templateName 템플릿 identifier * @param int $id 커스텀 키 ID * @return JsonResponse 수정된 커스텀 키 응답 (충돌 시 409) */ public function update(UpdateCustomTranslationRequest $request, string $templateName, int $id): JsonResponse { $template = $this->templateService->findByIdentifier($templateName); if (! $template) { return $this->notFound('common.not_found'); } $model = $this->service->find($id); if ($model === null || (int) $model->template_id !== (int) $template->id) { return $this->notFound('common.not_found'); } try { DB::beginTransaction(); $updated = $this->service->updateValues( id: $id, values: $request->input('values'), expectedLockVersion: (int) $request->input('expected_lock_version'), updatedBy: $this->getCurrentUser()?->id, ); DB::commit(); return $this->success( 'common.success', new TemplateCustomTranslationResource($updated), ); } catch (ConcurrentModificationException $e) { DB::rollBack(); return $this->error( 'exceptions.concurrent_modification', 409, [ 'error' => 'concurrent_modification', 'current_version' => $e->currentVersion, 'your_version' => $e->expectedVersion, 'resource' => $e->resource, ], ['resource' => $e->resource, 'current' => $e->currentVersion, 'expected' => $e->expectedVersion], ); } catch (ModelNotFoundException $e) { DB::rollBack(); return $this->notFound('common.not_found'); } catch (\Exception $e) { DB::rollBack(); return $this->error('common.failed', 500, ['error' => $e->getMessage()]); } } /** * 커스텀 다국어 키 삭제 * * @param string $templateName 템플릿 identifier * @param int $id 커스텀 키 ID * @return JsonResponse 삭제 결과 응답 */ public function destroy(string $templateName, int $id): JsonResponse { $template = $this->templateService->findByIdentifier($templateName); if (! $template) { return $this->notFound('common.not_found'); } $model = $this->service->find($id); if ($model === null || (int) $model->template_id !== (int) $template->id) { return $this->notFound('common.not_found'); } try { DB::beginTransaction(); $this->service->deleteKey($id); DB::commit(); return $this->success('common.success'); } catch (\Exception $e) { DB::rollBack(); return $this->error('common.failed', 500, ['error' => $e->getMessage()]); } } /** * 커스텀 다국어 키 일괄 삭제 (관리 모달 "선택 삭제"/"미사용 전체 삭제") * * 요청 ids 중 해당 템플릿 소속 키만 삭제합니다(교차 템플릿 삭제 차단). * * @param BulkDestroyCustomTranslationRequest $request 일괄 삭제 요청 * @param string $templateName 템플릿 identifier * @return JsonResponse 삭제 결과 응답 (삭제 건수 포함) */ public function bulkDestroy(BulkDestroyCustomTranslationRequest $request, string $templateName): JsonResponse { $template = $this->templateService->findByIdentifier($templateName); if (! $template) { return $this->notFound('common.not_found'); } // 요청 ids 중 해당 템플릿 소속만 추려 교차 템플릿 삭제를 차단. $ownedIds = []; foreach ((array) $request->input('ids', []) as $id) { $model = $this->service->find((int) $id); if ($model !== null && (int) $model->template_id === (int) $template->id) { $ownedIds[] = (int) $id; } } if ($ownedIds === []) { return $this->success('common.success', ['deleted' => 0]); } try { DB::beginTransaction(); $deleted = $this->service->deleteKeys($ownedIds); DB::commit(); return $this->success('common.success', ['deleted' => $deleted]); } catch (\Exception $e) { DB::rollBack(); return $this->error('common.failed', 500, ['error' => $e->getMessage()]); } } }