デモキット仕様(配布+GMeet 実演)

顧客・店員・BE は本番と同じコード(BE はアダプタのみ mock)、Terminal だけモックにしたデモ環境。先方に zip を配布し、Google Meet で使い方を実演する。

現行のAWSデモは Cloudflare Pages + AWS API 構成。手順は「11. Cloudflare Pages + AWS デモ」と ../OPERATIONS.md を参照。


1. 目的

  • 実機と Square アカウントなしで、V1 の操作感を再現する
  • 先方が自分の PC で起動して試せる
  • 本番と同じ状態遷移・API 形状を使い、捨てコードにしない
  • 現金は対象外(V1.1。デモでは扱わない)

2. 構成

[CloudFront]
  /s/{shopId}/customer  ← 顧客PWA(公開)
  /s/{shopId}/staff     ← 店員PWA(公開)
  /api/*                ← Lambda(BE、ADAPTER=mock)
  /webhooks/*           ← Lambda

[店舗PC(キット / Node)]
  /terminal             ← Terminal モック(ローカル配信)
  /setup                ← 初期設定
  • PWA は公開ホスト。客・店員はスマホの URL を開くだけ
  • キットは Terminal モックとランチャーを担当
  • モック端末は 2 秒ポーリングで BE と同期(現行AWSデモ)

3. 配布物

shop-kit/
├── start.bat              Windows 用(ダブルクリック)
├── start.command          Mac 用(初回 chmod +x を README に明記)
├── package.json
├── package-lock.json
├── server.js              Terminal モック配信+ランチャー
├── shop.config.json       設定
├── public/
│   ├── terminal/          Terminal モック
│   └── setup/             初期設定
├── README.md              5分で分かる手順
└── DEMO-SCRIPT.md         GMeet 台本(3分/15分)

4. 起動(Windows / Mac)

前提

  • Node.js 18 以上(20 LTS 推奨)
  • インターネット接続(BE はクラウド)

手順

  1. zip を展開
  2. start.bat(Windows)/start.command(Mac)を実行
  3. ブラウザが自動で開く
  4. 未設定なら /setup で shopId / registerId / apiBaseUrl を入力
  5. ランチャーから「顧客」「店員」「端末」を開く

現状のPWA: manifest とアイコンのみで、Service Worker は未登録。ブラウザ運用で、PWAインストールは未対応。

スマホからHTTPSで開く場合(任意・AWS不要)

Cloudflare Quick Tunnel の例(独自ドメイン・アカウント不要、URLは起動ごとに変わる):

# 別ターミナルで3本起動
cloudflared tunnel --url http://localhost:5173
cloudflared tunnel --url http://localhost:5174
cloudflared tunnel --url http://localhost:3100

表示されたURLを .env またはシェルの環境変数に設定して npm run dev:

CUSTOMER_URL=https://xxxx.trycloudflare.com/
STAFF_URL=https://yyyy.trycloudflare.com/
TERMINAL_URL=https://zzzz.trycloudflare.com/
  • ランチャーのQRが上書きURLになる。PCの「端末画面を開く」はローカルのまま
  • cloudflared は別途インストール(このリポジトリの依存には含めない)
  • インストール済みPWAはURL(オリジン)に固定されるため、Quick TunnelのURL変更後は再インストールが必要
  • 継続利用する場合は Tailscale Funnel などの固定URLを使う
  • ローカルデモ自体はAWS不要(Docker上のDynamoDB Localを使用)

実装上の注意

  • ネイティブ依存ゼロ(sqlite3 等を使わない)
  • パスは path.join、改行は .gitattributes で固定
  • ブラウザ起動は process.platform で start / open を切替
  • 起動パネルは Terminal(3100)のHTTP応答を待ってから別窓で開く(失敗時はパネルのボタン)
  • OPEN_TERMINAL=0 で Terminal の自動オープンを無効化
  • Terminal パネルのQRは LAN の 3100(TERMINAL_URL 指定時はそのURL)。スマホからも開ける
  • ポート 3000 → 使用中なら 3001 に自動フォールバック
  • Windows の文字化け対策(UTF-8 / chcp 65001)
  • 起動時に doctor:Node 版、API 到達性、設定の妥当性をチェック

5. 設定

shop.config.json

{
  "shopId": "shop-01",
  "shopName": "デモ商店",
  "registerId": "reg-01",
  "terminalId": "term-01",
  "apiBaseUrl": "https://xxxx.execute-api.ap-northeast-1.amazonaws.com/prod",
  "publicBaseUrl": "https://xxxx.cloudfront.net",
  "mode": "mock",
  "staffPin": "1234"
}
  • 配布時に shopId / registerId を発行して同梱
  • mode はキットの表示・機能フラグ用。実際の決済アダプタは BE 側の ADAPTER(mock/sandbox/production)で決まる
  • staffPin はデモ専用(本番は Cognito)

6. Terminal モック仕様

画面

┌────────────────────────────┐
│  DEMO                      │
│  ────────────────────────  │
│  ご注文                      │
│  コーヒー豆 200g   ×2  2,400 │
│  ドリッパー        ×1    800 │
│  ────────────────────────  │
│  合計              ¥3,200    │
│                            │
│  [ カードをタッチ ]          │
│  [ キャンセル ] [タイムアウト] │
└────────────────────────────┘

状態

状態 表示
IDLE 「お待ちください」
PRESENT 明細+合計+タッチ促し
PROCESSING スピナー「処理中」
SUCCESS チェック+「完了」+レシート風
FAILED エラー+再試行案内
CANCELED / EXPIRED 取消・期限切れ

操作(デモ用)

  • タッチ(成功) → POST /api/mock/checkouts/{id}/complete
  • キャンセル → .../cancel
  • タイムアウト → .../timeout
  • 成功・失敗は本番と同じ共通ハンドラを通す

表示上の注意

  • 「DEMO」バッジを常時表示し、本物と誤認させない
  • 金額・明細は BE が返した注文をそのまま表示
  • 端末風フレーム(5.5インチ比率)で実機に寄せる

7. モード(BE 側 ADAPTER)

ADAPTER カタログ 端末 用途
mock シードJSON Terminal モック 配布デモ
sandbox Square Sandbox シミュレート端末ID 結合テスト
production Square 本番 実機 本番
  • キットの shop.config.json の mode は表示・フラグ用。BE の ADAPTER と揃えて運用する

8. GMeet 実演(30分)

時間 内容
0–5分 全体像(顧客/店員/端末の3画面)
5–15分 正常系:カート→6桁→店員確認→端末タッチ→完了
15–20分 例外系:キャンセル/タイムアウト
20–27分 先方の PC で /setup→起動→実演(画面共有でフォロー)
27–30分 本番(Square 実機)との差分、次フェーズ

画面共有の配置

  • 1画面に3ウィンドウ:顧客PWA(モバイル幅)/店員PWA(モバイル幅)/Terminal モック
  • 2レジを見せる場合は、キットを別ポートでもう1つ起動(reg-02)

9. トラブルシュート

症状 原因 対応
起動しない Node 未導入/古い README の手順、node -v 確認
ポート使用中 既存プロセス 自動で 3001 へ。表示された URL を使う
画面が真っ白 API 到達不可 apiBaseUrl と /api/health を確認
カメラが動かない HTTPS でない/アプリ内ブラウザ Safari/Chrome で開く(MVP はスキャンなし)
Mac で start.command が開かない 実行権限 chmod +x start.command
文字化け コンソールのエンコーディング UTF-8 / chcp 65001
「本物?」と誤解 モック DEMO バッジと README を明示

10. 受入条件

  • Windows と Mac の両方で start から起動できる
  • 未設定時に /setup へ誘導される
  • 顧客→店員→端末→完了 が一連で動く
  • キャンセル/タイムアウトが再現できる
  • 2レジ同時で干渉しない
  • DEMO 表示が出ている
  • README と台本だけで先方が再現できる

11. Cloudflare Pages + AWS デモ(現行)

ローカルにVite/Nodeを常駐させず、画面はCloudflare Pages、API/DBはAWSで動かす構成。

Cloudflare Pages(無料・HTTPS)
  customer.pages.dev  → 顧客アプリ + /launcher
  staff.pages.dev     → 店員アプリ
  terminal.pages.dev  → Terminal
       ↓ fetch /api/*(CORS)
AWS API Gateway → Lambda → DynamoDB
       ↑
WebSocket(wss)はAPI Gatewayへ直接

前提

  • AWSアカウント・AWS CLI・SAM CLI・Node.js 22
  • AWSプロファイル(例: shoptools)にCloudFormation/Lambda/DynamoDB/SSM/IAM/S3の権限
  • Cloudflareアカウント(Pages Free)
  • CLOUDFLARE_API_TOKEN(Account → Cloudflare Pages → Edit)
  • CLOUDFLARE_ACCOUNT_ID
  • .env に CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID を設定(Git管理外)
  • .env に MFA_SERIAL / MFA_TOTP_SECRET / MFA_DURATION_SECONDS を設定。MFA_SERIALはMFAデバイスのARN(例: arn:aws:iam::<account>:mfa/<device-name>)。ユーザーARNではない。TOTPシークレットはMFAデバイス同等の秘密
  • MFA_TOTP_SECRET はAuthenticator登録時のQRにあるBase32 secret。AWSは既存デバイスのsecretを再表示しない

初回デプロイ

. .\scripts\use-env.ps1
npm run aws:mfa                              # MFA(.envのTOTPシークレット)
npm run aws:check
powershell -File scripts\deploy.ps1 -Yes      # AWSバックエンド
powershell -File scripts\pages.ps1 -Yes       # Cloudflare Pages

pages.ps1 は以下を行う:

  • AWSスタックのApiUrlを取得
  • 3アプリをビルドし、dist/config.jsにAPIベースを注入
  • QR付きlauncher.htmlを生成
  • wrangler pages deployで顧客/店員/Terminalを配置

表示されたURL:

  • 起動パネル: https://<prefix>-customer.pages.dev/launcher
  • 顧客: https://<prefix>-customer.pages.dev/
  • 店員: https://<prefix>-staff.pages.dev/?r=reg-01
  • Terminal: https://<prefix>-terminal.pages.dev/

起動・停止(データ保持)

npm run aws:demo:stop
npm run aws:demo:start
npm run aws:demo:status
  • stop: Api/Webhook/Syncの同時実行0+同期ルール停止
  • start: 同時実行復元+同期ルール再開
  • CloudFront/S3は使わない。Pagesの静的配信は停止中も残る

データ操作

npm run aws:data:export
npm run aws:data:import -- -File .\backups\shoptools-dev-....json -Yes
npm run aws:data:reset -- -Yes

DynamoDBへ直接アクセスするため、停止中でも実行可能。resetは全件削除後に店舗/レジを再作成する。

ポーリング

  • 顧客カタログ: 10秒
  • Terminal: 2秒
  • 店員の決済中: 1秒

APIはCORSでPagesドメインからの直接アクセスを許可する(デモは*、本番はPagesドメインに限定)。