夕方に湯田温泉へ

建設アシストアプリケーションをマルチテナントSaaSとして「他社のデータは存在自体が見えない」状態を全モデルに実現する作業をする・・設計上の重要ポイントとして、グローバルスコープ単体ではなく、既存のIDOR(Insecure Direct Object Reference:URLのIDを書き換えて、他人のデータにアクセスする攻撃)対策トレイト(AuthorizesTenantAccess)と二重防御になっている。仮にどちらか一方に穴があっても、もう一方が守る構造で、これが大手組織のセキュリティ監査に耐えられる根拠になる

■会社IDを直接持つ主要モデル10個に、自動テナント絞り込みを適用

分類対象モデル例絞り込み方式
直接持ちUser, Project, Department など7モデルWHERE company_id = 自社
NULL=全社共通テンプレート・プリセット系3モデルWHERE company_id = 自社 OR NULL

■途中で発覚した重大問題と解決:User モデルにスコープを適用した直後、ログイン後の画面でメモリ枯渇エラーが発生・・・原因は無限再帰

■Project配下・監査計画配下のモデル13個に適用。これらは company_id を直接持たず、親テーブル経由で絞り込む
実データで確認した効果の例

モデルスコープ前スコープ後
ProjectEnvAspect241件(他社75件含む)166件(自社のみ)
ProjectCondition49件(他社23件含む)26件(自社のみ)

■最終状態
テスト:TenantIsolationTest 31パス(38 assertions) 対象:A分類10 + B分類13 = 計23モデル完了

湯田温泉駅からホテルまで2kmを歩く 湯田温泉の白狐も久しぶり
天気は曇り空 ホテルからの湯田温泉裏通りの眺め

Claude Fable5でシステムの検証

今日は雨の日曜日・・・現在最高性能を持つというAIのClaude Fable5が、6/1に提供されたが6/5には提供禁止となってしまった、7/1から再び提供されて、7/7まで使えるという・・・これは、是非とも一番課題で問題が多いシステム全体の成熟性を確認しなければ、熱も下がって少し調子も上がったので、さっそく取り掛かる

0.前提条件

  • まずFable5には修正・削除・リファクタリングは一切行わなず検証を実施する
  • 対応済みの事項は以下の内容(再確認は必要)
  • AuthorizesTenantAccessトレイトによるコントローラのテナント認可
  • SecurityHeadersMiddleware、HTTPS 強制、セッション強化、不審ログイン検知
  • CSP 対応の途中経過(インラインイベントハンドラの addEventListener 化、@alpinejs/csp 採用)

1.作業フェーズ

  • フェーズ1: セキュリティ検証(ファイル別)
  • フェーズ2: 保守性・コード品質の改善提案(全体)
  • フェーズ3: バグおよびバグの可能性の検出(全体)

2.フェーズ1: セキュリティ検証

2-1. 検証観点(チェックリスト)

A. テナント分離(最優先)

  • クエリに tenant_id 等のスコープ漏れがないか(Eloquent 直接呼び出し、find($id)、DB:: 生クエリ含む)
  • AuthorizesTenantAccess トレイトの適用漏れコントローラ・メソッド
  • ルートモデルバインディングでの他テナントリソース参照可能性(IDOR)
  • グローバルスコープの回避箇所(withoutGlobalScopes 等)の妥当性

B. 認証・認可

  • ミドルウェア(auth, verified 等)の適用漏れルート
  • Policy / Gate 未適用のまま操作可能なアクション
  • 権限昇格の可能性(ロール判定の抜け)

C. 入力検証・インジェクション

  • バリデーション未実施・不十分なリクエスト処理
  • SQL インジェクション(whereRaw, DB::raw, DB::select 等の変数連結)
  • マスアサインメント($fillable/$guarded の不備、$request->all() の直接渡し)
  • パストラバーサル(ファイルパスにユーザー入力を使用している箇所)

D. XSS・出力エスケープ

  • Blade の {!! !!} 使用箇所の妥当性
  • SVG ダイアグラムエディタ(約3,600行の JS): ユーザー入力の SVG/DOM への挿入方法(innerHTML、属性直接代入等)、保存された SVG データの再表示時のサニタイズ
  • リッチテキストバー(RTB)経由の HTML 挿入のサニタイズ

E. CSP 対応

  • 残存するインラインイベントハンドラ(onclick 等)・インライン script/style
  • SecurityHeadersMiddleware の CSP ディレクティブの妥当性(unsafe-inline / unsafe-eval の残存有無)

F. CSRF・セッション・Cookie

  • CSRF 保護の除外ルート($except)の妥当性
  • Ajax/fetch 呼び出しの CSRF トークン付与漏れ
  • セッション・Cookie 設定(secure, httponly, samesite)と Xserver リバースプロキシ構成(TrustProxies)との整合

G. ファイルアップロード

  • 拡張子・MIME タイプ検証、サイズ制限
  • 保存先(public 直下への保存有無)、実行可能ファイルの拒否
  • ダウンロード時のテナント認可

H. 情報漏洩

  • ログ・例外メッセージへの機密情報出力
  • .env 値のハードコード、デバッグコードの残存(dd, dump, console.log の機密出力)
  • API レスポンスの過剰な属性返却(Resource 未使用でのモデル直接返却)

I. 依存パッケージ

  • composer audit および npm audit を実行し、既知脆弱性を報告する(アップデートは実施しない)

3.フェーズ2: 保守性・改善提案

3-1. 検証観点
  • 重複コード: コントローラ・JS 間の重複ロジック(サービスクラス / 共通モジュールへの抽出候補)
  • 肥大化: 長大なコントローラメソッド・Blade ファイル・JS ファイル(特に SVG エディタ約3,600行の分割方針)
  • 命名・構成: Laravel 標準構成からの逸脱、命名の不統一(日本語/英語混在の規則性含む)
  • 設定のハードコード: config/env に逃がすべきマジックナンバー・文字列
  • テスト: 自動テストのカバレッジ状況、テナント分離・認可まわりのテスト欠落箇所
  • フロントエンド: Blade 内 JS の構造(モジュール化、イベント委譲の一貫性、Alpine.js との役割分担)
  • DB: マイグレーションとスキーマの整合、インデックス欠落(tenant_id 複合インデックス等)、N+1 クエリ
  • ドキュメント: CLAUDE.md / README の実態との乖離

4.フェーズ3: バグおよびバグの可能性

4-1. 検証観点
  • 明確なバグ: 未定義変数・null 参照、型不整合、到達不能コード、条件式の誤り(=/==/=== 等)
  • JS 側: SVG エディタのイベントリスナー解除漏れ(メモリリーク)、tblMergeCells/tblSplitCell 等テーブル操作の境界条件、undo/redo の状態不整合、非同期処理の競合
  • 境界条件: 空配列・null・0件データ時の挙動、日付境界(年度・和暦処理があれば特に)
  • トランザクション: 複数テーブル更新時のトランザクション欠落、失敗時のロールバック不備
  • 並行性: 同一テナント内の同時編集での上書き・競合(楽観ロックの有無)
  • 環境差異: MariaDB(ローカル)と MySQL(本番)の差異に起因する潜在問題、Xserver 固有設定への依存
  • エラー処理: try-catch の握りつぶし、失敗時にユーザーへ誤った成功表示をする箇所

5.実行手順

  1. リポジトリ構成を把握する(app/, routes/, resources/views/, resources/js/, database/, config/, public/ を中心に全体を読む。vendor/, node_modules/ は除外)
  2. フェーズ1を実行し、レポートを出力して停止・確認を待つ
  3. 承認後フェーズ2を実行し、レポートを出力して停止
  4. 承認後フェーズ3を実行し、レポートを出力して完了報告
  5. 各フェーズの完了報告には「検証したファイル数」「読み飛ばした箇所とその理由」を必ず含める(検証の網羅性を判断できるようにするため)

