🛒

【文化祭】模擬店での会計を楽にするためのレジを作った話

2023/06/18に公開

東福岡学園 学園祭から、気づけば1週間が経過しました。感動の新しいうちに、今回の学園祭で使用した、レジシステムについて記録しておこうと思います。
実際に、学園祭で使用していった中で気づいたことや、感じたことを記事にしていますので、他校の方の参考になったら幸いです。文章が拙く、読みにくいところが多々あるかと思いますが、質問等がありましたら、コメントにてお知らせください!

1. システム概要

東福岡学園 学園祭は、例年約1万人を超える方々が来場し、40店舗以上の模擬店が出店します。その中で、会計時に簡単に使えるレジのようなシステムの開発が必要になりました。元々は、QRコード決済の作成などを考えていましたが、お年寄りや、小さな子供までさまざまな年代層の方が来場する上で、「スマートフォンを持っていない」、「小さい子供にお金を使わせる経験をさせてみたい」などの問題から、断念しました。

おもな機能としては次のとおりです。

  • 会計の計算
  • 会計記録の確認
  • 準備金の入力
  • 総売上の確認


実際のレジ画面

2.導入背景

2022年の学園祭にて、筆者の2個うえの先輩がレジシステムを開発しました。(GASとスプレッドシートだけで作成しててビビりました。)しかし、システムの運用がうまくいかず、来年こそはきちんと整備された使いやすいレジシステムを作成しようと思いました。それから、かなり時間が流れ、2023年1月。学園祭の概要が少しずつ見えてきて、学園祭が一般公開されることがわかりました。そこで、第一案である「QRコード決済(仮名:Higashi Pay)」の作成の案があがりました。しかし、システム概要にも書いたような問題から、断念しました。しかし、そこで諦めないのが当委員会(後述のデジタル委員会)の委員長。会計システムだけは作成したいと、生徒会の偉い人たちに掛け合ってくれ、本格的なシステムの構築へと一歩前進しました。

3.使用技術

当システムには、以下の技術を使用しました。技術選定をする上で、安定し、使いやすいを目指しました。
おおよそ、3000円ほどで運用できました。

フロントエンド

Next.js + Mantine UI + Vercelで作成しました。
https://github.com/T-taku/hfhs-register

UI

UIには、Mantine UIを使用しました。
Mantine UIはカスタマイズ性が高く、またiPadで使用しても見やすく仕上げることができたため、とても重宝しました。コンポーネント数もかなり多く、痒い所に手が届くHookもかなり多く助かりました。



数字入力の部分の実装は、以下の記事にてnewtさんに質問したところ、快く答えていただけました。
https://zenn.dev/newt_st21/articles/gateway-stay-status-record-system#comment-71a893865c7908

PWA

学校のネットワークは、かなり貧弱なので、できるだけ負荷を減らすことを目標にしました。
next-pwaを使用し、簡単に実装することができました。
学校のiPadには、端末管理(CLOMO MDM)のプロファイルがインストールされてあり、こちらからアプリの追加や、削除ができたため、iPadへのインストールに困ることはありませんでした。

オフライン対応

PWAで負荷を下げてるとはいえ、いつネットワークに異常が発生し使えなくなるかわかりません。異常が発生し、記録が消えないようにするため、端末内にデータを保存できるようにしました。ここの実装は、前述の2個うえの先輩がやってくれました。マジで助かりました🙏
https://github.com/T-taku/hfhs-register/blob/main/src/utils/initAPI.ts
https://github.com/T-taku/hfhs-register/blob/02ded70bc7f4d5050eae2c3fbc9357ecd6252ec7/src/utils/initAPI.ts#L39-L53
https://github.com/T-taku/hfhs-register/blob/02ded70bc7f4d5050eae2c3fbc9357ecd6252ec7/src/utils/initAPI.ts#L63-L75
https://github.com/T-taku/hfhs-register/blob/02ded70bc7f4d5050eae2c3fbc9357ecd6252ec7/src/utils/initAPI.ts#L93-L108
https://github.com/T-taku/hfhs-register/blob/main/src/utils/initAPI.ts#L128-L181
この辺りがオフライン対応時の部分のコードになっています。

認証

