コンテンツにスキップ

Design

Context

現在、管理者モード(AdminPage)は以下の仕組みで認証を行っている:

  • useAuth?token=xxxのURLクエリパラメーターからSASトークンを取得
  • 取得後、トークンをメモリに保持し、URLから削除(history.replaceState
  • BlobWriterがこのトークンを使用してAzure Blob Storageに書き込み

この仕組みにより、開発環境では有効なSASトークンがないと管理者モードの機能(CSV一括保存、グループ名編集)をテストできない。E2Eテスト(Playwright)でも管理者モードのシナリオをカバーできない。

開発者は、機能開発時に毎回Azure Portal/CLIから一時的なSASトークンを発行する必要があり、開発効率が低下している。

Goals / Non-Goals

Goals:

  • 開発環境(pnpm run dev)で管理者モードをテストできるようにする
  • E2Eテスト(Playwright)で管理者モードのシナリオをテストできるようにする
  • 本番環境のセキュリティを維持する(ダミートークンは開発環境でのみ有効)
  • 既存のコードへの影響を最小限に抑える

Non-Goals:

  • 本番環境での認証メカニズムの変更
  • SASトークン生成の自動化
  • 開発環境でのアクセス制御(誰でも?token=devで管理者モードに入れることを許容)

Decisions

1. ダミートークンとしてdevを使用

決定: ?token=devを開発環境で有効な管理者トークンとして認識する

理由:

  • シンプルで覚えやすい(開発者がすぐに使える)
  • 本番環境では無効(後述の環境チェックと組み合わせる)
  • 既存のトークン取得フローを再利用できる

代替案:

  • UUID形式のダミートークン: より現実に近いが、開発者が覚えにくい
  • 環境変数での設定: 柔軟だが設定手順が増える

2. BlobWriterのモック化方法

決定: オプション2を採用 — ローカルのdev-fixtures/data/に書き込む

理由:

  • より実践的なテスト(実際にファイルが作成され、DataFetcherで読み込める)
  • データの永続化により、開発中の状態を保持できる
  • 書き込み処理の実装ロジック(JSON生成、パス処理など)をテストできる

代替案 (オプション1: スキップして成功を返す):

  • メリット: 実装が簡単、ファイルシステムに影響しない
  • デメリット: 実際の書き込み処理がテストされない、データが永続化されない

実装詳細:

  • BlobWriter.jswriteToDevFixtures(path, data)関数を追加
  • import.meta.env.DEV === trueかつトークンが"dev"の場合、この関数を使用
  • dev-fixtures/data/配下に同じディレクトリ構造で書き込む
  • Node.jsのfs.promisesを使用(Viteはビルド時にポリフィルを提供)

3. 開発環境の検出

決定: import.meta.env.DEVを使用して開発環境を判定

理由:

  • Viteの標準機能(追加の設定不要)
  • ビルド時に静的に評価され、本番ビルドでは開発用コードが除去される(Tree-shaking)
  • 既存のコードベースですでに使用されている(一貫性)

代替案:

  • process.env.NODE_ENV === 'development': Viteではimport.meta.envが推奨
  • カスタム環境変数: 設定手順が増える

4. セキュリティ対策

決定: ダミートークンの有効性を開発環境に限定する

実装:

  1. useAuth.jsx: token === "dev" && import.meta.env.DEVの場合のみisAdmin: trueを返す
  2. BlobWriter.js: 本番ビルドでは通常のAzure Blob Storage APIのみを使用(モックコードは含まれない)

理由:

  • 本番環境で?token=devが使用されても管理者権限を付与しない
  • ビルド時の最適化により、本番ビルドにモックコードが含まれない

Risks / Trade-offs

[リスク] 本番環境でのセキュリティ漏洩

  • リスク: 開発用コードが誤って本番環境に含まれる可能性
  • 軽減策:
  • import.meta.env.DEVチェックにより、本番ビルドではダミートークンを無効化
  • ビルド時のTree-shakingにより、開発用コードが除去される
  • E2Eテストで本番ビルドが?token=devを拒否することを確認

[トレードオフ] モック動作と実際の動作の差異

  • トレードオフ: ローカルファイルシステムへの書き込みは、Azure Blob Storage APIとは異なる挙動をする可能性がある
  • 影響:
  • ネットワークエラー、レート制限、認証エラーなどのテストはされない
  • ファイルシステムの権限エラー発生の可能性がある
  • 軽減策:
  • 重要な機能は実際のAzure環境(devブランチのCI/CD)でもテストする
  • モック動作時、コンソールで警告を表示(開発者への注意喚起)

[リスク] dev-fixturesディレクトリの肥大化

  • リスク: 開発中、dev-fixtures/data/へ大量のテストデータが蓄積される
  • 軽減策:
  • .gitignoredev-fixtures/data/を除外済み(既存の設定)
  • 開発者による手動クリーンアップが可能(rm -rf dev-fixtures/data/*
  • READMEへ「開発用データのクリーンアップ方法」を記載

[トレードオフ] Node.js API(fs)の使用

  • トレードオフ: ブラウザでfsを使用するためにはViteのポリフィル、またはNode.js互換ライブラリが必要
  • 影響: 現在のVite設定ではfsを利用できない可能性がある
  • 代替案:
  • Viteプラグインでfsをポリフィル(設定変更が必要)
  • BlobWriter内部でfetch APIを使用し/dev-fixtures-writeエンドポイントへ書き込む。Viteプラグインでハンドリング(より複雑だが、ブラウザ環境との整合性が高い)
  • 推奨: 代替案2を採用(既存のserveDevFixturesプラグインを拡張)

Migration Plan

デプロイ手順:

  1. コード変更をmainブランチにマージ
  2. 既存の機能に影響がないことを確認(利用者モード、本番環境での管理者モード)
  3. 開発者に新機能をアナウンス(?token=devの使い方)

ロールバック戦略:

  • 本番環境の動作に変更がないため、ロールバックの必要性は低い
  • 問題が発生した場合は、該当のコミットをrevertして再デプロイ

移行の影響:

  • 既存の開発者は引き続き実際のSASトークンを使用可能
  • 新機能の使用は任意(既存のワークフローを妨げない)

Open Questions

  1. Viteプラグインでの書き込み処理の実装方法
  2. serveDevFixturesプラグインを拡張してPOST/PUTリクエストをハンドリングする方法の詳細
  3. エラーハンドリング(ディスク容量不足、権限エラーなど)

  4. E2Eテストでのダミートークンの使用

  5. Playwrightテストで?token=devを使用する際の注意点
  6. テスト実行前にdev-fixtures/data/をクリーンアップするべきか

  7. 開発用データの初期化

  8. 新規開発者がdev-fixtures/data/に初期データを持っていない場合の対処
  9. サンプルデータのセットアップスクリプトが必要か