F1.セキュリティ検証レポート(フェーズ1)

F1-1.検証規模
  • コントローラ: 約40ファイル / モデル: 約50ファイル / Blade: 約168ファイル / ルート: 3ファイル / サービス: 8ファイル
  • 検証観点: A テナント分離 / B 認証・認可 / C 入力検証・インジェクション / D XSS / E CSP / F CSRF・セッション / G ファイルアップロード / H 情報漏洩 / I 依存パッケージ
F1-2.指摘件数(重大度別)
数主な内容
Critical7クロステナント IDOR 群(工程表・安全パトロール・RA・施工計画書)、CSP unsafe-inline + 保存型XSS の複合、phpspreadsheet SSRF/RCE
High12テンプレート認可欠落、機密ファイルの public 保存、保存型XSS(図面/AI-HTML/style属性)、依存パッケージ High、-tmp/_old ファイルのオートロード混入
Medium15Mass Assignment、例外メッセージ露出、グローバルマスタ越境、パストラバーサル、Secure Cookie 未設定 等
Low多数多層防御・推奨改善(代表例+件数で集約)
F1-3.総評
  • 全モデルにテナント用グローバルスコープ(BelongsToTenant 等)が存在せず、テナント分離は各コントローラの手動 authorizeProject() に全面依存している。
  • そのうえ authorizeProject() は「Project が自社か」しか見ず、ネストした子リソース(schedule / patrol / riskAssessment / item)の親一致を検証していないメソッドが多数あり、Route::scopeBindings() も未使用。結果として「自社の Project ID + 他社の子リソース ID」を URL に並べるだけで他テナントのデータを閲覧・改ざん・削除できる Critical な IDOR が7系統存在する。
  • 加えて CSP に script-src ‘unsafe-inline’ が残存し、図面ノード・AI整形HTMLがサーバー側サニタイズなしで保存・再表示されるため、保存型XSSが現実的に成立する。

一方で、認可が正しく実装されているコントローラ群も多く(ProjectPlan / Audit 系 / CompanyAdmin など)、修正パターンは「authorizeProject() の追加 + 子リソースの親一致 abort_if の2行」と明確です。恒久対策として Route::scopeBindings() の全面適用とグローバルスコープ導入を行えば、監査耐性は大きく向上します。

F2.保守性・改善提案レポート(フェーズ2)

F2-1.テナント設計の未完了モデル洗い出し

重要な前提: 本アプリには BelongsToTenant 相当のグローバルスコープ(addGlobalScope)は1つも存在しない。テナント分離はすべてコントローラ内の手動 where(‘company_id’, …) / authorizeProject() に依存している。既存の booted()(BarTask / NetworkNode / NetworkArrow)は front_id(UUID)採番専用でスコープではない。したがって下表の「グローバルスコープ」列は全モデル「未実装」。

テナント到達経路: 子テーブルは company_id を持たず、project_id → projects.company_id(または schedule_id → schedules.project_id、audit_report_id → audit_plans.company_id 等)の多段リレーションでのみテナントを特定できる。

F2-2.観点: 重複コード
  • 【高】Anthropic API 呼び出しの8重複(CLAUDE.md「AI推論は共通コード」ルール違反)
  • 【高】テナント認可の二重方式(トレイトがあるのに手書きが残存)
  • 【中】★ CSV入出力ロジックの6重複
  • 【中】Docx/Xlsx出力の二系統併存(デッドコードの懸念)
  • 【中】フロントエンド fetch/CSRF/モーダル制御の重複
F2-3.観点: 肥大化

コントローラ行数 Top10(実測)

数ファイル
1548ConstructionPlanController.php
952ProjectPlanController.php
865NetworkScheduleController.php
687SafetyPatrolController.php
573EnvironmentController.php
432RiskAssessmentController.php
392BarChartController.php
350ChecklistController.php
313UserController.php
251CompanyAdminController.php

【高】Blade巨大ファイル(インラインJS肥大)

数ファイル特記
3082schedules/network.blade.php単一<script> が724-3080の約2356行
2439schedules/barchart.blade.php同様の巨大インラインJS
1875projects_plan/edit_section.blade.php@push(‘scripts’)+diagram-editor-script include+openCtxMenu上書きIIFE
854environment/edit_environment.blade.php
729projects_plan/setup.blade.php対応 setup.js(392行)は分離済み=良い前例
  • 提案: network / barchart の巨大インラインJS を resources/js/schedules/network.js・barchart.js に外部化(setup.js の前例に倣う)。CSP unsafe-inline 除去の前提条件でもある。
  • 想定作業量: 大 → 別途計画が必要

【中】SVGダイアグラムエディタ群(実測 計4172行)の再分割
既に責務別5分割済み(良い設計)だが個別ファイルが肥大:

数ファイル責務
1541diagram-editor-nodes.blade.phpノードCRUD/RTB/画像/線ノード
1132diagram-editor-table.blade.php表/Excel貼付/xspreadsheet
726diagram-editor-ui.blade.php右クリック/保存/ページ/テンプレ/印刷
602diagram-editor-connect.blade.phpコネクタ/接続線ダイアログ
154diagram-editor-core.blade.php状態/Undo-Redo/グリッド
▶この続きを見る・・・・

iPad Proの復旧

iPad Proが急に起動しなくなった 長い時間をかけてようやく初期化をする

2020年4月に購入した、11インチiPad Pro 512GB Wi-Fi + Cellularモデル(iPad Pro11 第2世代)、もう6年間使用していることになるが、まだまだ現役で何の不自由もない・・ところが、大阪出張中に急にエラーが発生して、復旧不能となった・・・・Appleのサイトの手順に従って復旧を試みるが、復旧できない・・帰ってclaudeに相談して解決策を探ると、すぐ解決策を示してくれた
症状は、突如として復旧できないとのメッセージが出て、リセット→ リンゴマークが出る→長い間かかって→復旧の画面・・このiPadで問題が起きました→続ける→診断データ収集→Appleにデータ送信→パスワード入力要求→復旧できません→再起動:の繰り返し、となる・・・これは、ソフトウェアの深刻な損傷で、DFUモードからの復元が唯一の選択肢らしい
DFUモードの手順
事前準備

  • MACminiに良質なケーブルでiPadを接続
  • Finderを開いて待機

手順(タイミングが命)

  • 音量上ボタン → 素早く押して離す
  • 音量下ボタン → 素早く押して離す
  • 電源ボタンを 10秒間押し続ける
    10秒後、電源ボタンを押したまま → 音量下ボタンも同時に押す
    そのまま 5秒間 両方押し続ける
    5秒後、電源ボタンだけ離す(音量下は押し続ける)
  • さらに 10秒間 音量下を押し続ける

何回かチャレンジしてようやく成功・・・!!
成功すると:

  • iPadの画面は真っ暗のまま(ロゴも何も出ない)
  • Finderに「DFUモードのiPadを検出」と表示される
  • これから、iPadにOSを再インストールする

長い時間がかかってOSの再インストールが終わりiPadは初期化されて復旧・・これから認証して、各種アプリケーションのセットをするが、iPhoneがあったので同期させて認証は楽だった

キクと元宇品

朝は甲斐犬のキクと元宇品をぐるりと回る

2.onclick / onchange インラインハンドラを addEventListener に移行する

