珈琲・俺を支える技術 〜模擬店に内製POSシステムを導入する〜

2024/12/02に公開

机の上にコーヒーの入った紙コップが置かれている写真。紙コップには「No.741 べっぴんブレンド 1/1」と書かれたラベルが貼られており、ロータスのBiscoffとコーヒーカード、番号札が共に添えられている。
当日の様子。POSシステムによって印字されたラベルがカップに貼り付けられている

📍 はじめに

珈琲・俺(かふぇおれ) は25年の歴史を持つコーヒーのサークルです。
毎年、学園祭でコーヒー[1] を販売しています。

この記事では、珈琲・俺で 今年から導入されたPOSシステム についてご紹介します。

🏷️ 背景

近年、構成員の増加や広報宣伝の強化により、珈琲・俺の模擬店は非常に混雑します。

大量のお客さんを捌くため、注文から提供までのフローは分業化・マニュアル化されており、POSシステムの原型となる仕組みも以前から導入されていました。

ただ、Google スプレッドシートをベースに、Google Apps Script のマクロを組み合わせた簡易的なものでした。

注文から提供までのフローと共に、従来の課題を整理してみます。

従来の注文フロー

店舗における注文から提供までのフローは次にようになっています:

各役職の説明

レジ

  • 接客と注文を行う
  • POSに注文を入力する

タグ

  • レジで入力された注文の内容を1カップずつタグに転記する

豆屋

  • タグをカップに貼り付け、内容に応じた豆を計量・用意する

マスター

  • ドリップ待ちのカップをドリッパーにアサインする
  • その時間帯の店舗の責任者でもあり、イレギュラーな事態に対して判断を行う
  • POSから提供待ちの注文を参照する

ドリッパー

  • マスタに振り分けられたコーヒーの抽出を行う
  • 店舗に複数人いる

提供

  • ドリッパーが抽出したコーヒーを提供する
  • カフェオレ等のメニューではミルクを追加する
  • POSに提供完了を記録する

課題だった点

  • ⚠️ タグの記載ミスにより、再ドリップなどの大幅な手戻りが生じる場合がある
  • ⚠️ Google スプレッドシートの同期が途切れる場合がある
  • ⚠️ POSシステムの操作ミスが多い

POSシステムは既に多くの機能を要求されている一方で、 Google スプレッドシートはそれを十分実現するには不足でした。
また、ソースコードを Git 等の VCS で管理できていないこともあり、保守管理の課題も抱えていました。

📝 新規システム制作へ

前述の課題を踏まえ、Web アプリとして 0 から新規作成する方がメリットが大きい と判断しました。
制作は学園祭の3ヶ月前から開始し、後輩3人に実装の一部を担当してもらうことで、来年の引継ぎを兼ねることにしました。

技術スタック

型の恩恵を受けたかったので TypeScript での開発を基本に置きました。
また、引き継ぎの手間を考え、極力外部インフラへの依存を減らすよう考えました。
Firebase に寄せられる箇所は全て寄せ、SPA とすることでデプロイ・ホスティング先に依存しないよう設計しました。

  • Web アプリケーション
    • React
      • Remix + Vite (SPA mode)
      • 💡 内部でのみ使用する業務システムなので SPA でよい
      • 💡 インフラの管理を最小限にしたかった
    • Tailwind
      • shadcn/ui
        • 💡 内部システムなので独自スタイルが必要な画面が少ない
        • 💡 機能開発に注力することができる
    • Firebase
      • Firestore
        • 💡 Web でリアルタイム同期を扱う BaaS として十分熟れている
      • Authentication
        • 💡 信頼性
    • Zod
    • SWR
    • EPSON SDK for JavaScript
      • 💡 ラベルプリンタの制御に使用

🖨️ ラベルプリンターの導入

POSシステム開発の途中、思った
タグが自動で印刷されたらアツくね?

というのも、従来の課題であった

⚠️ タグの記載ミスにより、再ドリップなどの大幅な手戻りが生じる場合がある

を完全に解決できるからです。

しかし、ラベルの自動印刷の実現は困難を極めました。
安価で入手できるラベルプリンターは専用のソフトウェア以外での制御を受け付けておらず、Webアプリ内に組み込めなかったからです。


技術検証の過程で購入した安価なラベルプリンター
SDKが提供されていなかったため採用は見送りとなった