Auth.js(旧:NextAuth.js)を使用しました。学校が配布しているGoogleアカウントを使用し、ログインします。本当は、Firebase Authenticationなどを使いたかったですが、料金が従量制で固定されないこと、いつか記事にするであろう、修学旅行時に作成したSNSで、Firebaseを使用し、大変苦労したことなどから、断念しました。
たった数行のコードで、Googleアカウントを使ったログインシステムが構築できました。
APIとのアカウントの情報の受け渡しに、JWTを使用したかったのですが、なぜかAuth.jsは(JWTと書いているのに...)JWEでアカウント情報を暗号化するため、それに対応する複合を行う必要がありました。
JWTの取得はこの辺りです。この仕様に気づくのに、丸一日かかりました。
https://github.com/T-taku/hfhs-register/blob/main/src/pages/api/auth/jwt.ts
API上での複合はこのようになっています。
https://github.com/higashifukuoka-digital/hfhs-regi-api/blob/main/auth.py

商品の値段管理

商品の値段管理は、こちら側で提出されている模擬店の出店申請をもとに型定義で管理するようにしました。全体的に見やすく管理できました。
https://github.com/T-taku/hfhs-register/blob/02ded70bc7f4d5050eae2c3fbc9357ecd6252ec7/src/utils/product.ts

バックエンド

https://github.com/higashifukuoka-digital/hfhs-regi-api

API構築

API構築には、FastAPIを使用しました。これまで、Pythonでの実務経験もあり、型定義が簡単という点から選びました。その名の通り、とても高速に動いてくれました。
Swaggerで、自動的にAPIのドキュメントを作成してくれるため、簡単にAPIの仕様を共有することができました。

エンドポイント一覧
GET /user - ユーザー情報を取得する
GET /history/{class_name} - 決済履歴を取得する
POST /history/add/{class_name} - 決済履歴を追加する
GET /setting/{class_name} - 店舗設定を取得する
POST /setting/set/{class_name} - 店舗設定を変更する
GET / - インデックスページを表示する(200レスポンスを返すのみ、Uptimerobot用)
GET /auth - ログイン状態を確認する

データベース

データベースには、MySQLを使用しました。これも実務経験がかなりあり、phpmyadminなどとの相性が良かったのも、選んだ理由の一つです。
Ekkeさんの以下の記事を前もって読んでいたため、max_connectionの設定の変更も忘れることなくできました。
https://zenn.dev/ekke/articles/ec07943d678340#サーバダウンの原因

ORM

FastAPIのドキュメントでも紹介されていた、SQLAlchemyを使用しました。個人的には、SQL構文で書いたほうが楽ではあったのですが、安全性などを考えても、ORMの使用は適切だったなと思います。FastAPIとの相性もかなり良く、使いやすかったです。
https://www.sqlalchemy.org

Docker

開発環境が、MacとWindows、サーバーがUbuntuとさまざまなOSになってしまうことを考慮し、Dockerを使用して、環境構築を行いました。
デプロイ先は、ConoHa VPSを選びました。Dockerのテンプレートがあり、簡単にDockerコンテナをデプロイできました。
また、コマンド一つで全て起動できるのも魅力的でした。

4.システムの流れ


実際の会計の様子

4-1.会計

  1. 画面の上にあるボタンで商品を選びます。青色が通常価格、赤色が割引価格で登録しています。

  2. 商品を選び終わると、「支払いへ進む」ボタンが押せるようになり、押すと次のような画面が表示され、預かった金額を打ち込むことができます。

  3. 「支払いへ進む」をクリックし、記録完了の通知が出たら、記録が完了します。

    ※この写真だけ、パソコンで撮影。

4-2.会計履歴確認


このようにこれまでの会計履歴を確認できるようになっています。

アコーディオンを開くと、詳細を確認できます。

オフライン時の対応

オフラインになると、端末に保存することになるため、右下に通知を出すようにしました。
正常にネットワークに再接続した際に、自動的に送信し直す仕組みです。

端末に保存した旨を通知

ネットワーク復帰時

正常に記録ができた場合


正常にデータが送信できた場合は、以前の記録が送信された旨が表示されます。

正常に記録できなかった場合


正常に記録ができなかった旨の通知が表示されます。

このような場合は、先ほどの履歴ページへいき、ネットワークが良好な状態で、「送信」を押します。

このようにして記録を送信できます。

以上が、このレジシステムの一連の流れとなっています。

5.学園祭 当日〜会計監査