サーバー側のバリデーション・サニタイズと、ブラウザ側のCSPの両方が必要

  • グループA:サイドバー(id 付き → そのまま addEventListener)
  • グループB:サイドバー(id なし → id を付与してから addEventListener)
  • グループC:ページタブバー(id なし → id 付与)
  • グループD:ナビバー(Blade 条件分岐内)
  • フローティングRTB(書式ツールバー)のインラインハンドラ移行

施工計画のエディット画面(edit_section_blade.php)が、ほぼ実装が完了したので、再びコードの検証を行う・・・やはり、まだ課題が多く残っていたので、順にコードの手直しをする

1.生HTML出力({!! !!})を使用している

{!! !!} はエスケープなしの生出力のため、$headerHtml / $footerHtml がDB経由で、悪意あるスクリプトを含む場合、XSS攻撃が成立する。
サーバーサイドでのサニタイズ(無害化)状況を確認し、不十分であれば修正する・・・XSS(クロスサイトスクリプティング)、SQLインジェクション・・以下はサニタイズの手法

手法内容
エスケープ特殊文字を無害な表現に変換(< → <)
除去危険な文字・タグを削除
バリデーション想定外の値を拒否(数字のみ受け付けるなど)
プレースホルダSQLをコードと分離して処理

これらの手法は、Laravelでは多くは自動で処理してくれるが、施工計画のSVGダイアグラムエディタのような自前JS処理部分は別途確認が必要

1-1.データの流れを追跡する
  • コントローラを特定する(ルート名 project_plans.sections.editから逆引きする)
  • $headerHtml / $footerHtml の生成箇所を特定する
  • DBカラムの確認
1-2.現状の判定(サニタイズ処理必要性の検証)
  • ✅ 安全なケース(修正不要)
  • ❌ 要修正なケース(対応する、入力時サニタイズ、HtmlPurifier の導入確認、サービスクラスまたはヘルパーの作成、コントローラの保存処理にサニタイズを追加、既存DBデータの一括サニタイズ(Artisan コマンド))
1-3.実施結果

Claude Codeでの実施結果ではOK、変更なし、コメントを追記

▶この続きを見る・・・・

五日市の埋立地 施工計画エディタ画面修正

今日は雨は上がった 五日市の埋立地
大きな砂州が伸びていた 朝食と昼食を兼ねてフレンチトーストとケンタッキーのフライドチキン

Claudeで質問し検討し、指示書を作成させて、Claude Codeで作業をさせるパターンで、テキストボックスの修正をする・・Claude Codeだけでは実行するだけがメインなので、検討が不足する・・やれやれ、恐ろしい世界になったものだ

一日かけて、エディタのテキストボックスの編集を修正
ようやくテキストボックスのウインドウ画面のデザインが確定

J58のパーツが届く 施工計画の全面修正

土曜日だが、朝から一日雨がℎぐり続く・・・まあ、梅雨だから当たり前だが、キクの散歩はみなと公園・・・一日中、施工計画の改修

フロントブレーキのシリンダー4個を購入
フリーハブのパッキンとキングピンのシムを購入

施工計画書作成のエディタ分析(diagram-editor-script)

  • 完全自作図面エディタエンジン
  • 174関数 / 3,686行 / 166KB、→ 単一ファイルとしては限界に近いサイズ
  • 外部ライブラリなし、SVGとdivだけでDrawio・Visioのような図形編集を自力実装
観点評価
コード品質セクション分けが明確で追いやすい
機能完成度商用ツールに近いレベル
CSP対応95%完了・ページタブのみ残存
データ設計JSON構造が明確で拡張しやすい
リスク箇所renderPageTabs()のinline onclick


リファクタリングの優先順位

優先内容効果
🔴 高 getTargetId()関数を1つ作りID取得を統一バグ防止
🔴 高 setBg()をapplyBoxBg()に統合重複解消
🔴 高 toggleBorder()をapplyNodeBorderToggle()に統合重複解消
🟡 中 ctx系をコア関数に引数追加で統合コード削減
🟡 中 tbl系を別ファイルに切り出し見通し改善
🟢 低 snapshot()をラップして自動呼び出し化snapshot()をラップして自動呼び出し化呼び忘れ防止
▶この続きを見る・・・・

施工計画書の再構築 Claude Fable 5の話

今週はほとんどの時間を施工計画書の再構築で費やした・・・自由に表や画像およびテキストをキャンバスに配置して、計画書をつくることは難しい・・・結局、色々試したが、使い慣れたVisio的な画面操作で作成することにした・・・作成はやはり、かなり難易度が高く、構築指示も何回も失敗したが、さすがにClaude Code、最後は何とか意図する内容にまとめてくれた
これから、実際に施工計画書を作成して、効果的なテンプレートをつくりながら、システムの使い勝手を検証してゆく

施工計画書 セットアップ画面 あらゆるタイプの施工計画書に対応できる

世界中のあらゆるサーバーはハッキング出来ると恐れられ、提供が中止されていたClaude Mythosに、安全フィルターが施されたClaude Fable 5が提供させるようになった・・・6/22まではトークンは消費(2倍)されるが、無料で使うことができるようになっていた・・・この間にシステム全体の診断をさせようと思っていたら、開始から3日目でUSAからの指示で提供が禁止(アメリカ国民以外は使用禁止・・だが、区別ができないので全世界で禁止となった)されてしまった・・・これからのAIの使い方に新しい波がやってくる予感

施工計画書 作成画面(Visio的な操作を実施)
▶この続きを見る・・・・

京橋川の土手を散歩 施工計画書再構築

京橋川の土手を散歩
甲斐犬のキクと一緒に

施工計画書 セットアップ画面 再構築
resources/views/projects_plan/setup.blade.php を中心に、セットアップ画面の右パネルを大幅改修・・・手直しではなく作り直しに

1.変更ファイル一覧
1-1.マイグレーション(新規)

database/migrations/2026_06_13_000001_add_margin_to_project_plans_table.php
project_plans テーブルに余白カラムを追加margin_top(上余白 mm、デフォルト25)margin_bottom(下余白 mm、デフォルト25)margin_left(左余白 mm、デフォルト25)margin_right(右余白 mm、デフォルト20)

1-2.ルート追加(routes/web.php)
メソッド     URL名前用途
PATCH{plan}/settings|project_plans.update_settings全体一括保存
POST{plan}/change-work-typeproject_plans.change_work_type工事種別変更
POST{plan}/sectionsproject_plans.sections.storeセクション追加
1-3.コントローラー(app/Http/Controllers/ProjectPlanController.php)
  • 建築系セクション定義を24項目に更新(総合施工計画〜給排水衛生工事)
  • updateSettings() 追加:ヘッダー/フッター・余白・セクション並び順/名前を一括保存
  • changeWorkType() 追加:工事種別変更(既存セクション全削除 → 新規種別で再作成、JSONで新セクション一覧を返す)
  • addSection() 追加:カスタムセクション追加
▶この続きを見る・・・・

九州の友人から贈り物 施工計画書見直し

天気が良い、元宇品の海岸を散歩
ニンニクとジャガイモを送っていただいた

建設アシストの中で、最も難しいと言える【施工計画書】の作成について、大幅に見直しを実施する・・施工計画書のタイプは、官庁系、民間系、建築系、土木系、設備系と種類が多く、様式も組織によって、発注者によっていろいろな種別があり統一性が難しい
今までは、官庁系が主体の土木系に絞って作成をしていたが、色々な様式とタイプに対応するべく、全体の構成をフレキシブルなものに変えて、カスタム性を強くする・・・また、合わせてセキュリティ面、コードの健全性も考慮する

1.現状調査結果

