Doc 01
要件定義
Requirements Definition
Maruyama Coffee POS System — 表参道店
1. システム概要 System Overview
| 項目 | 内容 |
|---|---|
| システム名 | Maruyama Coffee POS System |
| 目的 | コーヒーショップの注文受付・会計・売上管理を一元化するPOSシステム |
| 利用形態 | ブラウザベースのWebアプリケーション(タブレット・PC対応) |
| フロントエンド | Next.js (App Router) + TypeScript |
| バックエンド | Hono + Cloudflare Workers(D1 / R2) |
| 状態管理 | Jotai (クライアントサイド) |
| スタイリング | Tailwind CSS |
| モノレポ構成 | pnpm workspaces (apps/web, apps/api, packages/shared) |
1.1 システムスコープ
本システムが対象とする業務範囲は以下のとおり。
- 来店受付(テーブルへの着席管理)
- 注文受付(スタッフによるオーダー入力)
- キッチンへの注文伝達・提供状況管理
- テーブル会計(割引・税計算・決済)
- 会計履歴の参照・取消
- 日次締め処理
- 商品・カテゴリのマスタ管理
- スタッフ情報の管理
- 売上分析・ランキングの閲覧
1.2 システム境界
- 在庫管理は本システムのスコープ外とする
- 外部決済端末との連携は本システムのスコープ外とする(支払方法の記録のみ)
- 予約管理は本システムのスコープ外とする
1.3 スコープ外機能 Out of Scope
以下の機能は本システムの対象外であり、将来の拡張フェーズまたは外部サービスとの連携で対応することを想定する。
| 機能 | 説明・補足 |
|---|---|
| オンライン決済(Stripe 等) | クレジットカード・QR コード決済などの電子決済処理。将来的には Stripe Payment Intents API や Square Terminal SDK との連携を想定するが、現フェーズでは会計レコードへの「支払方法」文字列記録のみ。PCI-DSS 準拠要件は本システムの対象外。 |
| 在庫・仕入管理 | 食材・消耗品の在庫数管理、発注、仕入先管理。商品マスタの「在庫あり/なし」フラグ(is_active)は提供するが、数量追跡・自動発注は対象外。 |
| 予約管理 | 来店予約・席予約の受付・リマインダー配信。現システムは当日の着席管理(来店受付)のみを対象とする。 |
| 会計ソフト連携 | freee・弥生会計・MayFair 等へのジャーナルエクスポート。日次締めデータは API で取得可能だが、仕訳生成・連携は対象外。 |
| 顧客管理・ポイント | 顧客 ID 管理、来店履歴、ポイント付与・利用。現システムはビジター(来客セッション)を当日限りで管理するのみで、顧客の継続的な識別は行わない。 |
| ネイティブモバイルアプリ | iOS / Android ネイティブアプリの提供。現システムはレスポンシブ Web アプリとしてタブレット・PC ブラウザに対応するが、App Store / Google Play への配布は対象外。 |
| キッチンディスプレイシステム(KDS)ハードウェア | 専用 KDS 機器への印字・表示連携。キッチン画面はブラウザ上のソフトウェア表示のみ対応し、ハードウェア制御・シリアル通信は対象外。 |
| レシートプリンター連携 | ESC/POS コマンドによる領収書・レシートの印字。現システムは画面上の会計情報表示のみで、プリンターへの直接出力は対象外。 |
| インボイス(適格請求書)発行 | 消費税法上の適格請求書(登録番号記載)の発行・PDF 出力。現フェーズは 10% 一律税率計算のみ対応し、軽減税率区分・インボイス番号管理は対象外。 |
| 多店舗管理 | 複数店舗のデータを横断的に管理するマルチテナント機能。現システムは単一店舗を前提とする。 |
| プッシュ通知・アラート | 注文完了・呼び出しに対するデバイスへのプッシュ通知(Web Push / FCM)。現システムはポーリングまたは手動リフレッシュによる状態確認を前提とする。 |
2. 利用者と役割 Actors & Roles
| 役割 | 説明 | 主な操作 |
|---|---|---|
| 店長 Manager | 全機能へのアクセス権限を持つ | 全ページ・締め処理・スタッフ管理 |
| バリスタ Barista | 注文・会計・キッチン操作 | POS・キッチン・会計・レポート閲覧 |
| ホール Hall | 着席案内・注文・会計 | テーブル管理・POS・会計 |
3. 機能要件 Functional Requirements
3.1 認証
3.1.1 ログイン
| ID | 要件 |
|---|---|
| AUTH-001 | スタッフはメールアドレスとパスワードを入力してログインできる |
| AUTH-002 | ログイン成功後、ダッシュボードへリダイレクトされる |
| AUTH-003 | 未認証状態でアドミン画面にアクセスした場合、ログイン画面へリダイレクトされる |
| AUTH-004 | ログイン中のスタッフ情報(名前・役職)がサイドバーに表示される |
| AUTH-005 | ログアウトボタンを押すと認証状態がリセットされ、ログイン画面に遷移する |
3.1.2 パスワードリセット
| ID | 要件 |
|---|---|
| AUTH-006 | ログイン画面からパスワードを忘れた場合の画面に遷移できる |
| AUTH-007 | パスワードリセット画面ではメールアドレスを入力してリセット申請が行える |
| AUTH-008 | リセット申請後、ログイン画面に戻るリンクが表示される |
3.2 ダッシュボード
3.2.1 サマリー統計
| ID | 要件 |
|---|---|
| DASH-001 | 当日の来店グループ数(在席中のVISITOR数)を表示する |
| DASH-002 | 進行中の注文件数(status = pending / preparing の ORDER 数)を表示する |
| DASH-003 | 当日の売上合計(当日 BILL の total_amount 合計)を表示する |
| DASH-004 | 当日の会計件数(当日 BILL 数)を表示する |
| DASH-005 | 当日の平均客単価(売上合計 ÷ 会計件数)を表示する |
3.2.2 売上チャート
| ID | 要件 |
|---|---|
| DASH-006 | 過去7日間の日別売上推移を折れ線グラフまたは棒グラフで表示する |
| DASH-007 | グラフには日付・売上金額・会計件数が含まれる |
3.2.3〜3.2.6 人気商品・進行注文・スタッフ・クイックアクション
| ID | 要件 |
|---|---|
| DASH-008 | 週間の売上上位5商品を一覧表示する |
| DASH-009 | 各商品に販売数と売上金額を表示する |
| DASH-010 | status が pending / preparing の ORDER を一覧表示する |
| DASH-011 | 各注文にテーブル番号・来店時刻・注文金額を表示する |
| DASH-012 | 「すべて見る」リンクからキッチン画面へ遷移できる |
| DASH-013 | 在籍スタッフの一覧を名前・役職とともにプレビュー表示する(従業員一覧 API は店長権限のため、店長以外のロールでは空表示となる) |
| DASH-014 | 「管理」リンクからスタッフ管理画面へ遷移できる |
| DASH-015 | 「新規注文」ボタンからPOS画面へ遷移できる |
3.3 テーブル・来店管理
| ID | 要件 |
|---|---|
| TABLE-001 | 店内の全テーブル(T1〜T6: 2〜6人席, C1〜C4: カウンター1人席)をビジュアルに表示する |
| TABLE-002 | 各テーブルに席数・テーブルラベルを表示する |
| TABLE-003 | 空席テーブルは「空席」状態として視覚的に区別して表示する |
| TABLE-004 | 着席中テーブルは来客グループの人数・来店時刻・注文ステータスを表示する |
| TABLE-005 | 空席テーブルをクリックすると着席モーダルが表示される |
| TABLE-006 | 着席中テーブルをクリックするとランニングタブモーダル(注文履歴)が表示される |
| TABLE-007 | スタッフは空席テーブルに対して来客人数(1〜最大席数)を選択して着席登録できる |
| TABLE-008 | 着席登録により VISITOR レコードが生成される |
| TABLE-009 | VISITOR には visitor_id(日付+連番)・table_id・visit_date・party 数・created_at が設定される |
| TABLE-010 | テーブルに紐づいた VISITOR の全注文履歴(ORDER・ORDER_ITEM)を表示する |
| TABLE-011 | 注文履歴に商品名・数量・小計・注文ステータスが含まれる |
| TABLE-012 | 「追加注文」ボタンを押すとPOS画面にアクティブ来客が設定されて遷移する |
| TABLE-013 | 「会計へ」ボタンを押すと会計画面にアクティブ来客が設定されて遷移する |
| TABLE-014 | 当日の全 VISITOR を一覧表示する |
| TABLE-015 | 一覧にはテーブルラベル・来客人数・来店時刻・来店順序番号が含まれる |
| TABLE-016 | 各行の「タブを見る」ボタンからランニングタブモーダルを開ける |
| TABLE-017 | 現在使用中のテーブル数 / 総テーブル数をヘッダーに表示する |
3.4 注文入力 (POS)
| ID | 要件 |
|---|---|
| POS-001 | 画面上部にアクティブな来客(VISITOR)を選択するドロップダウンを表示する |
| POS-002 | テーブル管理画面からの遷移時は対象 VISITOR が自動選択される |
| POS-003 | 選択中の来客のテーブル番号・人数・来店時刻を表示する |
| POS-004 | 商品はカテゴリタブで絞り込み表示される |
| POS-005 | カテゴリタブにはカテゴリ名が表示され、選択中タブがハイライトされる |
| POS-006 | 商品名でリアルタイム検索できる検索ボックスを提供する |
| POS-007 | 各商品カードに商品名・価格・カテゴリカラーバッジを表示する |
| POS-008 | 商品カードの「追加」ボタンを押すとカートに追加される |
| POS-009 | カートに既に追加済みの商品は数量バッジで現在の数量を表示する |
| POS-010 | 該当商品がない場合は「該当する商品がありません」と表示する |
| POS-011 | 画面右側に固定表示されるカートパネルにカート内商品を一覧表示する |
| POS-012 | 各カート行に商品名・単価・数量・小計を表示する |
| POS-013 | 数量の増減ボタン(+/-)で数量を変更できる |
| POS-014 | 数量を0にすると商品がカートから削除される |
| POS-015 | 各行の削除ボタンで個別に商品をカートから除去できる |
| POS-016 | カート下部に注文合計金額を表示する |
| POS-017 | 「カートをクリア」ボタンで全カート内容を削除できる |
| POS-018 | 来客が選択されており、かつカートに商品がある場合のみ「注文する」ボタンが有効になる |
| POS-019 | 「注文する」ボタン押下で注文確認モーダルが表示される |
| POS-020 | 確認モーダルにカート内容・合計金額・対象テーブルが表示される |
| POS-021 | 「確定」ボタンで ORDER および ORDER_ITEM レコードが生成される |
| POS-022 | 生成された ORDER は status = "pending" で作成される |
| POS-023 | 注文送信成功後、「注文を送りました」の完了画面が表示される |
| POS-024 | 完了後「閉じる」を押すとカートがクリアされモーダルが閉じる |
| POS-025 | 「店員を呼ぶ」ボタンで呼び出し確認オーバーレイを表示できる |
| POS-026 | 呼び出し確認後、呼び出し済み状態となりボタンが「お呼びしました」に変わる |
| POS-027 | 「お会計」ボタンで会計依頼確認オーバーレイを表示できる |
| POS-028 | 会計依頼確認後、依頼済み状態となりボタンが「依頼済み」に変わる |
| POS-029 | 「注文履歴」ボタンで現在の来客の注文履歴モーダルを表示できる |
3.5 キッチン表示
| ID | 要件 |
|---|---|
| KIT-001 | 全ての ORDER をカード形式でグリッド表示する |
| KIT-002 | 各注文カードにテーブル番号・来客ID・注文時刻・注文アイテム一覧・合計金額を表示する |
| KIT-003 | 各注文アイテムに商品名・数量・小計・アイテムステータスを表示する |
| KIT-004 | 「進行中」タブで status = pending / preparing の ORDER のみ表示する |
| KIT-005 | 「提供済」タブで status = served の ORDER のみ表示する |
| KIT-006 | 「すべて」タブで全ての ORDER を表示する |
| KIT-007 | 注文カードのアイテム単位でステータスを pending / served に変更できる |
| KIT-008 | 全アイテムが served になると ORDER のステータスが自動的に served になる |
| KIT-009 | ORDER のステータスは pending → preparing → served の順に遷移する(逆行・スキップ遷移は不可) |
3.6 会計
| ID | 要件 |
|---|---|
| BILL-001 | ヘッダーのドロップダウンで会計対象の VISITOR を選択できる |
| BILL-002 | テーブル管理画面からの「会計へ」遷移時は対象 VISITOR が自動選択される |
| BILL-003 | 選択中の来客のテーブル番号・来客人数・来客IDを表示する |
| BILL-004 | 選択した VISITOR の served 状態の ORDER に含まれる ORDER_ITEM を商品単位で集計して表示する(精算対象は served オーダーのみ) |
| BILL-005 | 集計テーブルに商品名・単価・税率・数量・小計を表示する |
| BILL-006 | 来客の全 ORDER リストも合わせて表示する(注文番号・注文時刻・金額) |
| BILL-007 | 小計(税抜き合計)を自動計算して表示する |
| BILL-008 | 割引金額を入力できる(0以上の整数、円単位) |
| BILL-009 | 消費税額は(小計 - 割引)× 10% を四捨五入して計算する |
| BILL-010 | 合計金額 = 小計 - 割引 + 消費税額 を自動計算して表示する |
| BILL-011 | 支払方法を「現金」「クレジット」から選択できる |
| BILL-012 | 会計担当スタッフはログイン中のスタッフ(JWT ペイロード)から自動設定される(クライアントからの担当者指定は受け付けない・なりすまし計上防止) |
| BILL-013 | 来客が選択されており served 状態のオーダーがある場合のみ「清算する」ボタンが有効になる |
| BILL-014 | 「清算する」ボタン押下で BILL および BILL_ITEM レコードが生成される |
| BILL-015 | BILL の status は "settled" で生成される |
| BILL-016 | 清算完了後、対象 VISITOR は status = checked_out に更新される(論理削除・フロアが空席に戻る)。精算対象となるのは served 状態のオーダーのみ |
| BILL-017 | 清算完了後、領収書モーダルが表示される |
| BILL-018 | 領収書には店名・日時・商品明細・小計・割引・税額・合計・支払方法が含まれる |
| BILL-019 | 領収書モーダルから「完了」でダッシュボードへ、「会計履歴を見る」で会計履歴画面へ遷移できる |
3.7 会計履歴
| ID | 要件 |
|---|---|
| BILLS-001 | 全ての BILL を日時降順で一覧表示する |
| BILLS-002 | 一覧に会計ID・来客ID・日時・アイテム数・小計・割引・税額・合計・支払方法・ステータスを表示する |
| BILLS-003 | BILL の status を視覚的に区別するバッジを表示する(settled / voided) |
| BILLS-004 | settled 状態の BILL に対して「取消」操作ができる |
| BILLS-005 | 取消前に確認モーダルを表示し、理由を入力できる |
| BILLS-006 | 取消確認後、BILL の status が "voided" に更新される |
| BILLS-007 | voided 状態の BILL には取消バッジが表示され、取消操作はできない |
3.8 日次締め
| ID | 要件 |
|---|---|
| CLOSE-001 | 当日の売上合計(void 除外 BILL の total_amount 合計)を表示する |
| CLOSE-002 | 当日の現金売上合計を表示する |
| CLOSE-003 | 当日のクレジット売上合計を表示する |
| CLOSE-004 | 当日の平均客単価を表示する |
| CLOSE-005 | 当日の会計件数を表示する |
| CLOSE-006 | 当日の BILL_ITEM をカテゴリ別に集計して一覧表示する |
| CLOSE-007 | 各カテゴリに販売数量・売上金額を表示する |
| CLOSE-008 | 「本日を締める」ボタンで当日の締め処理を実行できる |
| CLOSE-009 | 締め完了後、「締め済み」バッジが表示され、ボタンが非活性になる |
| CLOSE-010 | 締めメモとして特記事項(機材トラブル・廃棄ロス・引継ぎ事項など)を自由記述入力できる |
3.9 商品管理
| ID | 要件 |
|---|---|
| PROD-001 | 全商品をテーブル形式で一覧表示する |
| PROD-002 | 一覧に商品名・カテゴリ・価格・商品画像サムネイルを表示する |
| PROD-003 | 商品名でリアルタイム検索できる |
| PROD-004 | カテゴリでフィルタリングできる(「全てのカテゴリ」選択時は全件表示) |
| PROD-005 | 総商品件数をページヘッダーに表示する |
| PROD-006 | 「商品を追加」ボタンで商品エディタモーダルを開ける |
| PROD-007 | 商品エディタに商品名(必須)・カテゴリ(必須)・価格(必須・正の整数)・画像URLの入力フォームを提供する |
| PROD-008 | 保存後、商品一覧の先頭に新商品が追加される |
| PROD-009 | 一覧の編集ボタンから対象商品の情報が入力済みの商品エディタモーダルを開ける |
| PROD-010 | 保存後、該当商品の情報が更新される |
| PROD-011 | 一覧の削除ボタン押下で確認ダイアログが表示される |
| PROD-012 | 削除確認後、商品一覧から該当商品が削除される |
3.10 カテゴリ管理
| ID | 要件 |
|---|---|
| CAT-001 | 全カテゴリを一覧表示する |
| CAT-002 | 一覧にカテゴリ名・スラッグ(英語識別子)・カラーバッジを表示する |
| CAT-003 | カテゴリ名(必須)とスラッグ(必須・英数字)を入力して追加できる |
| CAT-004 | 既存カテゴリの名前・スラッグを編集できる |
| CAT-005 | 保存時にスラッグの重複チェックを行い、重複の場合はエラーを表示する |
| CAT-006 | カテゴリを削除できる(紐づく商品がある場合は警告を表示し、削除後は該当商品の category_id が 0(未分類)にリセットされる) |
3.11 スタッフ管理
| ID | 要件 |
|---|---|
| EMP-001 | 全スタッフをカード形式で一覧表示する |
| EMP-002 | 各カードにアバター(名前の頭文字)・名前・役職・最寄駅・入社日を表示する |
| EMP-003 | 「スタッフを追加」ボタンでスタッフエディタモーダルを開ける |
| EMP-004 | スタッフエディタに名前(必須)・役職(必須)・最寄り駅(任意)の入力フォームを提供する |
| EMP-005 | 保存後、スタッフ一覧に新スタッフが追加される |
| EMP-006 | 既存スタッフの情報を編集できる |
| EMP-007 | スタッフを削除できる(確認ダイアログあり) |
3.12 売上レポート
| ID | 要件 |
|---|---|
| RPT-001 | 「本日」「7日間」「30日間」のタブで集計期間を切り替えられる |
| RPT-002 | 選択期間の売上合計金額を表示する |
| RPT-003 | 選択期間の会計件数を表示する |
| RPT-004 | 選択期間の平均客単価(売上合計 ÷ 会計件数)を表示する |
| RPT-005 | 選択期間の商品売上総点数(BILL_ITEM の quantity 合計)を表示する |
| RPT-006 | 選択期間の日別売上推移をグラフ表示する |
| RPT-007 | グラフには日付・売上金額が含まれる |
| RPT-008 | 現金・クレジットの支払方法別売上シェアを円グラフで表示する |
| RPT-009 | 各支払方法の金額・割合をグラフまたはレジェンドに表示する |
| RPT-010 | カテゴリ別の売上金額を円グラフで表示する |
| RPT-011 | 各カテゴリ名・売上金額・割合を表示する |
| RPT-012 | 選択期間の売上上位5商品をテーブル表示する |
| RPT-013 | 各商品に商品名・カテゴリ・販売数量・売上金額を表示する |
3.13 売上ランキング
| ID | 要件 |
|---|---|
| RNK-001 | 「月指定」「年指定」「カスタム期間」の3モードで集計期間を指定できる |
| RNK-002 | 月指定モードでは年月(YYYY-MM 形式)を選択できる |
| RNK-003 | 年指定モードでは年(YYYY 形式)を選択できる |
| RNK-004 | カスタム期間モードでは開始日・終了日(YYYY-MM-DD 形式)を入力できる |
| RNK-005 | カテゴリでランキングを絞り込みできる(「全カテゴリ」選択時は全件表示) |
| RNK-006 | 指定期間・カテゴリの商品を売上金額降順でランキング表示する |
| RNK-007 | 各行に順位・商品名・カテゴリ・単価・販売数量・売上金額・売上シェア(%)を表示する |
| RNK-008 | 集計期間の総売上金額・総販売数量をサマリーとして表示する |
| RNK-009 | 売上シェアはその商品の売上 ÷ 集計期間全体の売上 × 100 で計算する |
4. 非機能要件 Non-Functional Requirements
4.1 パフォーマンス要件
| ID | 要件 |
|---|---|
| NF-P001 | 画面初期表示は3秒以内に完了する |
| NF-P002 | 注文確定処理(ORDER生成)は1秒以内に完了する |
| NF-P003 | 商品検索のリアルタイムフィルタリングは入力から200ms以内に反映される |
4.2 ユーザビリティ要件
| ID | 要件 |
|---|---|
| NF-U001 | タブレット(768px以上)およびPC(1024px以上)のレイアウトに対応する |
| NF-U002 | モバイル(768px未満)ではレイアウトが崩れないレスポンシブ対応をする |
| NF-U003 | 主要なアクションボタンは視認性の高いプライマリカラーで表示する |
| NF-U004 | エラー状態・空状態・ローディング状態を適切にフィードバックする |
| NF-U005 | 金額は日本円(¥ + カンマ区切り整数)形式で表示する |
| NF-U006 | 日時は日本時間 (JST) で表示する |
4.3 可用性要件
| ID | 要件 |
|---|---|
| NF-A001 | データは Cloudflare D1 (SQLite) に永続化され、ページリロード後も状態が保持される |
| NF-A002 | API は Cloudflare Workers 上で稼働し、エッジでの可用性を確保する |
4.4 セキュリティ要件
| ID | 要件 |
|---|---|
| NF-S001 | 認証が必要なページへの未認証アクセスはログイン画面へリダイレクトする |
| NF-S002 | パスワードはプレーンテキストで表示・ログに出力しない |
| NF-S003 | APIトークンはローカルストレージではなくHTTPOnly Cookie(pos_access / pos_refresh)で管理する。フロントは Next.js プロキシ経由で Cookie を Bearer トークンに変換して Worker へ転送する |
4.5 保守性要件
| ID | 要件 |
|---|---|
| NF-M001 | Bulletproof React フォルダ構成(features / components / lib / stores)に従う |
| NF-M002 | 共有型定義は packages/shared で一元管理する |
| NF-M003 | Biome によるリント・フォーマットを統一する |
| NF-M004 | TypeScript strict モードを有効にする |