--- title: ロール可否の構造化宣言と番人テストの追加(route_roles) updated: 2026-08-04 --- # 2026-08-04 ロール可否の番人を追加 「誰が使えるか」の記述が、これまで**本文の散文にしかありませんでした**。プラン可否(`available:`)は 番人テストで守られている一方、**ロール条件は機械検査がゼロ**で、実装を変えてもドキュメントは黙って古くなる状態でした。 AIサポートの誤答は「条件を取り違える」で起きます。MCPの運用ルールが 「端末・ロール・プラン・立場で答えが変わる質問は先に1つ聞け」と指示しているのは、 そこが主要因だと分かっているからです。にもかかわらず、肝心の条件が守られていませんでした。 ## 何を変えたか - Front Matter に **`route_roles:`** を新設。ルート名ごとに4ロールの可否を宣言できるようにした。 - 番人テスト **`tests/Feature/AiDocsRoleGuardTest.php`** を追加。 - 3本のドキュメントに宣言を付与(計6ルート × 4ロール=24通りを固定)。 - `faq/sales-analytics.md` … `analytics.index` / `sales-report.index` / `personal-report.index` / `sales-goals.index` - `manual/pc-dashboard.md` … `dashboard` - `manual/pc-approval.md` … `approvals.index` ### 書き方 ```yaml route_roles: analytics.index: admin: true approver: false staff: false field_only: false ``` 1つのドキュメントが複数画面を説明する場合は、**ルートごとに**書けます。 売上分析は画面によってロール条件が違う(ファネルは管理者のみ、売上履歴は担当者も可)ため、この形が必要でした。 ## なぜ「実際にアクセスして」判定するのか **ルート定義の middleware を読むだけでは不十分**だと実測で分かりました。 たとえば売上分析の「管理者のみ」は、ルートの middleware ではなく `AnalyticsController` 内の `abort_unless($user->isAdmin(), 403)` に書かれています。 静的にルートを読む方式では**これを取りこぼし、宣言と実装が食い違っても通ってしまう**=番人になりません。 そこで `AiDocsDriftGuardTest` が `Entitlement` を実際に呼ぶのと同じく、本テストは **各ロールで実際に GET して振る舞いで判定**します。middleware でもコントローラの abort でも、 どちらの実装でも捕まります。 ## 壊れることを確認済み(両方向) | わざと壊したもの | 結果 | |---|---| | ドキュメントの宣言(`approver: false` → `true`) | ✅ 赤(HTTP 403 なのに true と宣言、と指摘) | | **コード側**(`isAdmin()` → `canApprove()` に緩めた) | ✅ 赤(HTTP 200 なのに false と宣言、と指摘) | 2つ目が本来の目的です。**ロールゲートを緩めた/締めたときに、ドキュメントの直し忘れが機械で止まります。** ## 制約(v1 の割り切り) - 対象は **引数なしの GET ルート**のみ。POST や `{param}` 付きは対象外。 - 宣言できるルートは **ホワイトリスト方式**(`AiDocsRoleGuardTest::ALLOWED_ROUTES`)。 Front Matter から任意のルートを叩かせないための歯止め。対象を増やすときはここに足す。 - プラン差は `available:` / `entitlement:` の担当。本テストは **SOLO 会社に固定**してロールだけを見る (プランとロールの2軸が混ざると、落ちた理由が読めなくなるため)。 - `system_admin` は運営(当社)用のため、利用者向けドキュメントでは宣言しない。 - **端末(スマホ/PC)はまだ対象外。** 実装上「スマホでは使えない」の定義がどこにも無く、 突き合わせる先が存在しないため。`screen:` の端末プレフィックスは `AiDocsIntegrityTest` が照合前に捨てており、現在も未検証のまま(別途対応)。 ## AI影響 - [x] **プランのゲート(`App\Services\Entitlement`)を変えた?** → いいえ。 - [x] **画面名・操作手順が変わった?** → いいえ。 - [x] **画面のURLを変えた?** → いいえ。 - [x] **新しいエラー文言が出るようになった?** → いいえ。 - [x] **文言は出ないが挙動が変わる現象が増えた?** → いいえ。 - [x] **用語が増減した?** → いいえ。 **以後、ロールゲートを変えた場合は番人テスト `AiDocsRoleGuardTest` が落ちます。** そのときは該当ドキュメントの**本文**と `route_roles:`、そしてリリースノート(新しい1本)を**同時に**直してください。