【Webアプリ編】ポートフォリオの紹介

## 記事の概要
ポートフォリオの概要やどのような技術を使ったかなどを説明した記事です。

解説する内容は以下の通りです。

- アプリの概要
- フロントエンド
- バックエンド
- データベース
- インフラ（クラウド）
- 機能/操作方法
- ラクマネイングリッシュを開発した理由
- これから実装したいこと

## アプリの概要
![rakumane_top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/94196b83-ea4d-3bfe-05d2-bcb9782d55ab.png)

概要では以下の内容を解説します。
ポートフォリオ：[ラクマネイングリッシュ](http://e-rakumane.com/)
GitHub：https://github.com/Takapon2512/rakumane

- アプリ名と名前の由来
- アプリの強み
- 開発期間

### アプリ名と名前の由来
アプリの名前は「ラクマネイングリッシュ」で、ユーザーが楽に英単語の管理ができるということからその名前をつけました。

### アプリの強み
このアプリでは、英単語の登録や学習の記録、その日やるべき単語を示すことができます。
どの単語を学習すべきか迷う必要や学習を記録する手間がかかりません。

### 開発期間
2023年7月5日 ~ 2023年11月7日
つまり、要件定義からリリースまでで、約4ヶ月です。

## フロントエンド
使用した技術は以下の通りです。

- HTML
- CSS（Sass）
- Material UI
- JavaScript（React, Next.js, TypeScript）

## バックエンド
使用した技術は以下の通りです。

- JavaScript（TypeScript）
- Node.js（Express）

## データベース
使用した技術は以下の通りです。

- MySQL

## インフラ（クラウド）
使用した技術はAWSで、利用したサービスは以下の通りです。

- IAM
- VPC
- EC2
- RDS
- Route 53

### ネットワーク構成図
今回のアプリで構築したネットワークは以下の通りです。

![rakumane-aws.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/84380d45-0ab3-fbb5-8270-68dbd666ece3.png)

このネットワーク構成にした理由はコストを優先したからです。
当初は、可用性が高いマルチAZやデータベースのフェイルオーバーを考えていました。

しかし、無料利用枠を超えることや公式の料金表から支出が多いと判断し、シングルAZを採用しました。

パブリックサブネットにEC2インスタンスを1つ配置し、データベースはインターネットから見られないようにするためにプライベートサブネットに配置しました。

## 機能/操作方法
機能は以下の通りです。

- 新規登録
- ログイン
- ログアウト
- 単語を登録
- 単語を削除
- 本日の単語の登録
- 暗記カード
- 単語テスト
- フリーモード
- 記録
- 設定

### 新規登録
![rakumane1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/a68160bb-f0d3-3c12-5908-e7c3cb9b9d06.png)

新しくユーザーを登録する際に必要な情報は、以下の通りです。

- メールアドレス
- ユーザー名
- パスワード

メールアドレスは一意のものでなければならないので、すでに登録されているメールアドレスで新規登録しようとするとエラーになります。

パスワードは、漏洩リスクを減らすためにハッシュ化した後にデータベースに登録される仕組みになっています。

### ログイン
ログインの際に必要な情報は新規登録と同じ情報が必要です。

メールアドレスとパスワードが一致しているかを確認し、問題なければJWTトークンがユーザーに発行されます。
このトークンは4時間だけ有効なので、時間が過ぎると再度ログインが必要です。


### ログアウト
![rakumane2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/b40eeb4c-eab3-1384-6195-3f0aa0dbf4b3.png)


ログアウトが成功すると、ユーザーに渡したJWTトークンが消去されますので、再度ログインするまでマイページにアクセスできません。

### 単語を登録
![rakumane3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/bd553784-27ee-675e-25de-4c403f4d6f38.png)

マイページのホームで、英単語と日本語を登録できます。
対象の英単語を一目で確認しながら登録できるように、10単語ずつの登録になっています。

誤って入力した単語は対象の単語をクリックすると、編集や削除できます。

#### 操作方法
1. 英単語と日本語訳を入力する
2. 「登録リストに追加」もしくはEnterを押下する
3. 登録リストにある単語をデータベースに登録するかを確認してから「本登録」 を押下する

登録完了のアラートが出力され、登録リストが削除されたら登録が完了しています。
登録を確認する場合は、フリーモードもしくは記録のページで確認してください。

### 単語を削除
![rakumane4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/c390917a-4846-6d70-04e2-c84d85e54da9.png)

記録のページで、単語を編集したり削除できます。

#### 操作方法
1. メニューの「記録」をクリックする
2. 削除したい単語の番号やアルファベットを入力して、検索する
3. 対象の単語をクリックし、上記画像のように編集欄を出す
4. 「単語を削除」ボタンを押下する

### 本日の単語の登録
![rakumane5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/9f979b6d-c7cd-e11b-5033-145cbce199fd.png)

毎日、ユーザーに取り組むべき単語を「本日の英単語一覧」として出力します。
本日の単語は、出題回数や正答率などに基づいてます。

出題回数が少ない単語や正答率が低い単語を優先的に出題し、効率良く単語学習が可能です。
本日の英単語一覧に登録された単語は「暗記モード」で取り組むことができます。

なお、単語登録は毎日0時に自動で行われるので、ユーザーの操作は必要ありません。

### 暗記カード
![rakumane6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/88cffc6a-7d56-f5dd-c952-cb0a6799bf2f.png)

単語テストの前に、暗記カードで単語を覚える機能を搭載しました。

暗記したと思ったら「覚えた！」をクリックし、そうでない場合は「もう一度」をクリックします。
「もう一度」をクリックした単語は最後の単語が表示された後に表示され、覚えられるまで繰り返し表示されるようになっています。

また、英単語と日本語訳はカードをクリックすると、切り替わります。

### 単語テスト
![rakumane7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/20cb65a0-f78b-7178-f6e4-eb3186f7a815.png)

ユーザーが単語を覚えているかを確認するために、確認テストの機能も搭載されています。
制限時間内に日本語訳をキーボードで入力して解答する仕組みです。

正解かどうかは結果画面を確認するまで表示されないので、スピード感を持ってテストに取り組めます。

![rakumane8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/e04c2fa8-c50c-a460-7e39-0e9cc3105dc0.png)

結果は上記のように表示されます。
ユーザーの解答と正誤が表示されているので、どの問題でどのような間違いをしたかを確認することができます。

### フリーモード
![rakumane9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/c8135185-2e0f-663e-d101-60f20291f288.png)

フリーモードは、自由に英単語を学習できるモードです。
本日の英単語だけでは学習し足りないと感じた方におすすめです。

#### 操作方法
1. 覚えたい単語を検索する
2. 対象の単語をクリックして、ステータスを「出題」に変える
3. 2までを繰り返して「暗記する」をクリック

### 記録
記録のページには「英単語の記録」と「学習日の記録」があります。

![rakumane10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/e70036c3-47b6-e78d-938a-7a45ae2a28eb.png)

「英単語の記録」は、登録されている単語の学習状況が閲覧できます。
出題回数や正答率、前回学習した日などを確認できます。

![rakumane11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/3ff7a349-091b-2b73-6ec9-d413553751a7.png)

「学習日の記録」は、本日の英単語を学習する暗記モードで全問正解した日を確認できます。
「COMPLETED」がある日は、全問正解したことを示しています。

### 設定
「ユーザー情報」と「モード設定」の設定を変更することができます。

![rakumane12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/744c45f7-57d9-336e-a8a9-6f8b9b03645e.png)

ユーザー情報は、ユーザー名やパスワードなどを変更できます。
パスワードを変更する際は、現在のパスワードと基準を満たす新しいパスワードを入力する必要があります。

![rakumane13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617758/b6dcd2ca-c83a-dcd9-9457-d5395fe93fb1.png)

モード設定は、単語テストの制限時間と本日の英単語の単語数を設定できます。
ただし、本日の英単語の単語数は明日以降に反映されます。

## ラクマネイングリッシュを開発した理由
このポートフォリオを開発した理由は、私が英単語の暗記が苦手だったからです。
当時の私はどの英単語を覚えたのかを管理できなかったため、覚えている単語も勉強することもありました。

覚えてないことを覚えるようにするのが勉強なのに、これでは勉強した気になるだけです。

そのため、過去の自分に手作業で管理せずに英単語を学習できるものがあればと思い、開発に至りました。

## これから実装したいこと
これから実装したいことは以下の通りです。

- SSL化
- パスワードの再設定機能
- 他サービスアカウントでの認証機能
- LINEで学習忘れを防止する機能
- 英語音声の登録機能
- カレンダーに予定を追加する機能

優先的に実装したいことはSSL化とパスワードの再設定機能です。

SSL化はLet's Encryptで試したことがあるのですが、フロントエンドからバックエンドへの通信がうまくいきませんでした。
現在も調査と検証をしていますので、早期に実装できるように頑張ります。

パスワードの再設定機能はAWS SESを利用してメールをユーザーに送信し、パスワードをリセットできるようにする予定です。
こちらはSSL化が完了次第実装します。

私自身、必須事項ができてないままにするのは悔しいので、引き続きポートフォリオの実装を頑張ります。

## 最後に
開発前はアプリを作ってリリースまでできるのか心配でした。
さまざまなエラーの解決や処理を実装するコードをどのように書くかなどで苦戦し、無理なのではと思ったこともあります。

最終的にAWSへのデプロイまでが完了し、自信をつけることができました。

このポートフォリオの改修や別のアプリを開発し、ユーザーに役立つものを届けられるようにこれからも頑張ります。