ポートフォリオとして、If-Thenプランニングを活用した習慣化アプリを作成しました [Laravel / AWS]

# はじめに
### 記事の目的
**ポートフォリオとして作成したWebアプリケーションの紹介記事です。**

こちらのURLで公開中です。
https://rickeysan.com
また、Githubのコードはこちらです。
https://github.com/rickeysan/ifthen_plan_app

言語/フレームワークはPHP/Laravel、開発環境はLaradock、本番環境はAWS(EC2,RDS,S3など）を使用しました。

また、アプリ自体のご紹介のほか、開発過程についても触れていきます。


## 作成した人

- 2020年3月に都内の理系大学院（化学）を終了し、化学メーカーに生産技術職として入社
- 2020年5月から独学でフロント・バックエンドの学習を開始
- 働きながら勉強するのは大変でしたが、今ではプログラミングの面白さに魅了されています！！

目次は以下のとおりです。
[1. アプリの概要](#1-アプリの概要)
[2. アプリの特徴](#2-アプリの特徴)
[3. アプリの機能一覧](#3-アプリの機能一覧)
[4. 使用した技術スタック](#4-使用した技術スタック)
[5. 作成過程](#5-作成過程)
[6. 今後の課題](#6-今後の課題)
[7. 補足](#7-補足)


# 1. アプリの概要

**If-Thenプランニングを活用して習慣を挫折せずに継続できるWebアプリケーション**です。

If-Thenプランニングは目標達成術の一つで、【If】Xしたら【Then】Yするというものです
例えば、プログラミングを毎日3時間勉強するという目標があったとします。しかし、エラーに詰まってしまうと途中で投げ出してしまい、ダラダラとYouTubeをみてしまう。結局1時間しか勉強できませんでした。これはエラーが解決できないときにどう行動したら良いのかが決まっていないため起こります。ここで、下記のような自分ルールを設定します。
**「プログラミングの勉強に詰まったら、席を立って3分間体を動かす」**
このルールに従って行動すれば、勉強に復帰できる可能性は上がり、習慣の継続率が向上します。ある状況になったとき、この行動を取ると事前に計画しておくことで、スムーズにその行動を行うことが出来ます。
If-Thenプランニングの説明はここまでにしておきますが、興味のある方は検索するとたくさん情報が出てきます。

ざっくりというとこの習慣クックは、**自分なりのIf-Thenプランニングを見つけ、習慣を継続しようというコンセプト**です。しかし、このIf-Thenプランニングは知らない人が多いと思うので、開発しても使ってもらえない可能性は高いと思いました。後述しますが、このアプリではIf-Thenプランニングって何？、面倒臭そう、という壁を取り除くために工夫をしました。


## 2. アプリの特徴
###習慣の管理機能
達成したい習慣を新規登録できる機能を実装しています。このとき、If-Thenプランニングを設定します。また、習慣を編集、削除できる機能も実装しています。
![E648AC83-73C1-4BAC-A91C-8FF9046D707C.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1851421/6b4c423f-7513-d722-af7a-bc858d262246.jpeg)

また、カレンダー上でその日の記録（達成日or例外日）と簡単なコメントを残すことが出来ます。カレンダーの記録を振り返って、後からIf-Thenプランニングを自分なりにアップグレードしてもらうことを狙っています（例えば、自分は朝早起きに失敗したときにやる気を失ってその日のノルマを達成できていないという傾向がわかったら、「朝早起きに失敗したら、代わりに〜を行う」と新しいプランニングを行います）
![68EC1184-3303-4987-88AA-1DB62BE00DE7.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1851421/cc191256-1ae0-80dc-e48c-99e2c2730cf3.jpeg)

###習慣の検索・お気に入り登録機能
自分だけで考えてもなかなか答えが見つからないことも多いと思います。そこで、習慣の検索機能とお気に入り機能を実装しました。これで他の人が採用しているプランニングを参考にして、自分のプランニングをアップグレード出来ます。


## 3. アプリの機能一覧
現時点（2021年2月9日）で作成済みの機能は、以下のとおりです。
### メイン機能 :
- **習慣の登録**（CRUD処理）
- **カレンダー上での習慣の進捗記録**（CRUD処理）
    - カレンダーはFullCalendarプラグインを使用
- **絵本検索**（ページネーション）
- **お気に入り登録機能**
- **トースト通知**（toaster.jsプラグイン）
- **If-Thenプランニングのランダムジェネレーター**
- **プロフィール編集・閲覧機能**

### 認証機能
- ユーザー登録・ログイン・ログアウト
- パスワード変更
- プロフィール編集
- 退会


# 4. 使用した技術スタック
どのような技術を使って、どのような構成で作ったかについては、以下のとおりです。
[⑴ 使用技術](#-使用技術)
[⑵ インフラ構成図](#-インフラ構成図)
[⑶ DB設計](#-db設計)
## ⑴ 使用技術
使用技術については**フロントエンド**、**バックエンド**、**インフラ**で分けると以下のとおりです。
### フロントエンド
- **HTML**
- **CSS、Sass**
- **jQuery 3.6.0**
- **axios 0.19**
- **fullcalendar 5.10.1**
- **toaster 2.1.4**

デザインに関してはBootstrapなどのCSSのフレームワークがよく使われると思います。一方で、Bootstrapは導入するのは簡単だがカスタマイズが難しいという意見もありました。今回はデザインにこだわりたかったのと、BEMの練習をしたかったため、Sassのみで書きました。

### バックエンド
- **PHP**
- **Laravel 6.20.44**
- **MySQL**
- **composer**
- **PHPUnit**

Laravelの最新版はLaravel8ですが、LTSであるLaravel6を使用しました。

### インフラ
- **Docker 20.10.11 / Docker Compose 1.29.2 （開発環境）**
- **Laradock**
- **AWS ( EC2, ALB, S3, RDS, CloudFormation, Route53, IAM )**

開発環境に Docker / Docker Compose を使用しました。
AWSを本番環境で用いている理由は、クラウドサービスにも興味があり、求人情報で見ていても一般的と感じるため採用しました。

### その他
- **Git 2.34.1 / GitHub**
- **Sequel Ace**
- **Adobe XD**
- **VSCode**
今回は個人での開発になりますが、GitHubのIssueやPullRequestを活用し、タスクごとにブランチを切っては開発、プルリクエストしマージするという、擬似チーム開発を行うように意識しました。Gitコメントも自分だけが分かれば良いと思わずに、他の人が見てもわかるように心がけました。

また、Adobe XDを用いて画面設計を行いました。
![スクリーンショット 2022-02-09 16.47.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1851421/4a722dd4-090b-57ae-4f31-0414281d7369.png)



## ⑵インフラ構成図
- **本番環境のインフラ構成図です**
![Untitled Diagram.drawio (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1851421/f92e4e07-b081-14db-78b7-da840b78ef3c.png)

- 実践的な構成を意識しました（当然ですが、EC2サーバーを2つ立てているので、AWSの無料利用枠を超えています）ポートフォリオとして作ったアプリですが、自分としては今後も開発して多くの人に使ってもらいたい商品です。なので将来の拡張性を考えて、WebServerとRDSを一つずつ増築できる構成にしました。


# 5. 作成過程

## ⑴ 作成＆学習期間
### 作成期間（2021年1月初旬〜2月初旬）
Laravelでのポートフォリオ作成については、2021年初旬から制作を開始して１ヶ月強かかりました。制作にかかって時間をまとめていきます。
- **機能設計：5 h**
機能設計はさほど難しくありませんでした。If-Thenプランニングという目新しいコンテンツが盛り込まれてはいますが、原型はCRUD処理ができるアプリです。ユーザー管理の機能と習慣管理の機能を紙に書き出して完了させました。
- **画面設計：10 h**
XDの使い方に慣れていないこともありましたが、ここは意外と時間がかかりました。ここでは、各ページでのフォームの項目や表示する情報などを簡単に描いていきました。画面設計をしていくと、どのページからどのページへ遷移するか、このページではどのDBから情報を取ってくるかなどを整理することができ、後のコーディング作業の後戻りが少なくなった気がします。
- **画面デザイン：5 h**
使ってもらえるためにはある程度凝ったデザインにしたい（UI/UXにこだわりたい)と思っていました。しかし結局、デザインカンプは作りませんでした。ヘッダーやカード、ボタンデザインなどは必要なときに適宜サイトに合っていそうなものをチョイスしていました。色の種類については、Webサイトの配色サイトを利用して、最低限の統一感は出すようにしました。
https://www.palettelist.com/9de16f/53afff
また、サイトロゴはこちらのサイトを使わせていただきました。
https://hatchful.shopify.com/ja/
- **DB設計:5 h**
- **コーディング:140 h**
当然ですがここが一番時間がかかりました。以下、工夫した点と苦労した点をまとめます。
**工夫した点・苦労した点**
- **工夫した点**
**1.ランダムジェネレーターの設置**
習慣の新規登録画面で、習慣の期間や習慣にしたいことなどの他にIf-Thenプランニングを設定してもらいます。このアプリを初めて使う人は、If-Thenプランニングを入力してくださいと言われても難しいと思います。そこで登録画面では、プランニングを考える助けとして、ランダムジェネレーターを設置しました。これはIfの部とThenの部に別れていて、下にあるボタンをクリックすることでDBにあるランダムなフレーズが表示されます。出てきたプランニングをそのまま活用する必要はありませんが、これでプランニングを作るやり方を楽しみながら覚えてほしいです。

![D966E288-782D-4C9E-BCFA-4C3D92823BE5_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1851421/abf240ef-f7b3-0624-481a-516f699cb7e1.jpeg)

**2.コードの肥大化を最小限にする**
Laravelのコードを肥大化させないようにいくつか意識しました。具体的には、バリデーションにはフォームリクエストを使用しました。Bladeファイルでは親テンプレートを用意し、親テンプレートから継承してviewを作るようにて、ページで共通するデザインは使い回すようにしました。また、Route:resourceを使ってルーティングをコンパクトにまとめるようにしました。

- **苦労した点**

**1.FullCalendarの導入**
ここに一番苦労しました。英語を読むのは得意ですが、Jsの習熟度が浅く、プラグインのドキュメントから実装に落とし込むまでに試行錯誤しました。FullCalendarはDBに接続しなくても、イベントを書くこむことができますが、ページをリロードすれば消えてしまいます。FullCalendarで表示するカレンダーとは別に、入力と表示用のフォームを用意して値をlaravelに渡して保存するようにしました。また、カレンダーの日付をクリックした時のアクションとフォームの表示を違和感なく連動させることに苦労しました。
**2.AWSへのデプロイ**
AWSでは特に、ALBとWebServerへの連携で苦戦しました。最終的にはアウトバウンド・インバウンドルールが適切に設定できていないことが原因でした。Linuxコマンドもその時まであまり使ったことがありませんでしたが、このデプロイを通じて、linuxのフォルダ構成やコマンド、よく出てくるエラーメッセージと対処法などを覚えることが出来ました。また、デプロイ前にDNSやSSLサーバ証明書などを勉強していましたが、実際にドメインを取得し、Route53にレコードを設定することで、それらの理解も深まりました。

# 6. 今後の課題
**1.フロントにReactを導入して、アプリをSPA化する**
最初はフロントエンドはReactで実装しようと試みました。しかし、まだLaravel単体でアプリを開発したことがないこと、Reactを使うならTypeScriptを導入するべきという意見などを考慮して、とりあえずReactなしで制作することにしました。ある程度アプリが形になったので、ここからReactを使ってフロント部分を書き直していきたいです。
**2.ランダムジェネレーターの表示処理**
今のランダムジェネレーターは、専用のテーブルに私が考えたフレーズをランダム関数で表示しているだけです。もっと発想の幅を広げてもらうために、お気に入り数の高いプランニングを表示したり、何かAPIから単語やフレーズを取ってくるなど、高度な処理を実装したいです。

# 7. 補足
Laravelでのアプリ開発の前に、同じコンセプトのアプリをPHPのフルスクラッチで製作しました。バックグラウンドの処理は完成していたのですが、デザインが崩れており、お見せできるものではないので、ここでは公開しません（一応、デプロイはしてあります）。供養のためにGithubのコードだけ載せておきます。
https://github.com/rickeysan/rakusyu_app