1-1.ファイル構成と役割
resources/views/construction_plans/index.blade.php大項目一覧(1〜24番 + 表紙・目次)のチェック管理画面
resources/views/construction_plans/print_item.blade.php個別項目のPDF印刷用ビュー(キャッシュ無効化・A4最適化)
resources/views/construction_plans/ai_print_item.blade.phpAI整形HTMLの編集・出力画面(Word/Excel生成機能付き)
resources/views/construction_plans/diagram_editor.blade.phpフローチャート・図面エディタ(A4キャンバス・テンプレート機能)
app/Http/Controllers/ConstructionPlanController.phpメインコントローラー(1,550行・39メソッド)
app/Models/ConstructionPlan.php施工計画書モデル(プロジェクトと1:1)
app/Models/ConstructionPlanItem.php大項目モデル(TipTap JSON対応)
app/Models/ConstructionPlanImage.php画像管理モデル
app/Models/ConstructionPlanTemplate.phpテンプレートモデル(会社別/共通)

コントローラーに editItem() メソッドと editPlan() メソッドがあり、それぞれ
construction_plans.edit_item と construction_plans.edit_plan を参照しているが、ファイルが存在しない。
これはルーティングエラーの原因となる可能性がある。
調査時点では該当ルートが routes/web.php に登録されているかは要確認。

▶この続きを見る・・・・

墓参り 工事管理の見直し

墓掃除と墓参り
1-2. edit_overview.blade.php 削除
変更詳細
edit_overview.blade.php削除
routes/web.phpprojects.overview.edit / projects.overview.update ルートを削除
ProjectControllereditOverview() / updateOverview() メソッドを削除

残留リンク確認: resources/views/projects/ 内に overview ルートへの参照なし(削除前にgrep確認済み)

甲斐犬のキクも一緒に

2.show.blade.php — 工事編集ボタンの移動

変更前: <x-slot name=”nav_extra”> でヘッダータブとして表示
変更後*: 工事名・ステータスバーの右端にボタン配置

[ 工事名 (施工中) ] ··················· [ 部署: ○○ ] [ 担当: ○○ ] [ ✏️ 工事編集 ]

プロジェクトの管理画面を刷新

プロジェクト管理プロセスのセキュリティ及びファイルの健全性を検証

1.コードファイルの統合

1-1. create.blade.php + edit.blade.php → edit.blade.php(統合・create 削除)

統合方法:

  • $project->exists(Eloquent 未保存インスタンスかどうか)で動作を切り替え
  • 新規モード(exists = false): フォーム action → projects.store、HTTP method → POST、入力値なし
  • 編集モード(exists = true): フォーム action → projects.update、HTTP method → PATCH、old() + 既存値
  • ヘッダー文言・キャンセル遷移先・会社名ソース・nav_extra タブをモードで分岐
  • ProjectController@create() を view(‘projects.edit’, [‘project’ => new Project()]) に変更
  • 影響範囲: index.blade.php の route(‘projects.create’) はそのまま動作(resource ルートは維持)
変更前変更後
create.blade.php(新規登録専用)削除
edit.blade.php(編集専用)create+edit 統合版に書き換え
▶この続きを見る・・・・

元宇品散歩 建設アシスト安パト見直し

少し小雨の元宇品をキクと散歩
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.phpL105, L109, L113, L117onchange=”updateRowColor(…); autoSave()”
create.blade.phpL82onclick=”runAiProcess(…)”
index.blade.phpL43, L47, L51, L103, L115onclick=”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();

▶この続きを見る・・・・

雨の竜王公園を散歩 アップロード画像の縮小

娘たちを茶会に送り、雨の竜王公園で甲斐犬のキクと散歩

朝から雨が降り続ける日曜日、娘たちを送って、また迎えに行く・・・今日はお隣が地鎮祭
建設にアップする画像の軽量化のルーチンを組み込んで、DBに取り込む画像の軽量化を図る

建設アシストの最初の画面を組織全体の管理画面として、組織urlをインフレームにしていたが、ほとんどエラーとなるので、画像に切り替え

画像アップロード共通化・圧縮対応

1.概要

システム全体の画像アップロード処理を共通サービス化し、GDライブラリによる圧縮・リサイズを追加した

2.対象箇所の調査結果

コントローラーメソッド最大  ストレージパス
CompanyAdminControlleruploadLogo5MBcompany_logos/
ProjectControlleruploadPhoto50MBphotos/
ChecklistControlleruploadEvidence50MBevidence/
ConstructionPlanControlleruploadItemImage5MBplans/{id}/images/
ConstructionPlanControlleruploadTemplateImage5MBtemplates/images/
SafetyPatrolControllerstorePhoto10MBpatrol_photos/

以下は非画像混在・CSV等のため対象外とした:

  • RiskAssessmentController(Excel/Word/PDF/Image混在)
  • SafetyPatrolController::store(PDF/Image混在、圧縮不可のPDFが主)
  • AdminController, AuditMasterController, EnvironmentController, IsoClauseController(CSVのみ)
▶この続きを見る・・・・

元宇品の散歩 環境側面の見直し

甲斐犬のキクと元宇品を散歩
高射砲陣地跡の公園はきれいに草が刈ってあった

法規制の特定を見直したので、同じような処理をしている環境側面の特定方法も修正する
今まで特定のための検索条件を工事概要から実施していたが、法規制の特定で作成した工事に関する条件DBを共有化、項目追加することに変更する・・・また、フロントエンドも法規制と同じようにする

質問回答
条件保存方式project_conditions` テーブル新規作成。環境側面モーダルの条件も同テーブルに登録
AI軽量化今回は対象外。次のステップとして実施
edit_overview の廃止範囲☑ボックスで設定した内容を概要欄に転記する機能をすべて廃止。テキストボックスのみに変更
@section(‘extra_tabs)環境側面編集画面のみで使用。他ページへの影響なし

1.edit_overview.blade.php の変更

1-1.廃止する要素

現在のファイルは3エリアで構成:

エリア内容対応
エリア1(上部)textareaとフォーム残す
エリア2(中央)「選択した項目を概要に追加する」ボタン残す
エリア3(下部)チェックボックス群(工事種別・立地条件・工事規模・工事の特性・仮設設備等)削除
▶この続きを見る・・・・

雨の散歩 法規制の再構築コーディング開始

雨の広島港
雨の広島みなと公園をキクと散歩
1-3.更新ファイル

app/Models/Regulation.php ← $fillable 新カラム追加
app/Http/Controllers/ChecklistController.php ← 全面再構築
app/Http/Controllers/AdminController.php ← CSV新フォーマット対応
resources/views/components/eval_modal.php ← deleteEvidence URL修正
resources/views/layouts/footer.blade.php ← z-50 → z-10(モーダル被り解消)
routes/web.php ← conditionMatchルート追加・deleteEvidenceルート修正

法規制特定のコードの問題点が洗い出せたので、Excelシートをもう一度、見直しと再構築をして、いよいよコードを作成する

もう一度、法規制をまとめたExcelシートを見直す・・しっかり作ったつもりだったが、また変更追記する箇所が多くある・・・法律は難しい

1.法規制特定機能 再構築(Step 1〜8)

1-1.概要

edit_Laws_Regulations.blade.phpとindex.blade.phpを指示書に従い全面再構築した

1-2.新規作成ファイル

database/migrations/
2026_06_05_095137_add_select_columns_to_regulations_table.php
2026_06_05_095150_add_source_to_checklist_results_table.php
2026_06_05_112359_add_unique_index_to_checklist_results_table.php
app/Services/
RegulationMatcherService.php
resources/views/
components/laws_condition_modal.blade.php
Laws_Regulations/edit_Laws_Regulations.blade.php ← 新設計版
Laws_Regulations/index.blade.php ← 新設計版
Laws_Regulations/_tab_bar.blade.php ← 共通パーシャル

▶この続きを見る・・・・

キクと散歩 法規制コードの3回目の修正

京橋川の土手をキクと散歩
checklist_results (プロジェクト別選択結果)

※課題:保存は全件DELETE → INSERT の洗い替え方式

カラム型役割
project_idFK現場
regulation_idFK法規制
is_checkedboolean適用/非適用

c

法規制のコードを見直しを始めた・・・まずは現状分析

1.現在のテーブル構成

regulations`(法規制マスタ)