前日まで、試用期間としてレジシステムを開放していました。当日の開場は10時だったため、9時30分にデータベースのリセットを行おうとしていました。時間になり、データベースのリセットをかけ、ほっと一安心していたところ、模擬店の生徒からリセットされていない旨の連絡が入りました。結局のところ、iPadで開いていたレジシステムを、強制終了させることで、事なきを得ましたが、南館から北館の40店舗以上を回るのはなかなかに地獄でした。
1日目の学園祭会議にて、返金ボタンを作成して欲しいという意見があがり、1日目の終了後に実装しました。また、とあるクラスがデータの通信がうまくいっておらず(おそらくフィルタリングのプロキシのせい?)、大量に記録を送信してきてしまったため、2000万円近い売り上げを出してしまうという問題が発生しました。該当クラスには、2日目朝時点で金庫に入っているお金を全て計算してもらい、2日目の朝に反映させることで対処しました。phpmyadminを入れておいて本当に良かったです。
1日目は、委員会以外の仕事でも大量に走り回っていたため、Apple Watchのフィットネスの記録がすごいことになっていました。

2日目は、学園祭終了後に全クラスの会計監査を行いました。ヒューマンエラーなどで、システム上の金額と、金庫内の金額が合わないクラスが続出しました。その中でも、8クラスほどがシステム内のお金と、金庫内のお金がピッタリあっていました。ヒューマンエラーなどは、システムではどうにも防げないものなので、来年以降は何かヒューマンエラーを防げる仕組みを考えたいと思います。(ダブルチェック制など...)

6.来年へ向けた反省点

  1. 模擬店責任者向けへの説明会を行いましたが、その時はまだシステムが未完成だったため、前で説明するだけになってしまいました。そのため、うまく伝わらずシステム自体使用していないクラスもありました。やはり、実際に使ってもらいながら、説明を受けてもらうというのは大事ですね。
  2. 仕方ないとはいえ、急な仕様変更を学園祭期間中に行なってしまったことは、かなりまずかったです。更新を加えた際には必ず、責任生徒へ「ロイロノート」を使用し連絡を回していたのですが、朝礼で言ったにも関わらず、確認していなかったり、わからないことをそのままにしてしまっているクラスがあり、システムをうまく運用できてないクラスがありました。

以上の点を踏まえて、来年はより良いシステム構築をしようと思います。

7.おまけ

サーバーの使用状況

サーバーのスペックは、ConoHa VPSのメモリ2GBのプランでしたが、実際はそのうちの1.2GBを常に使用しているような状態でした。

サーバーの監視には、Mackerelを使用しました。無料で使用でき、またサーバー内に異常が発生した場合は、通知を送信してくれるため、パソコンの前にいない時でも、安心して学園祭を回ることができました。

システムの表示回数

Google Analyticsにて、システムの使用状況を記録していました。(学園祭期間中のみ)

全記録数は、2日間で18,076件でした。

「学園祭ウェブサイト」の閲覧数

全くレジシステムに関係ありませんが、今年も昨年同様、学園祭のウェブサイトをSTUDIOを使用し、作成しました。

閲覧数は、55,000回越えですね...2日でPV数を超過してしまいました。
ちなみに、今年の学園祭のサイトは、カラフルでポップをテーマに作成しました。よろしければ、ご覧ください✨
https://hfhs-schoolfestival2023.fun

最後に

自分が作ったシステムを、初めて、たくさんの人に使っていただきました。達成感がすごかったです。さまざまな調整を行なってくれた、デジタル委員長をはじめとし、このシステムの使用を認めていただいた、学園祭委員長、生徒会の方々、先生方本当にありがとうございました。

追記: デジタル委員会について

後述すると書いておいて忘れていたデジタル委員会についてご説明します。

東福岡学園では、ICT教育推進の一環として、デジタル委員会を自彊館中学校および、東福岡高校に設置しています。今回のシステムは、委員会活動の一環として作成されたものです。(レジシステムは、高校が作成したものです。)デジタル委員会は、このような活動以外にも、行事ごとの映像作成や、iPad配布オリエンテーション、ポスターの作成、iPadの便利活用術の紹介などを校内にて行なっています。興味を持たれた方は、以下までご連絡ください!!
hfhs.2268024[at]higashifukuoka.net (東福岡高校 デジタル委員会 プログラミング部門長 立石 / 本記事執筆者)
デジタル委員会への直接のご連絡はこちらです: hfhs.digital[at]higashifukuoka.net

Special Thanks

このシステムを運用する上で、以下の記事を参考にしました。(特に学校への説得方法など...)この場を借りて御礼を申し上げます。
https://zenn.dev/kakkokari_gtyih/articles/d592fd1d1e45dd
https://zenn.dev/newt_st21/articles/gateway-stay-status-record-system
https://zenn.dev/su8ru/articles/cappuccino-system
https://zenn.dev/ekke/articles/ec07943d678340

Discussion