bento_order_web コード構成解説

弁当注文PWA — 職場向けスマホ注文 + 管理者集計システム

Vite + React 19 Firebase GAS連携 PWA

最終更新: 2026-03-18

1. 全体アーキテクチャ(レイヤー構成)

ユーザー(ブラウザ / スマホ PWA) 従業員|注文・履歴 管理者|集計・メニュー管理 ルートガード(App.tsx) PublicRoute 未ログイン専用 /login /register PrivateRoute ログイン必須 / /order /history AdminRoute isAdmin = true 必須 /admin ページ層(src/pages/) 従業員ページ HomePage / OrderPage HistoryPage 管理者ページ AdminDashboard (5タブ統合画面) サービス層(src/services/) auth.ts 認証操作 firestore.ts 全データ操作 spreadsheet.ts GAS 連携 auditLog.ts 監査ログ emailService.ts Cloudflare Workers Firebase(バックエンド) Firebase Auth メール/PW + 不正防止チェック Firestore セキュリティルール 誰が何をできるかを DB 側で強制 GAS(外部連携) Google Apps Script シート同期 / Gmail送信

ユーザーリクエストは上から下へ流れる。ルートガードが認証を検証し、サービス層を経由して Firebase / GAS にアクセスする。

2. 注文フロー(OrderPage.tsx)

👤 従業員 1 受付中メニュー一覧を表示 getActiveSchedules() / getMenuItems() / getUserOrders() を並列取得 2 メニュー選択(複数チェック可) ☑ 日替わりA弁当 ☑ カレーセット ☐ サラダセット(注文済み) 3 配送日選択(2段階) ステップ1: 1日目希望 / 2日目希望 → day1 / day2 / day1_flexible / day2_flexible / both 4 注文確定 重複チェック + 締切チェック → addOrder() → GAS 確認メール送信 注文ステータス: 受付中 配送済み キャンセル

3. 認証フロー(招待制登録)

① 管理者が招待メール送信 invited_users に登録 ② 従業員が登録リンクから checkInvitedUser() 実行 招待 確認OK? はい いいえ 登録拒否 エラー表示 ③ Firebase Auth 登録 Firestore users 作成(isAdmin: false 固定) ④ AuthContext にセット 30分無操作で自動ログアウト ルートガードが権限を判定 isAdmin = Firestore users/{uid}.isAdmin

4. Firestore コレクション構成

Firestore セキュリティルール適用 users/ ユーザープロフィール 読: 本人or管理者 書: 本人(isAdmin変更不可) or 管理者 orders/ 注文データ(userName 保存なし) 読: 本人or管理者 書: 本人(作成) / 本人or管理者(更新) menu_items/ メニューマスタ 読: 認証済み全員 書: 管理者のみ deliverySchedules/ 配送スケジュール 読: 認証済み全員 書: 管理者のみ settings/ アプリ設定(GAS URL 等) 読: 管理者のみ 書: 管理者のみ invited_users/ 招待メール控え 読: 認証済み(get)/管理者(list) 書: 管理者のみ audit_logs/ 操作監査ログ 読: 管理者のみ 書: 認証済み(create のみ — 改ざん不可) 読み取り権限 書き込み権限

5. 管理者ダッシュボード(5タブ構成)

注文 メニュー スケジュール ユーザー 設定 注文 全注文リアルタイム 一覧表示 ステータス変更 一括削除 シート同期 メニュー メニューマスタ 追加・編集・削除 スケジュール 配送日程の管理 受付期間設定 ユーザー 全ユーザー一覧 管理者権限付与/剥奪 招待メール送信 設定 GAS WebアプリURL スプレッドシートURL 自動トリガー設定

6. メール送信の二重構成

bento_order_web 注文確定 / 管理者操作 経路① GAS経由(Gmail) spreadsheet.ts 注文確認メール 受付開始通知 締切リマインダー 配送前日通知・招待メール GAS 自動トリガーで定時送信 経路② Cloudflare Workers emailService.ts + Resend API 本番メインの送信経路 本番環境で優先使用 Gmail 経由送信 Resend 経由送信

GAS経由(Gmail)は定時トリガーによるリマインダー送信が主用途。Cloudflare Workers経由は本番環境のメインメール送信経路。

7. 状態管理(シンプル構成)

グローバル状態

AuthContext
user / firebaseUser / loading
login() / logout() / register()

ページ固有状態

useState + useEffect
各ページのローカルデータ管理。グローバルストアなし(シンプル設計)。

リアルタイム更新

Firestore onSnapshot
注文・メニュー・スケジュールの変更を即時反映。設定は localStorage + Firestore settings/app で管理者間共有。