※課題:ai_description1列に「キーワード」と「制御フラグ」を混在させている

カラム型 役割
idPK—
parent_idFK(self)親=null、子=親ID(2段構造)
group_codestring法律名(主に親)
ref_lawstring関係条文(主に子)
action_contentext実施すべき内容
full_law_texttext原文(展開表示用)
ai_descriptiontextAI判定用キーワード(【選択必須】/【選択しない】制御フラグも兼用)
explanation_imagestring解説画像
▶この続きを見る・・・・

我が家の妻側が丸見え 労働安全衛生法のレビュー

隣の家の解体が終わり、家の妻側が丸見えに
長い間、外壁も手入れをしていないので少しくたびれています
夕方にキクと散歩

建設アシストの法規制管理の見直しを貸しする・・これで2回目となる
それなりに満足できる法規制の特定とはなっているが、もう一度判定に使っているAIを検討した結果、AIに頼らず、条件選定で多くが可能なことが分かってきたので変更を検討するが、今まで法規制の解釈のためにベースとなる体系(Excel→CSVで取込)を見直しをする必要ができてきた
2回目も、かなり突っ込んできたが、途中でかなり妥協をしていたので、今回は腰を入れて見直しを開始する・・・やはり、安衛法の解釈は複雑、言葉の定義から、法規制と思っていたのが実は「ガイドライン」だったり、新しい発見も多い・・・1日をかけて約半分まで終わったが・・・疲れる

ここで、もう一度「元請」周りの安衛法による定義を確認する

呼称意味根拠
事業者労働者を使用する者すべて(元請も下請も)法2条3号
注文者仕事を他人に請け負わせる者(下に出せば中間業者も注文者)法31条等
元方事業者一の場所の仕事の一部を下請に請け負わせている事業者=元請(全業種共通)法15条1項
特定元方事業者元方事業者のうち建設業・造船業(特定事業)のもの法15条1項
関係請負人元方事業者の下のすべての請負人(一次・二次…下請全部)法15条1項

選任される「人」の呼称

呼称誰が選任役割根拠
統括安全衛生責任者特定元方事業者現場全体の安全衛生を統括管理する人法15条
元方安全衛生管理者特定元方事業者統括の管理事項のうち技術的事項を管理する人法15条の2
店社安全衛生管理者特定元方事業者(中小規模現場)店社(支店等)から現場を指導・巡視する人法15条の3
安全衛生責任者各下請(関係請負人)統括安全衛生責任者との連絡役法16条
  • 元方事業者(全業種)→ 法29条:関係請負人とその労働者が法令違反しないよう指導する義務。建設業ではさらに法29条の2で危険場所の技術的指導。
  • 特定元方事業者(建設・造船)→ 法30条:統括管理措置。協議組織の設置・運営、作業間の連絡・調整、作業場所の巡視、関係請負人の安全衛生教育の指導・援助、仕事の工程・機械設備の配置計画と関係法令措置の指導、その他労働災害防止に必要な事項の6つです。
  • 注文者(設備等を請負人に使わせる者)→ 法31条:足場・型枠支保工等の設備面の措置

雨のみなと公園 コードのレビュー

キクとみなと公園の散歩 雨はかなり降っている

台風の接近で朝からかなりの雨です・・・甲斐犬のキクの散歩は予定通り、上下に登山用のレインコートを着込んで散歩、でも40年前のゴアテックスは効果が薄く、かなり浸み込んできました・・・やはり、新しいのを使わないと大雨は無理かな

雨のみなと公園をまわる
公園には誰もいない

環境側面であるコードのレビューを実施した
\environment\edit_environment.blade.php
\environment\index.blade.php

1.最優先:CSPとインラインハンドラの矛盾

これが一番の地雷です。直近で@alpinejs/cspに移行してscript-srcから unsafe-eval を外したのに、1-1.この2画面はインラインイベントハンドラだらけonclick=”openAiModal()” / “closeAiModal()” / “runAiEstimate()”
onclick=”addCustomRow()” / “removeCustomRow(this)”
onclick=”window.print()”
script-srcからunsafe-inlineも外す方針なら、これらは全滅
Alpineだけ対応しても、素のonclickが残っていればCSPの一貫性は崩れる・・セキュリティ監査を目標にするなら、unsafe-inline除去は通過点になるはずなので、ここはaddEventListener方式へ統一すべき・・幸い既に477〜492行で同パターンを使っているのでdata-action=”open-ai-modal”のような属性+委譲リスナーに寄せれば機械的に直せる

▶この続きを見る・・・・

iso_app 開発ロードマップ

1. プロジェクト概要

so_app は、建設会社の作業所管理をシステム化した業務アプリケーションです。ISO監査・施工計画・環境側面・リスクアセスメント・安全パトロール・法規制管理を統合した、建設DXを目指した詳細な管理システム

項目内容
技術スタックLaravel(PHP) + Vite + Tailwind CSS + SQLite/MySQL
AI機能Claude API(法規制選定・環境側面推論・監査支援)
モデル数約45モデル(ISO監査・工事管理・環境・安全・リスクなど)
現在の状態複数社でテスト運用中
目標建設業界のDX化
特徴セキュリティを重視した「統制下でのAI活用」の実証システム

2. フェーズ別ロードマップ

Phase 1: 品質と信頼性の確立(現フェーズ)
作業状態
セキュリティ監査(Critical 1〜4 テナント分離)✅ 完了
セキュリティ監査(High 7〜9 認可漏れ)✅ 完了
AI送信情報のガード機構(InputValidator)⏳ 次タスク
AI送信内容の透明性確保(ユーザー画面への明示)⏳ 予定
Medium 13 ファイル名処理⏳ 予定
Phase 2: 保守性と共通化
今後作業効果
Blade コンポーネント化(写真・添付・印刷UI)新機能追加が高速化
AI Service の共通基底クラスAI呼び出しの一元管理
PrintHelper・共通ヘルパー関数の整備重複コードの削減
トレイト化(HasPhotos, HasAttachments等)モデルの統一化
Policy への移行(Phase 3)認可の構造的解決
グローバルスコープによるテナント自動分離忘れて漏れる事故の防止

4. 直近のアクションアイテム

作業内容対象ファイル状態
InputValidator の実装(AI送信ガード機構)app/Services/Ai/InputValidator.php⏳
既存AI Serviceへの組み込み(5箇所)AiRecommendationService等⏳
Environment + RiskAssessmentへのトレイト確認完了確認✅
ai_usage_logs テーブルの設計・作成database/migrations/⏳
プロンプトキャッシュの実装全AI Service📅
ログローテーション設定(.env変更)config/logging.php📅

5. 業界への影響と目標

このシステムは「技術者が作った業務システム」ではなく、「業務実践者がAIを道具として使って作った業務システム」です。建設業界のDX化に向けて、特に以下の点で先進的な位置付けにあります

  • ISO監査・施工計画・環境・安全・法規制管理の統合(業界で類を見ない)
  • 「機密情報は外部AIに出さない」設計によるセキュリティと利便性の両立
  • 大手企業の情報セキュリティ要件に対応可能な「統制下でのAI活用」の実証
  • 30年以上の建設業務経験と20年のISO審査経験が詰め込まれた業務知識

