Next.js(TypeScript), Rails, Docker, Vercel, AWS ECS(Fargate), Github Actions, Terraformを使用してポートフォリオを作成しました。

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


# 開発アプリ概要

#### アプリ名: 近所の人たちと家で余っている食べ物をシェアするアプリ「Mottainai-zerowaste」
家庭内で発生するフードロスを解決するために作成したWebアプリです。

### 使用技術
- Backend<br>
  - Rails 6.1.4.4（API mode）<br>
  - Ruby 2.7.2<br>
  - Nginx<br>
  - Puma<br>
  - PostgreSQL 13.4<br>
  - RSpec<br>
  - Rubocop<br>
- Frontend<br>
  - Next.js 12.1.0<br>
  - React 17.0.2<br>
  - Typescript 4.5.5<br>
  - Tailwind CSS 3.0.23<br>
  - Jest 28.1.0<br>
  - React Testing Library 12.1.5<br>
  - ESLint / Prettier<br>
- Infra<br>
  - AWS（ECS Fargate/ECR/RDS/ALB/Route53/ACM/VPC/SSM/S3)<br>
  - Vercel <br>
  - Docker 20.10.12<br>
  - docker-compose 1.29.2<br>
  - Github Actions（CI / CD）<br>
  - Terraform 1.2.6<br>

### インフラ構成
![mottainai-zerowaste.diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/3790b91a-885f-3e30-f0bd-49cd3fea89c5.png)


### 機能一覧
##### ユーザー利用機能
- ユーザー関連機能<br>
  - 新規登録<br>
  - 登録内容変更<br>
  - アバター投稿<br>
  - 現在地を登録（これをすると自分の家から近い投稿をソート機能で表示できる）
  - ログイン、ログアウト<br>
- 投稿機能<br>
  - Google Map APIを用いて、近所の人たちにシェアしたいItem(主に食べ物)を投稿する<br>
- オファー機能<br>
  - ユーザーがシェアした投稿に対するオファー<br>
- オファーに対する承認/拒否機能<br>
  - 投稿した食べ物を渡す相手を決められる<br>
- チャット機能<br>
- レビュー機能<br>
  - Itemをあげた側と貰った側が相互にレビューできる<br>
- ソート機能<br>
  - カテゴリ（Food or Non-Food）、新着順、距離が近い順<br>
- 検索機能<br>
  - 投稿されているItemのタイトルで検索ができる（例えば、クッキーなど）<br>
- 通知機能<br>
  - 投稿に対するオファーが来た時<br>
  - オファーが承認/拒否された時<br>
  - レビューがされた時<br>
  - チャットでメッセージが来た時<br>
  
- Route53 による独自ドメイン + SSL化
- レスポンシブ対応
 
##### 非ユーザー利用機能
- puma-socket通信によるRailsのNginx配信<br>
- Docker による開発環境の完全コンテナ化<br>
- Github Actionsによる自動 CI/CD パイプライン構築<br>
  - CI: Rspec, rubocop, eslint&prettier<br>
  - CD: AWS ECR (Rails)<br>
- TerraformによるAWSのインフラのコード化<br>


### Usecase図
Giverは家に余っている食べ物をあげる人。Receiverは食べ物を貰う人。
UserはGiverにもReceiverにも両方なれる。
※ユースケース図U01に「主に食べ物」と書いてあるのは、食べ物以外も一応投稿出来るため。
![Usecase-mottainai.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/55a95325-80fc-bca8-69f5-f4d5335e6f14.png)



### WebアプリケーションのDemo
##### ログイン
![Login.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/c984cb87-46ea-6936-1782-4b9a3dbc6fcf.gif)

##### ログインなしでメッセージ機能とオファー機能を使用しようとした時
ログイン画面にリダイレクトされる。

メッセージしようとした時
![Without login-click message button.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/b52ebbfe-b35b-dee1-659f-8fa3fc43cb0a.gif)

オファーしようとした時
![Without login-click request button.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/ef44ed91-f5e4-83f2-9b54-c772c83508a4.gif)

##### 投稿する
![Post an item.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/d9ea46fb-159c-26d7-ad39-61966a4c2f5f.gif)


##### オファーをする
![Request function.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/4ace2436-8ef6-fc7d-c4be-83a70bc628c1.gif)


##### オファーを承認する
![Accept an offer.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/59f7e00e-dae3-9109-43eb-fc995ffd7e43.gif)


##### オファーを承認された時
![The offer is accepted.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/5a87d998-9b36-6d75-62a4-852470167087.gif)


##### メッセージをする
![Message function.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/bf74bc03-7825-dfb5-d67f-611fb81733ee.gif)

##### メッセージとオファーされた時の通知一覧
通知一覧から会話一覧に遷移可能。
通知一覧からオファーの詳細に遷移可能。
![Check notifications of new message and offer.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/a0b21ff0-9a06-3126-e62c-2fc07dceb180.gif)

##### レビューを書く
これはGiverがReceiverにレビューを書く例。
![Giver write a review to receiver.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/df89dbad-f068-7686-fb8e-b15de40c3d53.gif)



##### 新しいレビューが追加されたかをプロフィールから確認する
Giverが書いた新しいレビューがReceiverのプロフィールに追加されている。
![New Review is added to profile.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/7aeb70b2-07b3-db42-3c0c-e78754f218ec.gif)

##### 検索機能
Itemのタイトルで検索可能。
![Search function.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/47072040-af9a-0a58-3254-6ca6ac73fce7.gif)

##### ソート機能
- カテゴリ（Food or Non-Food）、新着順、距離が近い順<br>
Userがプロフィールから自分の位置情報を登録している場合、距離が近いItem順に表示させるソート機能が利用可能。

![Filter function.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035396/66f90c47-47d6-4aca-6314-1ba90909fa47.gif)