予約カレンダー表示
予約カレンダー表示
Section titled “予約カレンダー表示”Document ID: SRS-RES-001 Parent: SRS-ROOT-001 v0.5 Version: 0.2 Status: Draft Last Updated: 2026-05-05 Depends on: SRS-MST-001 v0.6, SRS-MST-005 v0.2, SRS-CUS-004 v0.1, SRS-RES-002 v0.5, SRS-RES-004 v0.3, SRS-RES-005 v0.4 依存される: SRS-RES-002, SRS-RES-003
本書は SRS-ROOT-001 v0.5 に従う。
管理画面で 1 日単位の予約カレンダーを表示する。Phase 1 は日次のみ、縦軸 staff × 横軸 time、未指名列は左端固定。リアルタイム同期は SSE ではなく 30 秒 polling(親 §8 で SSE は Phase 2 採用)。
2. ユーザーストーリー
Section titled “2. ユーザーストーリー”- As a 受付, I want to 1 日の予約を staff 別に一覧したい, so that 受付の全体把握ができる
- As a 店長, I want to 未指名予約を左端で見たい, so that 当日割当を漏らさない
- As a スタッフ, I want to 予約詳細へすぐ飛びたい, so that 当日運用が速い
- As a スタッフ, I want to オプションで「自分担当のみ」フィルタを使いたい, so that 朝確認が速い
3. ユースケース
Section titled “3. ユースケース”3.1 主シナリオ
Section titled “3.1 主シナリオ”TanStack Routerのsearch.date=YYYY-MM-DDで画面を開くGET /api/admin/staffで active staff 一覧を取得GET /api/admin/reservations?date=YYYY-MM-DDで当日予約 snapshot を取得- クライアントが先頭に「未指名」列を合成
- 30 秒ごとに
since=<last_server_time>付きで再取得 - 変更がなければ 304、変更ありなら当日 snapshot を再描画
3.2 代替フロー
Section titled “3.2 代替フロー”- AF-1 印刷:
@media printで簡易印刷レイアウト - AF-2 詳細表示: 予約クリックで detail panel へ遷移
- AF-3 staff 0 名: 未指名列だけ表示
- AF-4 「自分担当のみ」フィルタ:
operator_staff_linkの active link が存在する operator のみ UI 上にフィルタを表示。サーバ側でもstaff_id自動絞り込み(Phase 1 はクライアント側絞り込みでも可)
3.3 例外フロー
Section titled “3.3 例外フロー”- EF-1
date不正: 400RESERVATION.CALENDAR_DATE_INVALID - EF-2 権限不足: 403
- EF-3 304: body なし、既存 snapshot を維持
- EF-4 日付跨ぎ予約:
starts_atの営業日で所属日を決める
4. UI仕様
Section titled “4. UI仕様”4.1 主要要素
Section titled “4.1 主要要素”- 日付ナビゲーション
- staff columns(
staff.display_order ASC) - 未指名固定列(左端)
- 時間グリッド(
store_settings.reservation_slot_minutes単位) - 予約ブロック
- detail side panel
- print button
- 「自分担当のみ」トグル(
operator_staff_linkあり時のみ表示)
4.2 バリデーション
Section titled “4.2 バリデーション”search.dateはYYYY-MM-DD- 未来・過去とも表示可
- Phase 1 で週表示 / 月表示は出さない
5. API仕様
Section titled “5. API仕様”5.1 エンドポイント一覧
Section titled “5.1 エンドポイント一覧”| Method | Path | 用途 | permission |
|---|---|---|---|
| GET | /api/admin/reservations?date=&since=&staff_id= | 日次カレンダー snapshot | admin:reservation:read |
| GET | /api/admin/reservations/{id} | detail panel | admin:reservation:read |
5.2 zodスキーマ
Section titled “5.2 zodスキーマ”query:
date: YYYY-MM-DDrequiredsince?: ISO8601staff_id?: uuid(self-scope filter)
200 response:
data.datedata.timezone = 'Asia/Tokyo'data.server_timedata.reservations[].iddata.reservations[].code(RES-002 v0.5 で追加された人間可読コード)data.reservations[].staff_iddata.reservations[].statusdata.reservations[].starts_at,ends_atdata.reservations[].customer_namedata.reservations[].menu_summary(最初の menu のname_snapshot)data.reservations[].version
304 response: body なし
5.3 エラーコード
Section titled “5.3 エラーコード”RESERVATION.CALENDAR_DATE_INVALIDRESERVATION.FORBIDDEN
6. データモデル影響
Section titled “6. データモデル影響”- スキーマ変更なし(既存
reservationsaggregate を流用) - 一覧 query は
from/to/cursor中心からdate/since中心へ拡張 0019_reservation_phase1_finalize.sqlで必要なら index 調整(既存reservation_store_starts_idxでカバー)
7. 業務ルール
Section titled “7. 業務ルール”7.1 列順
Section titled “7.1 列順”未指名→staff.display_order ASCstaff_id IS NULLは未指名列
7.2 polling
Section titled “7.2 polling”- 30 秒固定
sinceは delta ではなく “conditional full snapshot” 用- 変更ありなら full snapshot 返却、なければ 304
7.3 since 判定対象
Section titled “7.3 since 判定対象”- reservations の
updated_atのみ - staff layout 変更は別 API で管理
7.4 表示対象 status
Section titled “7.4 表示対象 status”expiredは既定非表示- その他 status は表示対象(
paid/ cancelled 系も含めて当日表示)
7.5 self-scope(Phase 1)
Section titled “7.5 self-scope(Phase 1)”staff_idquery パラメータでフィルタリング可能operator_staff_linkがある operator は UI で “自分のみ” トグルを表示- サーバ側強制(self-scope の権限境界)は Phase 2 OQ
7.6 監査
Section titled “7.6 監査”- read 系のため通常監査対象外
8. 非機能要件
Section titled “8. 非機能要件”- 初期表示 1 秒以下(親 §6.1)
- 100 reservations/day を SLA
- 1000/day の virtualization は Phase 2
9. セキュリティ・認可
Section titled “9. セキュリティ・認可”admin:reservation:read(全 role)- detail も同じ permission
staff_idfilter による情報絞りはアプリ層判定
10. 受け入れ基準(Given-When-Then)
Section titled “10. 受け入れ基準(Given-When-Then)”- GWT-1:
date=2026-05-05/ 画面表示 / 当日予約が staff 別に表示される - GWT-2:
staff_id=NULLの予約 / 表示 / 未指名列の左端に出る - GWT-3:
since以降変更なし / polling / 304 - GWT-4:
since以降変更あり / polling / full snapshot - GWT-5: operator が staff A に linked / “自分のみ” toggle ON / staff_id=A でフィルタされた予約が返る
- GWT-6:
expired予約 / 既定表示 / 含まれない
11. テスト計画
Section titled “11. テスト計画”- Integration: date query, 304/200 切替, self-scope filter
- E2E (Phase 2): polling, detail panel
12. 関連ジョブ
Section titled “12. 関連ジョブ”- なし
13. Open Questions
Section titled “13. Open Questions”| # | 内容 | 扱い |
|---|---|---|
| OQ-RES-001-01 | cancelled 系の表示色ルール | UI レイヤ |
| OQ-RES-001-02 | 深夜営業日跨ぎの “営業日” 定義 | Phase 1 は starts_at 基準 |
| OQ-RES-001-03 | self-scope のサーバ強制 | Phase 2 |
| OQ-RES-001-04 | SSE への移行タイミング | Phase 2 |
14. 変更履歴
Section titled “14. 変更履歴”| Version | Date | Author | Change |
|---|---|---|---|
| 0.1 | 2026-05-05 | Codex / yudai | 初版 |
| 0.2 | 2026-05-05 | yudai (with Codex co-design) | Round 2 反映: polling 30s 確定、SSE は Phase 2、reservation.code 表示、operator_staff_link 連動の self-scope filter(Phase 1 は UI option のみ) |