学食モバイルオーダーアプリ -RunTicket-

# はじめに
※本記事はアドカレに投稿した内容です

こんにちは😄

S科3年生のさいとーです。今回は私たちが製作した学食モバイルオーダーアプリ「RunTicket」の紹介をさせていただきたいと思います！

# 背景

皆さんは普段学食を利用していますか？

僕は唐揚げが好きでよく利用しています。

しかし、お昼の時間帯はバカ混み。。。次の授業が始まる50分までに食べ終わるかいつも心配になりながら過ごしてました。また、梅田キャンパスの食堂は決済方法が現金と楽天edyのみでその他電子決済に対応していないため、ATMにお金を引き出しにいかなければならないことが多々ありました😰

そこで！！！！

**学食モバイルオーダーを作ろう！**

ちょうどモノづくりデザイン思考実践演習という授業でモノづくりを行う機会があったため、愉快な仲間たち7人と今回開発することにしました。

## どうやって作る?

初めは某ハンバーガー店のモバイルオーダーアプリを参考にするか的な軽いノリで始まったプロジェクトですが、よく考えるとネイティブアプリだとAndroidとiOSで開発コストがそれぞれでかかってしまうため、プラットフォームから見直す必要があるという話が上がりました。

OSによってコストを掛けずに開発するには、FlutterやXamarinなどのクロスプラットフォームにビルドできるフレームワークを使ったり、WEBアプリケーションやLINE BOTなどのフロント部分を現あるサービスに任せる方法などがあったりします。その中で、僕を含めReact経験者がチーム内に二人いたということもあり、出来ればReactを使って開発したいという話が上がりました。また、ログイン時に組織ドメインを使って本学の生徒がどうかをチェックしたいということもあり、今回はGoogleログインに対応したWEBアプリが最適であると判断しました。

そんなこんなで方向性が決まったのですが、WEBアプリケーションを作ると言ってもフロントエンドには様々な描画アーキテクチャが存在します。SPA/SSR/ISRの中で何を選定するのが良いのかなどの話し合いが行われ、中々最初の方は開発に漕ぎ着けるまでに時間がかかりました。議論の末、SPAを採用し、UXの観点からPWAにも対応することにしました。その他、以下に話し合った出来事を書いておきます。

### 決済をどうするか

PayPayが便利だし街でも普及してるし対応させたら面白そう。ついでにクレジット決済にも対応するか

### バックエンドどうする？

1日にどれくらいアクセスがあるのか可視化したいし、保守コストも鑑みてクラウドに任せちゃおう。JavaScriptとの相性の良さからできればNoSQL使いたい→ firebase

### **Firebaseのデータ打ち込み面倒じゃない？**

Firebaseめっちゃ便利だけど、GUIでいちいち打ち込みするのが面倒でステータスの書き換えもすごく時間がかかる。簡単にデータを追加や書き換えをしたい→Google Apps Script

### 現状のシステムが食券制

本当は食券を撲滅したいけど、それだと現金派が困るし食堂のおばちゃんも困惑しそう。現金派とモバイルオーダー派で正しい順番を割り振るなら食券に統一する必要があるね。いっそ食券を発行して今のシステムを分散する形で混雑を解決するか

### レストラン側のメリットは？

回転率が上がるからこれだけでも需要あるのでは？追加で月の売り上げや購入数の多いメニューをランキング表示してくれるオーダーレポートを作ってくれる機能などつけると更に需要高まりそう

# 学食モバイルオーダアプリ-RunTicket-

<iframe width="966" height="543" src="https://www.youtube.com/embed/yxm0U-dOMCM" title="RunTicket 紹介ムービー" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

![IMG_20221213_223427.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275336/a3b37ddb-8fc9-8d81-60f5-511208832995.jpeg)



![web_mock_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275336/3350aa15-f0fd-7153-6cbf-1f5d436ff95e.jpeg)


![web_mock_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275336/5b0c56c7-b1ea-1cb0-452c-392de39be3fc.jpeg)

![IMG_2197.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275336/32c0d965-28b7-6cb9-48af-6cf71ebface2.jpeg)


![スクリーンショット 2022-12-13 1.55.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275336/54b6ace1-b063-ac27-b2ed-0d69e7010892.png)


# サービス概要

