[個人開発]実際に飲食店で使う予約サービスを実務未経験者が１から考え作ってみた。

# はじめに

この度、実際に飲食店で使っている予約サービスをリリースしました！

##### サービスを作ったきっかけ
私が以前手伝いをしていた個人経営の小規模な飲食店では事前の来店数を把握したいが予約受付は営業時間内の電話のみ。予約来店が少ないという課題を実感していました。
その解決策として、お店の要望に沿った予約サービスを開発しました！


実際に使えるような予約システムの参考資料がなく苦労しましたが、初心者なりに１から考え、実装してみました。

# サービス概要
一般ユーザーの予約来店を促し、管理ユーザーの業務効率化を図るサービスです。


https://www.lunchcafeocean.com/

こちらは公開用のサービスです。
実際に使っているものと機能は基本的には同様です。

![Home画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1870530/6e19c4d4-a66c-daf3-fe67-5815f14a7b6d.png)


ゲストログインボタンからは管理画面にアクセスでき、機能の確認が行えます。
実運用のサービスは個人情報が含まれるためここでは公開しておりません。

#### 一般ユーザー
- Web予約より日付、人数、時間を指定して予約ができる。
- 管理画面より投稿されたメニューやキャンペーン情報を確認できる。

#### 管理ユーザー
**予約管理**
- Web予約に限らず、その他予約(電話・SNS)も一括で管理できる。
- 予約の確認、予約上限人数の変更、キャンセル、変更処理を行える。

**その他**
- お知らせの投稿
- メニューの投稿
- お問い合わせの確認
- 業務効率化機能(リマインダー等)


# 使用技術
### バックエンド
- Ruby 2.7.3
- Rails 6.0.3.7
- Rubocop
- RSpec
### フロントエンド
- HTML
- CSS(SCSS)
- JavaScript(jQuery)
- bootstrap4
### 主なGem
- gem 'sorcery'
- gem 'simple_calendar'
- gem 'carrierwave'
- gem 'kaminari'
- gem 'ransack'
- gem 'enum_help'
- gem 'rails-i18n'
- gem 'meta-tags'
- gem 'slack-notifier'
- gem 'gretel'
### インフラ
- Heroku
- PostgreSQL
### その他ライブラリなど
- Admin LTE
- Toastr
- Slick
- JqueryValidation
- GoogleMapAPI


# 工夫した点

#### 要望に応じたサービス作り
デザインや配色のフロントエンドから予約システムのバックエンドまでこのサービスの要望を伺い、要望に応じたサービスを作りました。
予約システムについて、勤務する店員の人数にバラつきがあり提供できる食事数が日によって変わる場合があるため予約の上限を管理画面から行えるシステムを作成しました。
リリース後も「このような機能があれば便利」などの要望を伺い、追加機能を実装しております。