今AIの活用に伴い、AIのセキュリティが大きな課題となっていますが、「AI使用禁止」ではなく、「適切な制御下での活用」という選択肢を具体例として示すことが目標とし、このシステムが業界全体のAI活用推進のモデルケースとなることを目指します

Phase 3: AIゲートウェイ・セキュリティ監視
今後作業期待効果
AI利用ログテーブル(ai_usage_logs)の実装コストの可視化・会社別分析
コスト制御(予算上限・アラート)コスト制御(予算上限・アラート)APIコストの自動管理
ルールベース匿名化サービス機密文書の安全なAI活用
セキュリティ監視Console Command日次自動チェック
セキュリティダッシュボード運用状況の可視化
プロンプトキャッシュの実装APIコスト最大90%削減
Phase 4: 組織内AI・高度なセキュリティ
今後作業内容
Ollama + ローカルLLMの検証自前AIの感触をつかむ(無料)
契約書・技術文書の匿名化処理機密情報を外部に出さない仕組み
統合AIパイプライン匿名化→外部AI→復元の一連の流れ
AI利用の完全監査ログセキュリティ監査員AI
管理ダッシュボードの高度化リアルタイム監視・異常検知
Phase 5: 商用化準備
今後作業内容
サーバーセキュリティの強化ファイアウォール・HTTPS・バックアップ
ユーザー管理のセキュリティ強化パスワードポリシー・2FA・セッション管理
スケーラビリティ対応複数社本格導入への対応
SLA・サポート体制の整備商用化に向けた運用体制

3. サーバー・ユーザー管理セキュリティ計画

3.1 ユーザー管理の強化(優先度高)
項目内容優先度
パスワードポリシー複雑性要件・有効期限の設定高
ログイン試行回数制限ブルートフォース攻撃対策高
セッションタイムアウト一定時間後の自動ログアウト高
退職者の即時無効化アカウント無効化フローの整備高
二要素認証(2FA)重要操作時の追加認証中
アクセスログ閲覧UI管理者向けの操作履歴確認機能中
3.2 サーバーセキュリティ(段階的に対応)
項目内容難易度
HTTPS の徹底SSL証明書の設定・自動更新低
不要ポートの閉鎖ファイアウォール設定
中
OS・PHP・Laravelのアップデート方針定期更新のルール化低
バックアップ体制自動バックアップの設定・復旧手順中
ログローテーション日次ローテーション設定(保存14日)低
依存ライブラリの脆弱性チェックcomposer audit の定期実行低

新しいマザーボードに交換

現在のパソコンの構成

  • マザー ASUS ROG STRIX B550-A GAMING
  • CPU Ryzen9 3950X(16C32T 3.5-4.7GHz)
  • メモリ DDR4 PC4-28800 3600MHz 2✕32GB=64GB
  • グラフィックボード GeForce RTX™ 4070 Ti
  • M.2SSD PCle4.0 NVMe M.2 Kingston KC3000 1021GB PCIe Gen 4.0 x4 70000MB/S
  • M.2 SSD PCIe Gen4x4 NVMe M.2 diloca EN760 2TB 2280 4800MB/s
  • 電源 MSI 750W MAG A750GL PCIE5  PS1326
    ・PCIe 5.0 GPU ネイティブ16ピン(12VHPWR)450W対応
    ・ATX 3.0 対応/フルモジュラー設計
    ・80 PLUS Gold認証取得
  • ケース NZXT(CA-H510E-B1)
マザーを交換してケースに組込む
マザーに仮組して、稼働を確認
ASUS ROG STRIX B550-A GAMINGでAMD Ryzen 5000シリーズ AM4 対応 メモリはDDR4
新しいマザーボードが届いていた

今回は、パソコンの修理は、マザーだけを交換する、他のパーツはすべて前のを流用・・さっそく裸で組んで、テストをすると無事に起動、ケースをパーツを清掃して組込み、12時前にセットが完了した

ログインに関するセキュリティ

1.ログインに関するセキュリティ

SaaS運用に向けたセキュリティ強化として、フェーズ1(必須項目)の完了およびフェーズ2の主要項目を実装した。

1-1. HTTPS強制(フェーズ1)
  • iPadのChromeブラウザでログインフォーム送信時に「送信されている情報は保護されません」の警告が表示されていた。
  • XサーバのSSL化は設定済みだったが、LaravelのURL生成がHTTPになっていた。
    ① `app/Providers/AppServiceProvider.php` に追記
    “`php
    use Illuminate\Support\Facades\URL;

    public function boot(): void
    {
    if (!app()->environment(‘local’)) {
    URL::forceScheme(‘https’);
    }
    }
    ② `bootstrap/app.php` にTrustProxies設定を追加
    “`php
    $middleware->trustProxies(at: ‘*’);
    “`

結果

  • iPadでの警告が解消された。
  • ローカル環境(HTTP)では適用しない条件分岐を追加し、ローカルの動作も正常化。
1-2. セッションのセキュア設定(フェーズ1)

本番・ローカル各.envに以下を追記:

項目本番ローカル
SESSION_SECURE_COOKIEtruefalse
SESSION_ENCRYPTtruetrue
SESSION_SAME_SITEstrictlax

結果

  • セッションCookieのHTTPS限定送信を設定。
  • セッションデータの暗号化を有効化。
  • 既存ログインユーザーのセッションが一度無効化されたが、再ログインで正常動作を確認。
1-3. ログイン失敗のロック機構(フェーズ1)

app/Http/Requests/Auth/LoginRequest.php を確認した結果、Laravel標準のRateLimiterによる以下の機能がすでに実装済みであることを確認した。

  • 5回失敗でアカウント一時ロック
  • メール+IPアドレスの組み合わせでカウント
  • 時間経過で自動解除
  • Lockoutイベントの発火

結果

  • 追加実装不要。実装済みを確認。
1-4. セキュリティヘッダーの実装(フェーズ2)

app/Http/Middleware/SecurityHeadersMiddleware.phpを新規作成し、bootstrap/app.php` に登録。

設定したヘッダー:

ヘッダー設定値効果
Strict-Transport-Securitymax-age=31536000HTTPS強制をブラウザに記憶
X-Frame-OptionsDENYクリックジャッキング防止
X-Content-Type-OptionsnosniffMIMEタイプ誤判定防止
Referrer-Policystrict-origin-when-cross-originURL漏洩防止
Content-Security-Policyself + unsafe-inlineXSS対策

注意事項

  • ローカル環境(APP_ENV=local)では全ヘッダーをスキップする条件を追加。
  • TipTapエディタ・Axios使用のため、CSPは段階的に厳格化する方針とした。
1-4. セキュリティヘッダーの実装(フェーズ2)

