【個人開発】シフト自動作成サービス作ってみた。ソースコード同時公開【React/Remix】

こんにちは。
以前に[こちらの個人開発記事](https://qiita.com/Hizuraky/items/0b4e4e7daf595326e006)を公開してから4ヶ月が経ちました。

> 全てのドキュメントとソースコードを公開します！！

なんて粋がっていまだに公開していません。申し訳ございまメン。
円安でAWSの請求がキツくなり、非公開にした頃には当開発を初めており、こちらに熱中していました。
まず、今回は記事公開と同時にコードもそのまま公開しています。

# はじめに
個人開発をする上でどのような理由で行うのか、大きく以下の2つに分類されると思います。
- **利益のため**(開発したものを通して直接的な利益を得る)
- **学習のため**(学習してポートフォリオとして残すことで自身の市場価値を高める)

Qiitaに記事をあげている方は後者が多いと勝手に思い込んでおります。
私の個人開発も後者です。
なので、「どのようなサービスで、どのような背景で、どのようなことを意識して」みたいなことが今回はあまり書きません。
あとテストは試験書を作らずにスマホとPCでサラッと一通り見て、ちょちょっと修正した程度なので普通にバグでると思います。すみません。

まず今回作成したものがこちらです。

https://shift-maker.vercel.app/login

ソースコードがこちらです

https://github.com/Hizuraky/shiftmaker

タイトルにシフト自動作成サービス的なノリで書きましたが、若干タイトル詐欺ってます。半自動といった感じです。
1. 従業員と勤務時間の情報を入力する
2. 自動生成した後に、最後に手動で調整して作成する。
の流れです。

以下は「シフト作成」の一連のキャプチャを撮りましたが、平成初期の無料掲示板レベルの画質でお届けしてみます。雰囲気だけ感じてください。
9人分のシフトがあら不思議1分で完了しました。
こちらのgifでも9MBくらいあってさらに高画質はqiitaに入れれなさそうでしたのですみません。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527842/cb9badb3-015e-5463-f1ae-6612c510bcfd.gif" width="100%">

今回作るきっかけが、母親がいわゆるマネージャー的なことをしており、そこでシフトの作成に苦労しているとのことでした。
エクセルで作成していて、既存のフォーマットを見たところかなり残念な状態だったので、VBAでボタンを押すと自動でシフトを埋められるようなものを作りましたが、VBAは得意ではないのであまり納得の出来ではありませんでした。
そこで Remix + GraphQLを使用して何か個人開発がしたいと思っていたので今回の開発に至りました。



# 使用技術・サービス
今回の成果物のイメージはこのような感じ。
![スクリーンショット 2022-09-22 16.40.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527842/4249cd2b-2b64-13fd-4d8f-7037a3023820.png)

#### [Remix](https://remix.run/)
昨年11月のリリースされたReactのフレームワークです。
選定理由としては、Nextjs以外でReactのフレームワークを使ってみたい + 日本語の情報が少なく新しめなもので何か作ってみたかったためです。
NextjsとRemix両方で開発してみましたが、次どちらかで開発をするなら要件次第ではありますが多くの場合はNextjsを選ぶ気がします。
ただどちらも素晴らしい技術で、create-react-appでプロジェクトを作成して開発することはもうあまりないのかなと思わされました。
create-react-appで作成する場合は特段理由がなければまずWebpackではなくViteを使った方がいいと思います。
Remixについての詳細はリンクよりドキュメントを参照してください。

https://remix.run/


#### [vercel](https://vercel.com/)
Hostingに使用。
選定理由はRemixでプロジェクトを作成したときにデプロイ先にVercelの選択肢があったため。

https://vercel.com/

#### [firebase](https://firebase.google.com/?hl=ja)
ユーザーの認証に使用しました。
アプリ上でユーザー登録があると、cloud functionが動いてpostgres内にもユーザーが作成されるように実装してます。
firebase経緯でのみhasuraでユーザーが作成可能でAdmin権限を持たせてないフロントからはユーザーを作成できないようにしてます。
postgres内にはfirebaseで作成されるuidと登録日時のみを保存してユーザー名やメールアドレスなどの情報は全てfirebase任せです。

https://firebase.google.com/?hl=ja

#### [Hasura](https://hasura.io/)
DBを連携すればGraphQLサーバーを自動で立ててくれる。
- Resolverの実装不要
- テーブルやカラムはHasuraのGUI上で作成できる
- Dockerイメージが配布されている
- 無料枠が用意されている
- DataLoaderなどを使用してn+1問題に対応する必要がない。

すごく使いやすかったです。
GraphQL初心者の私にはとてもとっつきやすいサービスでした。

が、少しデメリットもあります。
- 有料版は99ドル ~ と割高
- 無料版はリージョンの選択ができない。
- リージョンのせいなのか、レスポンスが300ms~4000msくらいと波が激しめ。
- デフォルトでpostgresが選択されており、Herokuとの親和性が高いが、Herokuの無料が廃止されるので。。。

あくまで無料版は個人開発やテスト環境などに留めるのが吉な印象です。

https://hasura.io/


#### [Heroku](https://id.heroku.com/)
無料のpostgresqlを使用。
スリープモードに入るのを防止するために一応heroku scheduleを10分に1回走らせてます。
Herokuの無料プラン廃止が発表された頃には時すでに遅し。方向転換できる状態ではなくそのまま公開。
他の選択肢として、Hasura + Herokuではなく[Fauna](https://fauna.com/)使ってみたいなとは思いました。

https://id.heroku.com/

https://fauna.com/

#### [Apollo](https://www.apollographql.com/docs/react/)

GraphQLのクライアントサイドのライブラリ。
選定理由としてはGraphQLについて色々調べているとよく出てきたためです。
axiosだけでも実際いいのですが、キャッシュができたりと何かと便利ではあります。
> Apollo Client is a comprehensive state management library for JavaScript that enables you to manage both local and remote data with GraphQL. Use it to fetch, cache, and modify application data, all while automatically updating your UI.
----以下翻訳-----
Apollo Clientは、ローカルとリモートの両方のデータをGraphQLで管理できるJavaScript用の包括的な状態管理ライブラリです。UIを自動的に更新しながら、アプリケーションデータのフェッチ、キャッシュ、変更に使用します。

ただ、キャッシュがあってもQueryの時には一度データはundefinedになります。
SWRはGetの際にキャッシュがあればそのデータを返してくれるので、SWRに慣れていると少し不便に感じました。
今回の開発に限って言えばapollo cientは比較的バンドルサイズも大きかったり、あまり多機能な部分をいかせてないのでミスった感があります。

https://www.apollographql.com/docs/react/



# 設計関連
開発に関するドキュメントは一切用意しませんでした。
以前の個人開発はゴリゴリにドキュメントを作成しましたので、何もない状態で作成するとどのようになるのかを体験してみたかったから + 早く開発に移りたかったからという理由からです。
Figmaでイメージだけ4,5画面作成しましたが、ヘッダー、フッター、タブ、カラー以外は途中でほとんど変更になりました。

#### DB設計
DB設計は以下の感じです。
![postgre.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527842/21a6248b-9674-b009-cce7-a86c616c308c.png)

勤務時間・従業員などは複合PKにしてます。
開発当初[employee <> workingTime]、[shiftEmployee <> shiftWorkingTime]の間に中間テーブルを入れてましたが、Heroku無料枠の1万レコードを圧迫する原因になるので、中間テーブルは廃止してint4カラムを用意したりなどなど開発中に変更していきました。
~~命名は本当に終わってます。~~

# 開発を通じて
今回の開発を通じて何を学んで、何を思ったのか。

#### 学び
- Remixを通してSSRやSSGについてのより深い理解
- GraphQLについて
- Hasura,Fauna,Heroku,firebaseなどのサービスについて

#### 所感
- 命名が適当すぎると本当にわからなくなる
- 設計がほとんど無いと個人開発でも手戻りが頻繁に発生する
- 個人開発はやはり勉強になる

GraphQLは過去にチャット機能部分だけをGraphQLとDynamoでやったことありましたが、しっかり目に使うのは今回が初めてでした。
GraphQLを使ってみて思ったのは、[HasuraのRESTとGraphQLの比較ドキュメント](https://hasura.io/learn/ja/graphql/intro-graphql/graphql-vs-rest/)にも記載されてますがAPIのためにサーバーを立てて開発といった作業は減らせるので高速な開発ができるという印象も強いですし、サブスクリプション機能も便利だと思いました。
やはり慣れが必要で、また使うかどうかはその時の要件次第といった感じだと思います。
データを整形したり計算したり等々のバックエンドで処理する部分もフロント側である程度実装が必要になるのでコードが煩雑になりやすい気もしました。(NextjsやRemixにもあるapiルートをちゃんと使えば良いって話なんですけどね)
終わってみて思うのは今回の開発においては、mongoDBのようなドキュメント指向のDBが合ってるような気がしました。(なんとなく

firebase以外はほとんど初めて使うものばかりで調べるのに膨大な時間がかかりましたし、エラーも5億回くらい遭遇しました。
が、自分が実装しないと進めないので、出来ないと色々と調べて試行錯誤しての繰り返しが自分を成長させてくれてると思います。
私が個人開発を公開したのは3回目(2020年11月と2022年5月と今回)ですが、いずれも転職や昇給などで良い方向に作用してる気がします。(あくまでそんな気がするだけですが。
皆さんもぜひ個人開発をしてみては、、、！

※あくまで個人開発で趣味の範疇なので、バグやソースコードに対するツッコミはそっと心の中に留めておいていただけますと幸いです。

余談ですが8月28日に第一子が誕生しました🤭