店員POSモード(V1)

Terminal は Connected Mode では決済専用機(明細表示+PINパッド)であり、カートを作る POS 機能を持たない。そのため 店員アプリ側に POS モードを追加する。


1. スコープ

含む 含まない(V1.1以降)
商品タイル・検索・カテゴリ バーコードスキャン(継ぎ目のみ用意)
カート(追加・数量・削除) 値引き・クーポン
合計確認・決済開始(Terminal) 顧客の紐付け
6桁コードなし(自動claim) 保留(オープンチケット)
顧客セルフスキャンとの併存 現金・返金UI

2. 業務フロー(店員POS)

店員: 商品をタップ/検索 → カート → 合計確認
  → 「会計へ」= POST /api/staff/orders(認証・自動claim)
  → 「決済開始」= POST /api/orders/{id}/checkout
  → Terminal に明細+合計 → 顧客が支払い
  → webhook(terminal.checkout.updated)→ PAID
  → レシートは Terminal が印刷
  • 顧客セルフスキャン(既存)は「新着」タブで受付(6桁コード or タップ)
  • 店員POSの注文は 作成時に自レジへ claim するためコード入力が不要
  • source: "staff" を注文に記録し、セルフスキャン(customer)と区別

3. API

メソッド パス 内容
POST /api/staff/orders 認証付き注文作成。価格はカタログから解決、clientToken で冪等、作成後 自動claim
GET /api/staff/orders 新着(OPEN)一覧(既存)
GET /api/staff/orders/{id} 注文ステータス(既存)
POST /api/orders/{id}/checkout Terminal へ送出(既存)
GET /api/staff/register レジ状態(既存)
POST /api/staff/register/release 端末ロック解放(既存・mock限定)
  • 既存の POST /api/orders は顧客用(未認証・公開)として維持
  • claim 前のレジ状態チェックは assertRegisterAvailable() を共用
  • 端末IDは サーバー側で REG#.terminalId から解決(クライアント指定は不可)

4. データ

項目 内容
注文 source: "customer" | "staff" を追加
店員POS OPEN で作成 → 即 CLAIMED(registerId / terminalId 設定)
コード 6桁コードは発行されるが、店員POSでは使用しない(将来のレシート照会用)

5. 共通パッケージ

パッケージ 役割
packages/cart 純粋なカート演算(add / change / remove / total / toOrderItems / barcode解決)
packages/ui-cart 共有 Svelte 部品(ProductGrid.svelte / CartLines.svelte)

顧客PWAと店員POSで同一ロジック・同一UIを使う(重複実装を避ける)。


6. スキャンの将来対応(V1では未実装)

層 今の状態 追加時にやること
ロジック addByBarcode() / findItemByBarcode() 実装済み(テストあり) UIから呼ぶだけ
API カタログに barcode を保持 GET /api/catalog/barcode/:code を追加
索引 未追加 カタログをDynamoDBに持つ段階で GSI2 または BARCODE# 項目
UI 機能フラグ features.scan=false で非表示 入力欄+ボタン
入力 — Bluetooth HIDスキャナ(第一候補)、カメラはM8で実機検証

7. 受入条件

  1. 店員がタイル/検索でカート作成 → 合計 → 決済開始 → Terminal で PAID
  2. 顧客セルフスキャン(新着→claim→決済)が従来どおり動作
  3. 同一注文の二重送信が冪等(clientToken)
  4. 端末ロック競合時は 409 TERMINAL_BUSY → 復旧UI(既存)
  5. スキャンUIは表示されない(features.scan=false)

8. 非目標・制約

  • Terminal 実機はオフライン決済に対応しない(Connected Mode)
  • 値引き・顧客・保留・現金・返金UIは V1.1
  • Square POS アプリとの同時利用は不可(terminal-options.md)