しかし!そのタイミングでAmazonマーケットプレイスで EPSON のラベルプリンターが約9000円で出品されているのを発見し、すぐさま購入しました。

EPSON は JavaScript 用に公式 SDK を提供しており、それを用いると Webアプリからの制御が可能です。ただ、中古でも数万円で出回っており、1万円以下で手に入れられたのは幸運でした。

SDK 無しで制御している方の記事が見つかった[2]というのも理由のひとつです。


EPSON TML90UE431
Amazonマーケットプレイスにて約9000円で購入

🕹️ UIのこだわり

基本的には内部でのみ使われるシステムですが、前述の通り店舗スタッフはシフト交代制で多数の方々がシステムに触れるため、UIにも工夫を凝らしました。[3]

次の動画はレジ画面の動作の様子です:

https://youtu.be/ZjDX5pfLmZs

左下のカラフルな画面はお客さんが注文内容を確認する画面です。
スタッフが操作するレジ画面と状態が同期され、確定前の注文内容を常に確認できます。

注文が確定すると、珈琲・俺のモーショングラフィックが動き、某コーヒーチェーンのようなベル音が再生されます。この画面はお客さんの目に触れるのでぱっと見でインパクトがあるデザインを目指しました。

このタイミングでラベルプリンタも統合されて制御されているのも胸熱ですね。

続いて、各画面のスクリーンショットと説明を簡単に並べておきます:

レジ画面

スタッフ画面


レジでは5つの入力箇所を順に埋めていく。キーボード入力 / マウス操作両方で同一の操作が可能なように設計


キーボードで直接メニューを入力できるようシールを貼り付けてある
特定の入力箇所の場合のみキーイベントを拾うため誤入力しづらい仕様になっている

お客さん向け画面


レジの状態をFirestoreで同期して表示する

マスタ画面


基本的に閲覧のみの画面。区別しやすいように色付けられている。後述の提供とは別のカラーリング

提供画面


「提供」ボタンで提供完了を記録する。後処理が必要なカフェオレ系のメニューに色付けられている

✅ 振り返ってみて

改めて、新システムによって変化した注文フローと課題について振り返ってみましょう

改善された注文フロー

店舗スタッフからタグの役職がなくなり、POSシステムのラベルプリンターが代わりの役割を担っています。

ヒューマンエラーが発生しうる箇所を一つ減らせたという点で、この変化は想像よりも大きな効果を生むこととなります。

改善された点

  • タグが自動印刷になったため
    • 転記ミスによる手戻りがゼロに
    • 提供時間の大幅な短縮
    • 店舗スタッフに余力が生まれた
  • ✅ 接続安定性の向上
  • ✅ UI の改善による操作ミスの低減
    • 副次的に、データの提供時間などのタイムスタンプの正確さが向上

特に、提供時間の短縮は解析結果からも明らかで、大きな成果と言えそうです。


当日の夜にすぐさまPOSデータの解析が行われた
提供時間が大幅に短縮されていることがわかる

🎗️ むすびに

ここまで読んでいただきありがとうございました!
POSシステムを通じて売上改善に貢献できたこと、そして来場者の方々にもよい評判をいただけたことは制作者として大きな喜びでした。

POSシステムは、来場者さんにおいしいコーヒーを提供する「珈琲・俺」という組織のほんの一部にすぎず、デザインチーム、売上データ解析担当、映像制作担当、看板や店舗装飾のDIYチームや、実行そのものを主導する役職者など、多くの人々の尽力によって今年の店舗の姿があります。

珈琲・俺の皆様、本当にありがとうございました!

📑 関連記事

今回のプロジェクトで得た技術的知見は、以下の記事にて発信予定です。

No. タイトル(仮) 公開日時
1 Zod で Firestore を型安全に扱う 〜再帰的 Date コンバータの実装〜 未定
2 EPSON SDK for JavaScript を使用して Web アプリからラベルプリンタを制御する 未定
3 DuckDB を使ってサクッとJSONを解析してみる 未定
脚注
  1. 豆の選定、ブレンド考案、ハンドドリップ試験制度など、紹介したいことは沢山ありますが、他の記事に譲ります。 ↩︎

  2. https://qiita.com/yamukotonaku/items/53f3fa167ca7c867c4b4 ↩︎

  3. Webアクセシビリティの観点から見ると不適切な実装箇所がいくつかあります。今回は内部で使用するシステムということもあり、ユーザーをかなり限定した想定で製作しました。 ↩︎

Discussion