app/Http/Middleware/SecurityHeadersMiddleware.hpを新規作成し、bootstrap/app.php` に登録。

設定したヘッダー:

ヘッダー設定値効果
Strict-Transport-Securitymax-age=31536000HTTPS強制をブラウザに記憶
X-Frame-OptionsDENYクリックジャッキング防止
X-Content-Type-OptionsnosniffMIMEタイプ誤判定防止
Referrer-Policystrict-origin-when-cross-originURL漏洩防止
Content-Security-Policyself + unsafe-inlineXSS対策

注意事項

  • ローカル環境(APP_ENV=local)では全ヘッダーをスキップする条件を追加。
  • TipTapエディタ・Axios使用のため、CSPは段階的に厳格化する方針とした。
1-5. 不審ログイン通知メール(フェーズ2)

新しいIPアドレスからのログインを検知し、登録メールアドレスへ通知メールを自動送信する機能を実装。
新規作成ファイル
app/Mail/SuspiciousLoginMail.php
resources/views/emails/suspicious_login.blade.php
resources/views/emails/suspicious_login_text.blade.php(HTML/テキスト両形式対応)

    修正ファイル
    app/Http/Controllers/Auth/AuthenticatedSessionController.php

      検知ロジック:

      $isNewIp = !LoginLog::where(‘user_id’, $user->id) ->where(‘ip_address’, $request->ip()) ->where(‘id’, ‘!=’, $log->id) ->exists(); if ($isNewIp && $user->email) { Mail::to($user->email)->send( new SuspiciousLoginMail($user, $request->ip(), now()->format(‘Y年m月d日 H:i’)) ); }

      メール設定

      環境設定
      本番Xサーバ SMTPサーバ(sv13426.xserver.jp:587)
      ローカルMAIL_MAILER=log(ログファイルに出力)

      動作確認結果

      • Gmail:受信トレイに正常届を確認 ✅
      • MSN(Outlook):迷惑メールフォルダに届くことを確認 ✅

      残課題

      MSN/Outlookの迷惑メール判定を解消するため、DNSへのSPFレコード追加を推奨。
      レコード種別:TXT
      値:v=spf1 include:xserver.jp ~all

      2.フェーズ別進捗

      フェーズ1(必須・リリース前)
      項目状態
      パスワードのハッシュ化(bcrypt)✅ 完了(実装済み確認)
      HTTPS強制✅ 完了
      セッションのセキュア設定✅ 完了
      ログイン失敗のロック機構✅ 完了(実装済み確認)
      フェーズ2(リリース後早めに)
      項目状態
      セキュリティヘッダー(HSTS等)✅ 完了
      不審ログイン通知メール✅ 完了
      SPF・DKIMの設定⬜ 未対応(推奨)
      パスワードリセットフローの強化⬜ 未対応(次回

      MACmini4にLaravelローカル環境構築

      元宇品の森に散歩
      MACmini4に建設アシストLaravelのローカルな環境を構築する・・・なれないMACで一日かかった
      マザーを交換することにする このマザーは6年前に購入したASUS ROG STRIX B550-F GAMING(ちょっと高級品)でAMD Ryzen 5000シリーズ AM4 対応だが、最近はメモリが高騰して数倍になっているので、高いDDR5を避けてDDR4のAM4が人気があり、まだ現役バリバリだった
      マザーは同じくB550だが、LANが2.5G対応のASUS ROG STRIX B550-A GAMING を手配する

      パソコンのエラー

      朝は京橋川の土手をキクと散歩
      ケースからマザーを取り出して、清掃して裸にして色々と試す
      とりあえず、MACmini4を使えるようにして、Laravelのシステムの再構築を行う
      メモリも交換、電源の交換、BIOS更新、USBの清掃・・・すべてやってみたが、USB device over current status detected(USB過電流検出)のエラーメッセージは消えない

      建設アシストセキュリティ監査

      1. セキュリティ監査の実施

      iso_app (建設アシスト)のセキュリティ強化を実施する

      1.1 監査方法

      Claude Code(Opus 4.7)を「セキュリティ監査員」として起用し、以下の観点でアプリケーション全体を調査しました。

      • 認証・認可の漏れ(全コントローラーを網羅的に調査)
      • テナント分離の実装状況(マルチカンパニー対応の確認)
      • ファイルアクセス制御
      • AI API への機密情報送信リスク
      • 入力検証・出力エスケープ
      • 依存ライブラリの脆弱性
      1.2 監査サマリー
      重大度 件数対応状況
      Critical6件 4件完了・2件対応中
      High8件7件完了・1件対応中
      Medium2件計画中
      合計16件 11件完了

      3. High 項目の詳細

      項目コントローラー内容状態
      認可漏れChecklistControllergetEvidence で他社データをJSON取得可能✅ 完了
      認可漏れEnvironmentControllerindex/edit/save/aiEstimate でテナント確認なし✅ 完了
      認可漏れRiskAssessmentControllerdownloadAttachment で他社ファイルダウンロード可能(16メソッド)✅ 完了
      AI情報AuditAiService被監査対象名・業務概要がAPI送信される⚠ 対応中
      AI情報SafetyPatrolController作業内容・使用機械の詳細が送信される⚠ 対応中
      AI情報risk_assessment.blade.php下請業者名・プロジェクト名がプロンプトに含まれる⚠ 対応中

      4. 是正処置の内容

      4.1 共通トレイトの新規作成

      認可ロジックを一元化する AuthorizesTenantAccess トレイトを作成しました。

      app/Http/Controllers/Concerns/AuthorizesTenantAccess.php

      このトレイトにより:

      • 認可ロジックが1箇所で管理される
      • 各コントローラーへの適用が use 一行で済む
      • 将来の Policy 移行への布石となる
      • 役割ベースの例外(システム管理者は全社アクセス可)を正しく処理
      4.2 適用したコントローラーと保護されたメソッド数
      コントローラー保護メソッド数対応回
      ProjectController8メソッド第1回
      ConstructionPlanController15メソッド第1回
      SafetyPatrolController14メソッド第1回
      ChecklistController6メソッド第1回
      EnvironmentController4メソッド第2回
      RiskAssessmentController16メソッド第2回
      合計63メソッドー
      4.3 テストケース(26件 全PASS)

      各コントローラーに対して以下のパターンを網羅的にテスト:

      • 他社ユーザーが各リソースにアクセス → 403
      • 自社ユーザーがアクセス → 200(正常)
      • role=1 システム管理者 → 全社アクセス可(200)
      • 削除・変更系でDBの状態が変わらないことを確認
      4.4 実施コストと効果
      項目内容
      実施時間(合計)約2時間半
      API利用コスト$6.51(約1030円)
      外注した場合の市場価格130〜350万円相当
      コスト比約1300〜3500倍の費用対効果
      コード変更量673行追加、12行削除
      テスト件数26件 全PASS

      2. Critical 項目の詳細

      2.1 テナント分離の欠落(Critical 1〜4) ✅ 完了

      最も重大な問題でした。URL のIDを変えるだけで他社のデータに読み取り・編集・削除アクセスが可能な状態でした

      対象コントローラー影響範囲重大度
      ProjectControllershow/edit/update/destroy/editOverview/updateOverview/uploadPhoto(8メソッド)Critical
      ConstructionPlanControllerdownloadDocx/downloadXlsx/generatePdf/diagramEditor等(15メソッド)Critical
      SafetyPatrolControllercreate/store/index/show/destroy/generateAiChecklist等(14メソッド)Critical
      ChecklistControllerdeleteEvidence/getEvidence等(6メソッド)Critical
      2.2 AI API への機密情報送信(Critical 5〜6) ⚠ 対応中

      発注者名・予算・下請業者名・近隣企業名などが、マスキングなしで Anthropic Claude API に送信される可能性がありました。

      【現状の評価(設計意図の確認後)】
      現状のAI利用は「チェックボックス選択による固定語彙のみを送信」という設計になっており、実質的な機密情報漏洩リスクは低い状態です。ただし、将来の機能拡張で誰かがフリーテキストを送る実装をしてしまうリスクの予防として、コードレベルのガード機構を実装予定です。

      5. 進捗状況

      フェーズ内容状態
      Phase Aリスクアセスメント(自主監査)✅ 完了
      Phase B-1Critical 1〜4 テナント分離✅ 完了
      Phase B-2High 7〜9 認可漏れ(Environment, RiskAssessment)✅ 完了
      Phase B-3Critical 5〜6, High 10〜12 AI関連⏳ 次フェーズ
      Phase B-4Medium 13 ファイル名処理⏳ 後ほど
      Phase CAIゲートウェイ構築・匿名化📅 来月
      Phase D監視・運用体制の確立📅 数ヶ月後
      Phase E継続的改善(PDCA)継続

      6. 次フェーズの計画

      6.1 AI送信情報のガード機構(InputValidator)

      現在の「固定語彙のみ送信」という設計意図をコードで強制するバリデータークラスを実装します。

      • 会社名・個人名らしき文字列の検出
      • 長い数字列(電話番号・契約番号等)の検出
      • 検出時の警告ログ記録
      • 既存のAI Serviceへの組み込み(5箇所)
      6.2 将来計画:ローカル AI 前処理

      契約事項・技術的背景・経営内容の文書化を扱う際、自前サーバーに置いたローカルAIで一般化処理をしてから外部AIに送信する仕組みを構築予定です。

      • ルールベース匿名化サービス(Phase 1): 氏名・会社名・金額の自動マスキング
      • ローカルLLM検証(Phase 2): Ollama + Llama 3.2 などで自前AIの感触をつかむ
      • 統合AIゲートウェイ(Phase 3): 匿名化→外部AI→復元のパイプライン構築

      Claude Code 最適化

      1. プロジェクト容量の実測結果

      Claude Codeのトークン消費がものすごい・・・いくら請求が来るやら(トークン量は1億となっていた!!)、これは大変なのでトークン削減・コスト最適化の実践を考える
      iso_app プロジェクトの容量分析結果(2026年5月実測):

      フォルダサイズ(MB)分類除外対象
      node_modules/103.25npmライブラリ
      ✅ 除外必須
      vendor/73.14Composerライブラリ✅ 除外必須
      storage/app/59.91写真・添付ファイル✅ 除外必須
      storage/logs/4.33ログファイル✅ 除外必須
      storage/fonts/5.87IPAexフォント✅ 除外必須
      storage/framework/0.27Laravelキャッシュ✅ 除外必須
      public/18.39ビルド成果物・画像⚠ 一部除外
      resources/1.32ビュー・CSS・JS❌ 必要(含める)
      database/0.86マイグレーション❌ 必要(含める)
      app/0.38実コード❌ 必要(含める)

      ⚠ 実コード(app/, resources/, database/, routes/, config/)の合計はわずか 2.7MB。全体の 1% です。

      2. .claudeignore の設定

      .claudeignore ファイルをプロジェクトルートに作成することで、Claude Code が読み込む対象を 268MB から 2.7MB に削減できます。

      依存ライブラリ(最重要)
      vendor/
      node_modules/
      アップロードされた写真・添付ファイル(iso_app固有)
      storage/app/public/photos/
      storage/app/public/evidence/
      storage/app/public/plans/
      storage/app/public/ra_attachments/
      Laravelキャッシュ・ログ
      storage/logs/
      storage/framework/
      storage/fonts/
      ビルド成果物
      public/build/
      public/storage/
      手書きCSSは含める
      !public/css/print-common.css
      Git・IDE
      .git/
      .idea/
      .vscode/
      バイナリ・大容量ファイル
      *.zip *.tar.gz *.pdf *.xlsx *.sql *.sqlite

      ▶この続きを見る・・・・

      Laravel 基礎知識

      1. Laravel とは

      Laravel は PHP で書かれたオープンソースの Web アプリケーションフレームワークです。2011 年に Taylor Otwell によって作られ、現在では PHP フレームワークの中で最も人気のあるものの一つとなっています。MVC(Model-View-Controller)アーキテクチャを採用しており、ビジネスロジック・データ・表示を分離して開発できます。

      1.1 主要な機能
      機能説明
      Eloquent ORMデータベース操作をオブジェクト指向で直感的に扱える。SQLをほとんど書かずにDB操作が可能
      Blade テンプレートシンプルかつ強力なテンプレート構文。HTMLとPHPを綺麗に分離
      Artisanコマンドラインツール。コードの自動生成・マイグレーション・キャッシュクリアを効率化
      ルーティングRoute::get(‘/users’, …) のような直感的な記述でURLとコントローラーを結びつける
      認証(Auth)ログイン・登録・パスワードリセットなどの認証機能を標準装備
      マイグレーションデータベース構造のバージョン管理
      キューと スケジューラ非同期処理・タスクの定期実行

      2.Composer による依存管理

      2.1 Composer とは

      Composer は PHP の依存管理ツールです。JavaScript の npm、Python の pip に相当します。Laravel 自体も Composer を使ってインストール・管理されます。「アプリの部品調達係」と考えると理解しやすいです

      2.2 Composer の3つの役割
      • 買い物リストの管理: composer.json = 「このアプリに必要な部品リスト」
      • 部品の調達と配置: Packagist からライブラリを取得して vendor/ に配置
      • 部品同士の互換性チェック: バージョン矛盾がないか自動確認

      2.3 ライブラリの所在
      場所役割
      Packagist (packagist.org)PHPライブラリのカタログ(Amazonのサイトに相当)
      GitHub実際のソースコードの置き場所(Amazonの倉庫に相当)
      vendor/ フォルダあなたのPCに取ってきた完成品(自宅に届いた荷物)
      ローカルキャッシュ一度落としたものの控え(物置に置いてある予備)
      2.4 よく使うコマンド

      composer install               # composer.lock通りにインストール
      composer update                # 制約内で更新
      composer require guzzlehttp/guzzle  # 新規パッケージ追加
      composer remove vendor/package      # パッケージ削除
      composer dump-autoload         # オートローダーの再生成

      ▶この続きを見る・・・・

      日曜日も天気が良い

      元宇品の森の中
      元宇品のプリンスホテル側を散歩
      Codexをインストールする

      建設アシストのコードが多くなってきたので、Claude Codeのトークン消費が多くなってくる(毎回、コードを読み込んで応答するため)・・・2日ごとにクレジット要求が来るようになったので、今噂のchatJPのClaude Code向けのプラグインであるCodexをインストールをして、さっそく工事管理のフロントエンドを修正させたが、ずいぶん時間がかかり、おまけにClaude codeも消費しているようで、またクレジットが切れてしまった・・・いくら請求が来るのか戦々恐々・・・Codexが使えるようであればFreeから契約するかと思っていたが、もう少し様子をみる必要がある・・・・Claude Codeを使わなくても、Clude,Geminiなどでもコード作成はできるが、スピードとシステム全体の網羅性はClaude Codeを使いだすと数倍以上に効率が良いため、中々戻れない

      ▶この続きを見る・・・・

      内部監査システムを構築

      昨日に引き続き内部監査のシステムを構築する・・・ようやく、難しい監査チェックシートを作成、かなりClaudeを使い倒していると、昨日に引き続きもう追加のクレジットの要求・・・かなりの金食い虫だが、仕事は素晴らしいので対価としては多少納得
      内部監査システムはかなり完成に近い、明日で細かな詳細を仕上げるかな

      朝の散歩では、宇品波止場にはクルーズ船が停泊
      内部監査の個別監査計画書
      内部監査リスト
      監査チェックシート ISOシステムはタブメニューで
      監査チェックシートはCSVで雛形を取り込み

      内部監査の複雑な仕組みのアプリうケーションが作成できれば、どのような業務アプリも作成できる自信がついた

      監査指摘シート
      監査での不適合 是正処置報告書