Oh my teethの予約システム

こんにちは。

テックリードのTerukiです。

突然ですがOh my teethの予約システムの裏側を話したくなったので紹介。
バックエンドはASP.NET Core、フロントエンドはReactで作られています。

# なぜ自作したのか

予約システムはユーザーを待たせない歯医者には絶対に欠かせないものです。

昔はCalendlyという海外のSaaSを使ってシステム連携させていましたが、UIは英語なのと歯医者に特化しているわけではないのでUIや技術面、運用面で課題がありました。

https://calendly.com/

当時の予約画面

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192685/a10655fb-3a8e-4486-b39a-c51d5c417162.png" width="300">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192685/7d2bfca4-17b3-408b-a89a-4c71e2597e31.png" width="300">

シンプルなUIですが、英語が分からず電話が来ることがちょこちょこありました。

とはいえシンプルなUIで私達が求める機能を有しているサービスは当時は見つからず、ないなら作るか・・・！ということで開発プロジェクトが始まったのでした。

半年程度の開発期間を経て2023年の2月16日に無事リリースされました:tada:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192685/f18b10bf-4dd0-45a8-95d1-52677f89c4bf.png)

# デザイン

なるべく入力がスムーズでシンプルなデザインを目指していました。

Figma上でPC版、スマホ版を作成してみてよりシンプルにできるところがないかデザイナーさんと議論したのがもはや懐かしいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192685/38c11dbc-84d3-4734-bbfe-2fa1257e9c2e.png)

リリース後も複数回のABテストを行い今のデザインの予約システムに落ち着いています。

https://reservation.oh-my-teeth.com/scan?tags=qiita_reservation

# 実装

システム全体としてはバックエンドはASP.NET CoreでフロントエンドはReactのよくあるSPA構成で作られています。

## バックエンド

バックエンドはマルチテナントアーキテクチャになっていて、やろうと思えば外販できるような作りになっています。
予約数が増えても処理速度が落ちないよう、データベースのインデックス戦略をかなり考えて実装されています。

バックエンドはここが一番大変だったと言っても過言ではないです。

画面右下に過去24時間の予約件数を出していますが、これは本当にリアルタイムの予約数の数値です。

記事執筆時点
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192685/078a9f32-d4c7-45de-96bb-763872c915bd.png)

定期的に見ていたら結構リアルな数値変化をしているんじゃないかと思います笑
（検証していただくのは問題ないですがプログラムからのアクセスはお控えいただければ幸いです:pray:）


## フロントエンド

バックエンドもですがフロントエンドもスピード命なのでReact＋macaron-cssの構成にしています。

https://macaron.js.org/

macaron-cssはビルド出力としてcssファイルを出せるのが特徴です。

他のstyled-componentsなどはJSを経由してCSSを読み込むのでその分遅くなります。（もちろん量が少なければ誤差の範囲にはなるかとは思います）

Oh my teethでReactを本格的に使い出したのがこの予約システムで、それよりも前はVue 2でした。

私も実はこの予約システムで初めて本格的にReactを使いだしたのですが、開発体験が良すぎて感動していました。
HMRがない開発には戻れそうにないです:innocent:

# SPAミドルウェアが便利

Reactの開発をする時はほぼほぼviteを使うことになると思います。

最近のモダンなフロントエンド開発では、viteやその他諸々のツールで開発用サーバを立てて開発することになると思いますが、バックエンドはバックエンドで別のサーバとして起動してしまうので同時に開発する時にちょっと面倒です。

Oh my teethでは基本的にフルスタックな人が作業をするのでフロントエンドをバックエンドを同時に開発するという力技をやっています。

そこで、ASP.NET CoreのSPAミドルウェアの開発用機能を使うとバックエンドを経由してフロントエンドの開発サーバにリクエストをプロキシしてくれるので非常に捗ります。

Startup.csかProgram.csにて
```cs
    app.UseSpa(options => {
#if DEBUG
        options.UseProxyToSpaDevelopmentServer("http://localhost:5173/");
#endif
    });
```

上記の例はURLをハードコードしてますが必要に応じてappsettingsなどに書く感じが良いかと思います。

この設定を入れることで、バックエンドAPIへのアクセスは普通にバックエンドが処理し、バックエンド側にルートが見つからなかった時はSPAの開発サーバにプロキシしてくれます。

本番ビルドではASP.NET Core側のwwwrootへReact側のビルド成果物をコピーするようにしておけばOKです。

# おわりに

細部まで非常にこだわって開発したシステムなので今でも思い入れがあります。

当時予約システムを開発していた時は、フルタイムが私1人と副業のメンバー1人だけという超少数精鋭なチームで、今思えばよくやりきったなと思います笑

この記事では触れていないですが、予約枠を管理するための管理画面なども裏にあるため見た目以上に開発ボリュームがあるプロジェクトでした。

今後もこの予約システムの改修は続けていくので進化にご期待ください:pray:


# Oh my teethについて
[Oh my teeth](https://www.oh-my-teeth.com/?tags=qiita)では未来の歯科体験を創るために日々活動しています。

Techチームではより良いユーザー体験を提供するべく、Webフロントエンドからバックエンド、スマホアプリに機械学習モデルなど、さまざまなプロダクトを開発しています。

一緒に未来の歯科体験を創りませんか？興味がある方は是非こちらを確認してください。

https://oh.careers/

カジュアル面談も可能なので気軽に応募してみてください！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192685/0138b492-e02b-852e-61fa-fc065b53d285.png" width="450" />