- 大阪工業大学 梅田キャンパス21階 菜の花食堂で利用を想定としたモバイルオーダーアプリケーションの開発および運用
- スマートフォン向けのWEBアプリケーション(PWA)で注文・決済を行い、現地に設置してあるキオスク端末にて食券を発行
- 購入されたデータを月末毎に集計し、月額の売り上げや各メニューのランキングを提供する。アプリケーションに表示されたメニューの内容は、予め読み込ませたメニューデータを基に夜間、システムが動的に書き換えを行う
- 任意にメニュー情報を変更する場合、メニューデータベースと連携したスプレッドシートの書き換えを行うことで変更が可能
- 現行の食券注文方式を採用することで店員側のオペレーションの変更はなし

# 技術スタック

- フロントエンド
    - React+TypeScript (SPA,PWA)
    - MUI
    - Emotion
    - Tailwind CSS
- バックエンド
    - Firebase
        - Hosting
        - Cloud Firestore
        - Storage
        - Authentication
        - Cloud Functions
    - Google Apps Script
    - Raspberry Pi
    - Node.js (Express)
    - Python (ESC/POS)
- 画面設計
    - Adobe XD

## システム全体のシーケンス図

```mermaid
sequenceDiagram
    %%{init:{'theme':'forest'}}%%
    autonumber
    actor User
    participant client as RunTicketApp
    participant backend as RunTicketBackend
    participant payback as PaymentBackend
    participant payapp as PaymentApp
    participant kiosk as Kiosk端末
    participant mise as 店側端末
		backend->>backend: Websocket Server起動
    mise->>mise: Websocket Client起動
    User->>client: メニュー選択
    client->backend: 在庫確認
    backend-->client: 
    client->>backend: 注文を送信
    backend->>backend: 注文データの保持
    backend-->>client: 完了ステータス
     Note left of backend:status:not_paid
    client->>backend:決済リクエスト
    backend->>payback: 決済URLの作成
    payback-->>backend: 決済フォームのURLを返却
    backend-->>client: 決済フォームのURL
    client-->>User: 決済画面の提供
    User->>payapp: 支払い情報の入力
    payapp->>payback: 支払い情報の取得
    payback-->>payapp: 
    payapp->>payback: 決済処理
    payback-->>payapp: 
    payapp-->>client:RunTicketAppへリダイレクト
    client->>payback:決済ステータスの取得
    payback-->>client: 
    client->>backend:在庫の更新
    backend-->>client: 
		client->>client:Websocket Client起動
    client->>backend:完了ステータス
    Note left of backend:status:ordered
    backend->>mise:注文即時通知;
    mise->>backend:料理完成;
    Note right of backend:status:cooked
    client-->>User:QRコードを表示
    User->>kiosk:QRコードを読み取り
    kiosk->>backend:ステータス書き換え
    backend-->>kiosk: 
    Note right of backend:status:complete
    backend->>mise:注文完了
    mise->>mise:完了済みの注文を削除
    kiosk-->>User:食券発行
```

## システム構成図(webアプリ側)


![UserClient_ad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275336/d6763b6c-c92c-2da7-d923-2d29cfd3611a.png)




## システム構成図(GAS側)

![menu (2) (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275336/7c977750-e8de-1ac6-de14-61c703274ea1.png)


# まとめ

３ヶ月間という短い期間でこれだけの工数掛かるものを開発するのはかなり大きな挑戦でした。また、チーム開発を行う上で、メンバーと話し合いながら仕様決定や問題提起などを行えたことはとても貴重な経験となりました。(自分たちで思い返してもよくできたなと思う)

ユーザはこちらが想定している仕様と異なる操作を行う可能性があるため、ユーザテストを行い、その結果を踏まえて仕様変更を度々行ってきました。仕様変更の怖いところはどれだけ小さな変更であっても該当ロジック以外のところにも影響を及ばすことです。

そんなこんなで初めのうちは仕様変更の嵐でしたが、何とか完成することができ、我ながら良いサービスができたと思います。現在、学食を運営されてる常翔ウェルフェア様とサービス運用に向けての面談を実施中です。本番公開は来年の春を予定していますので、公開されたらぜひ皆さんも使っていただけると幸いです！

# 関連リンク
https://product.run-ticket.com

# Contributor
https://qiita.com/Nikudanngo

https://qiita.com/Ronexy