未経験からのエンジニア転職に向けてSpringBootとReactでシフト管理サービスを作成してみた

## はじめに
2022年2月からプログラミング学習を始め、2022年7月現在まで半年近くが経ちました。
未経験からの転職活動にあたってポートフォリオ用にWebアプリケーションを作成したので、機能の紹介とハマった点などをご紹介します。
同じように未経験から転職する際にポートフォリオを作成する方向けに参考になれば幸いです。

## アプリ概要
シフト管理作成サービス「E-Shifty」を作成しました。
ラク(Easy)にShiftを管理できることを目指し、主な機能は以下のとおりです。
- 各従業員のログイン機能
- 従業員情報の管理や新規登録ができる
- シフトを確認できる
- 来月分の休み希望を提出できる
- 管理者は提出された休み希望を元に半自動でシフトを作成できる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602113/5a0e8183-0c5b-2b37-e2ad-e7d6c3d45ad6.gif" width="60%">

## 作成背景
シフト制のフルタイムで働いている妻が頻繁にシフトに関する愚痴を言っていました。
「シフト作成が遅い」
「シフトが偏りすぎている」

円満な家庭のためには妻のストレスに気を使うことは欠かせません。
世の中にシフト管理サービスは多く存在するのですが、妻の職場は従業員の出勤状況やその日によって複雑に動きが変わります。
そのため、自動でシフトを作成した上で、手動で簡単に修正できる裁量を残した半自動のシステムが良いのではないかと考え作成にいたりました。

## 主な使用技術
#### バックエンド
- Java 17
- SpringBoot 2.7

#### フロントエンド
- React 17.0
- TypeScript 4.4
- chakra ui 1.2

#### インフラ・DB
- docker
- AWS(EC2, S３, Route53, ALB)
- MySQL 5.7

#### [SwaggerによるAPI仕様書](https://swagger-url.vercel.app/?url=https%3A%2F%2Fraw.githubusercontent.com%2FTomooAkamatsu%2FE-Shifty%2Fmain%2Fswagger%2Fopenapi.yaml#/)

#### E-R図
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602113/1eefca3d-ad23-d4b4-a94c-2ebad5d88bb9.png" width="70%">

#### URL一覧
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602113/957fee09-3ef3-6898-89a4-24d852becc3a.png" width="60%">

#### 画面遷移図(管理者)
※ゲストログイン時も管理者での想定でログイン処理を行っております
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602113/f278a039-02d8-e827-538d-6793e6242a28.png" width="70%">

#### 画面遷移図(従業員)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602113/64ec9d58-9b1f-676a-4d04-4e64edbf2eed.png" width="70%">

#### インフラ構成図
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602113/e5afa007-84f0-038b-179f-aa9f669cb071.png" width="70%">


## 使用イメージ


#### シフト確認画面と休み希望提出
- シフトを月毎に確認できる
- 各従業員が翌月の休み希望を提出可能
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602113/4be78dcc-8e3b-2c01-581d-199816df989a.gif" width="60%">


#### 従業員管理
- 従業員一覧をカードで一目で確認できる
- 従業員詳細情報はモーダルから修正可能
- 新規登録や退職処理も実装
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602113/d0865091-9190-4233-46b6-090e3c45d4dc.gif" width="60%">

#### シフト作成
- 土日と休み希望日には休みを入れる
- 1日のうち早番(A)と遅番(D)に正社員を一人ずつ
- 残りのB,Cをランダムに振り分ける
- 手動で調整可能かつ、作り直し機能も実装
- 提出された全従業員の休み一覧も確認できる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602113/a55cfffa-7148-2f22-61b8-c58635abf4bb.gif" width="60%">

## ハマった点
#### API設計
そもそもどういったAPIが適切かつフロントで処理を行いやすいのかが分かりませんでした。
ただ、いくら調べて考えても経験が無いため、ひとまずフロントとバックを同時に進めながら設計についても随時修正していく形で進めました。
API設計の重要さを改めて実感するとともに、綺麗なAPIを設計できるバックエンドエンジニアを目指します。

#### シフト自動作成のロジック
休みを反映し、決められたシフトパターンの条件を守りながらシフトを自動作成するというものです。
言葉で説明するとなんてことはないのですが、従業員数が変動した場合や後述の月毎の日数がロジックを難しくさせる要因の一つでした。

1. 土日に休みを入れる
2. 休み希望に休みを入れる
3. 営業日には早番と遅番(A,D)に出勤可能な正社員をランダムに一人ずつ割り当てる
4. 出勤可能な従業員の勤務形態に関わらず、残りのシフトパターン(B,C)を均等になるようランダムに割り当てる

"従業員数×シフトを作成する月の日数"のサイズを持つListに、従業員と日付とシフトパターンをフィールドに持つEntityクラスを上記の順につめていくようなイメージです。
最初に大まかな流れを考え、実際にコードを書いてデバッグ機能で中身を見ながら実装を行いました。

パフォーマンスはもっと改善しようがあるとは思うのですが、現状私の知識と技術ではこの方法しか思い浮かびませんでした。
文法としては繰り返し処理やコレクション、StreamAPIあたりです。

今回は上記のパターンでシフト作成を行っておりますが、現実的にはこのパターンを手動で調整できるよう今後実装していきたいと考えております。
従業員人数を増減させても上記のパターンでシフトが作成可能ですが、組み合わせが無く作成ができなかった際のハンドリングは未実装です。

## 今後の展望
- JUnitによる単体テスト(現在一部のクラスのみ実装)
- GitHub Actionsの導入
- シフト作成失敗時のエラーハンドリング
- シフト自動作成のパターンを手動で設定できる機能の実装
- AWS ECSを用いたDockerコンテナ運用

## 感想
至らない点は多々ありますが、ひとまず形にはなったかなと考えています。
形になるかどうかも分からないレベルからのスタートで、環境構築からデプロイまで挙げればキリがないほど色々ハマったのですが、一つずつ状況を整理してひたすらトライアンドエラーを繰り返すことで乗り越えることができました。
その中で少しずつできることが増え、技術を学ぶ楽しさとアイデアを具体的に形にできる喜びを実感しています。
まだまだやれることはたくさんあるので転職活動と並行して進めていこうと思っております。

転職活動がひと段落したらフィードバックなども記事にしようと思います。
ここまで読んでいただきありがとうございました！