#### 予約までの動線
- どこのページからでも3クリックで予約完了となるようにしました。
- フォームでは`JqueryValidation`を導入しフロントで送信前にバリデーション判定を行い、確認画面を自作することで個人情報入力や人数、時間など情報を間違えないようにしました。
**フォームに確認画面を挟む**
[![Image from Gyazo](https://i.gyazo.com/9263609de2930ab4424604e113efea91.gif)](https://gyazo.com/9263609de2930ab4424604e113efea91)
**バリデーションを即時表示**
[![Image from Gyazo](https://i.gyazo.com/e1b0aa99384d12b7f36d2ae790ddd646.gif)](https://gyazo.com/e1b0aa99384d12b7f36d2ae790ddd646)

#### 直感的に操作できる管理画面
誰でも直感的に操作しやすいように、管理画面を作成しました。
管理画面もレスポンシブ対応にすることでPCに慣れていない人でも簡単な操作を追求。
予約をカレンダー管理にすることで簡単に予約の確認、編集操作ができます。
[![Image from Gyazo](https://i.gyazo.com/9188ec60892ab46c10437137eba896a8.gif)](https://gyazo.com/9188ec60892ab46c10437137eba896a8)

#### 予約処理
このサービスの肝となる部分です。
コントローラーのロジックについてははこちらの記事に書かせていただきました。

https://qiita.com/TakeKata/items/953ddc4137741595d7d8


1. **設定以上の予約人数があると新規の予約できない。**
予約システムで一番重要なポイントです。
突然、予約が殺到し一気に日に100件、1,000件、10,000件など来てしまったら？
可能性は極めて低いが起こりうる事象です。
実運用する際には欠かせない機能です。



2. **削除とキャンセルを区別。**
キャンセルになった際に削除してしまうと履歴がなくなってしまいます。
そこで、キャンセル処理を１クリックで可能にし、ステータスの変更、予約上限を元に戻す処理を一度に行えるように作成しました。

3. **予約変更処理を簡単に。**
実装していて予約システムで一番複雑な部分でした。
フロントでは予約に関する人数や日付を変更するだけですが、実際に変更されるデータは予約だけでなく、日時や人数変更前の上限戻し、変更後の上限も変更なども含まれます。
手動で全てを処理するのは手間なので予約の変更のみで全ての処理が行われるようにしました。



### 効率化のための自動化
**Slack通知**
- **予約時に即時通知**
営業前に管理画面をから予約を確認する手間を削減しました。
- **営業日当日に予約件数を通知**
営業前に当日の予約件数を自動で通知。予約の確認忘れを防止します。

**ステータス変更**
- **管理画面から休業日を設定**
管理画面より、日にちのステータスを変更するだけで休業日に設定し、設定日の予約を受け付けないバリデーションを付与できます。
- **営業終了時間に当日の予約のステータスを「来店済み」に自動で変更**
自動でステータス変更することで管理の手間を削減しました。

今後も業務効率化のため自動化できる部分を考え、実装していきます。

### セキュリティ対策
実際に運用しているサービスではセキュリティ対策をシビアに捉え対策を行いました。

1. **管理画面のログインページに辿り着かせない。**
調べていく中で多くの予約サイトが`/admin`で管理画面に辿り着きました。(主にWordPress)そこで、実際に運用してるサービスでは管理画面のURLを`/admin`では辿りつけなくしました。

2. **ログイン画面に辿り着いたとしてID/パスワードを破らせない。**
ID/パスワードが流出しない前提で、破られる場合はブルートフォルスアタックが考えられます。
そこで`gem 'sorcery'`のオプション機能を使い一定回数のログインが失敗すると一定時間ログインできないようにしました。

今後もできる対策は追加したいと考えています。

### SEO対策
実際に運用していく中で実店舗での周知やSNSからの流入を考え実施しておりましたが、新規顧客獲得のためにSEO対策は必須と考えました。
- GoogleSearchConsoleの導入
- ページタイトルの設定
- description,OGPの設定(`gem 'meta-tags'`の導入)
- サイトマップの作成(`gem sitemap_generator`)
etc...

##### 平均掲載順位が`80位⇨25位`まで上昇
##### 検索ワード`地名(実店舗のある)　カフェ or　ランチ`での順位が3位以内

SEO対策を行ったことにより改善されています。

# 今後追加したい機能

常にフィードバックを貰いながら改善を続けていますが、今後このような機能の追加を考えています！！

- ネットクーポン機能
- ~~管理画面で動的にバリデーション(予約不可)設定する機能~~ (導入済み)
- ~~管理者への予約リマインダー機能~~ (導入済み)
- ユーザーへの予約リマインダー機能
- ~~ステータスの時間経過による自動変更~~ (導入済み)
- セキュリティの強化
- SEO対策の強化

# おわりに

現在も日々改良中ですが、プログラミングを始めた目的の一つが達成できてました！

初めて予約通知が来た時は涙が出るほど嬉しかったです！！

実際に世の中で使われているシステムと比べると不都合があったり、修正や改善すべき点が多々あることも認識しています。これからも技術を追求しより良いサービスを作ってように頑張ります！

サービスは自分の作りたいように作り、こうすれば便利だろうなと思って作ってみても、実際に他の人からそう思ってもらえるとは限らないと実感し、実際に使ってもらうと「ここが使いづらい」「よく分からない」「こういうのあれば便利そう」など貴重な意見をたくさんもらえるのでありがたいです。

最後までご覧いただきましてありがとうございました！

https://www.lunchcafeocean.com/