少し小雨の元宇品をキクと散歩
2-2.承認済みパトロールの編集ロック不完全
SafetyPatrolController.php saveDraft()メソッドshow.blade.phpのUIは$isLockedフラグで編集を無効化しているが、saveDraftエンドポイントにはis_finalizedチェックがなく、直接POSTで承認済みデータを上書き可能 修正 php public function saveDraft(Request $request, Project $project, $id) { $this->authorizeProject($project); $safetyPatrol = SafetyPatrol::findOrFail($id);
// 承認済みは変更不可 if ($safetyPatrol->is_finalized) { return response()->json([‘success’ => false, ‘message’ => ‘確認済みの記録は変更できません。’], 403); } //
2-3.CLAUDE.md との相違点
項目 問題 対象箇所 session(‘success’)表示 CLAUDE.mdでは `toast.blade.phpは error のみ表示とあるが、`show.blade.phpに独自のsuccess表示が存在 show.blade.php` L23-27 ` 未使用 一覧のボタン群が直接 <button class=”bg-indigo-600…”>等で実装されている index.blade.php` L43-53 ファイル先頭の説明コメント欠如 コントローラ・モデルの先頭に「このファイルの説明文」がない SafetyPatrolController.php` 等全般 インラインスクリプト index.blade.phpの flash メッセージ消去処理がインライン<script>内に記述 index.blade.php` L26-35
1.【安全パトロール】コードの健全性検証
1.セキュリティ・脆弱性
エラーメッセージ漏洩
safetyPatrolController.php:210 php // 現状:例外メッセージをそのまま返している return response()->json([‘success’ => false, ‘message’ => ‘システムエラー: ‘ . $e->getMessage()]); PHPの例外メッセージ(DBパス・APIキー名・内部構造等)がそのままフロントエンドに露出する 修正 php // 固定文言に変更 return response()->json([‘success’ => false, ‘message’ => ‘システムエラーが発生しました。時間をおいて再試行してください。’]); // ログには詳細を記録 \Log::error(‘AI checklist generation error: ‘ . $e->getMessage());
1-2.ファイルアップロードのバリデーション欠如
SafetyPatrolController.phpstore() php // 現状:バリデーションなしで直接 store() $filePath = $request->file(‘attached_file’)->store(‘patrol_files’, ‘public’); ファイルタイプ・サイズ制限がないため、実行ファイルや大容量ファイルのアップロードが可能な状態 修正 php $request->validate([ ‘attached_file’ => ‘nullable|file|mimes:pdf,jpg,jpeg,png,gif,webp|max:10240’, ‘patrol_datetime’ => ‘required|date’, ‘inspector_name’ => ‘required|string|max:100’, ]);
1-3.CSP方針違反 インラインイベントハンドラ
CLAUDE.md に「`onclick=””等のインラインハンドラを使わず、必ず `addEventListenerで登録する」と明記されているが、以下の箇所に違反が存在する
ファイル 行 内容 show.blade.php L105, L109, L113, L117 onchange=”updateRowColor(…); autoSave()” create.blade.php L82 onclick=”runAiProcess(…)” index.blade.php L43, L47, L51, L103, L115 onclick=”window.location.href=…”
修正方針:** 各ボタンに `data-url属性を付与し、外部JSで `addEventListenerに移行
2.データ喪失リスク
SafetyPatrolController.php destroy()` メソッド php // 現状:attached_file_path のみ削除 if ($patrol->attached_file_path) { Storage::disk(‘public’)->delete($patrol->attached_file_path); } $patrol->delete(); // → safety_patrol_photos テーブルのレコードと画像ファイルは残存 パトロール削除時に、紐づく写真ファイル(storage/public/patrol_photos/)とDBレコードが削除されない。時間とともにストレージを圧迫する php // 写真ファイルとレコードを先に削除 $patrol->safetyPatrolPhotos()->each(function ($photo) { Storage::disk(‘public’)->delete($photo->file_path); $photo->delete(); }); $patrol->delete();