# ``1・【概要】``
某大学教授からの依頼を受け、ワクチンを二回摂取した人向けに顔写真や摂取証明書の情報が記載されたワクチンパスポートを表示する機能、及び病院側で摂取者の情報や写真の管理ができる管理画面の機能を持ったアプリケーションの開発。
アプリケーションの技術選定及びフロント、バックエンドの開発、インフラの構築。
# ``2・【チーム構成、規模】``
フロントエンド: 2
バックエンド: 2
【自分の役割】
・フロントエンド、バックエンド技術選定及び開発環境、テスト環境構築
・フロントエンド、バックエンド両方の実装担当
# ``3・【詳細】``
この案件では私がアプリケーションの設計を行いました。
技術選定を行う上で以下のポイントを重視しました。
## ●フロントエンド
・静的型付け言語で型の不整合等を事前に検出し開発効率を上げる
・コンポーネントは凝集度を高く保つために機能毎に細かく分割し、複数の機能を持たないようにするとともに、テストを行いやすいようにする
・CSSはグローバルに参照するような書き方をせず、コンポーネントごとにスコープし、スタイルの競合や意図しない参照を防ぐ
## ●バックエンド
・静的型付け言語で型の不整合等を事前に検出し開発効率を上げる
・速度をシビアに求められるような要件ではなかったため、実行速度よりも開発効率を重視する
## ●開発環境構築(インフラ)
・人によって開発環境の動作が異なったりすることを無くすために、コマンドを入力するだけで同じ環境が構築できるように目指す
上記の項目を満たすために以下の技術を選定しました。
## ●フロントエンド
●React
・ライブラリ独特の文法が少なく、基本的にJavascriptの文法を使用してUI部分のコードが記述できる
・凝集度の高いコンポーネントを作成でき、Typescirptと合わせて使うとコンポーネントのPropsの型を事前に定義すること等によって保守性の高いコンポーネントが作成できる。
●TailwindCSS
・ユーティリティクラスが豊富
・スタイルを直接記述することによってコンポーネントごとにスコープされたスタイルを記述することが可能になる
## ●バックエンド
●Ts-Node
・静的型付け(Typescript)の恩恵を受けられること
・フロントエンドと使用言語を揃えることで開発効率の向上を図る
・インタプリタ言語の中では高速な部類に入る
## ●開発環境構築
●Docker,Docker-compose
・DockerFile、Docker-compose.ymlに予め開発環境の情報を記述しておくことによって、コマンドを入力すれば環境を構築できるような状態を目指す
# ``4・【実装した主な機能】``
## ●フロントエンド
## ・モーダル表示機能
【どのような機能の開発・実装か】
・登録、変更、削除する前に「登録します、よろしいですか?」のようなメッセージ付きの確認モーダルを表示する機能及びそれらが成功、失敗した時に「登録に成功(失敗)しました」のようにメッセージを表示するモーダルの実装
【課題・問題点】
始めは上記の機能をコンポーネント化(確認モーダルは「ConfirmModal」、了承専用モーダルは「ApproveModal」)し、ReactHooksでページごとにその都度呼び出すような方式で実装していたが、毎回PageComponentに該当コンポーネント及びuseStateによる状態を付与していたためコードが冗長になってしまった。
これを解消するためContextAPIを使用し、Providerで囲んだコンポーネントに確認、了承モーダルを呼び出す状態を付与し、呼び出せるようにした。
【使用した技術】
・createPortal
・useReducer
・createContext, useContext
【上記の技術をどのように使用したか】
・了承モーダルは``useApprove``というカスタムフックを作成しContextのプロバイダに渡す。使用する際はuseContextでインポートし使用する
使用例:
```
const { setApprove } = useContext(approveContext);
setApprove('登録に成功しました。');
```
・確認モーダルは開閉時の状態やアクションを定義したreducerをuseReducerでContextのプロバイダに渡す。使用する際は``confirm``の関数を呼び出す。
```
const { confirm } = useConfirm();
const isConfirmed = await confirm(
'登録します、よろしいですか?',
)
if (isConfirmed) {
//了承時の処理
}
```
【この機能の工夫点】
・window.confirm, window.alertのように少ないコード記述量でモーダルを呼び出せるようにしたこと。
## ・React-webcamでの画像撮影機能
【どのような機能の開発・実装か】
React-webcamでキャプチャしたスクリーンショットを画像に変換し、formDataに登録する機能。
【課題・問題点】
React-webcamでキャプチャしたスクリーンショットがbase64文字列になっているため、それを画像に変換する必要があったこと。
【工夫した点】
ボタンをクリックして撮影するデバイスを「外付けカメラ」「内蔵カメラ」と切り替えられるようにしたこと
## ・PrivateRoute機能
【どのような機能の開発・実装か】
・管理者側管理画面と病院側管理画面のPrivateRoute機能(未ログインユーザーはどちらもアクセスできず、管理者は病院に、病院は管理者画面にアクセスできないようにする機能)
【使用した技術】
・react-Router
・swr
【上記の技術をどのように使用したか】
・PrivateRouteには使用時「'Admin'」か「'Hospital'」のPropsを渡す
・登録されているDBのデータには「Role」というカラムがあり「Admin」か「Hospital」が格納されている
・ページ遷移する際に必ずバックエンドにリクエストを送り、バックエンドはリクエストにcookieが含まれているかどうか確認する。無い場合はログインページ(propsがAdminならば管理者ログインページ、Hospitalならば病院ログインページ)へリダイレクトする。
・cookieがリクエストに含まれている場合はレスポンスのユーザー情報の「Role」を参照し、ユーザー情報のRoleとPropsが一致するか確認する。
・一致する場合はページ表示、一致しない場合はpropsに対応するログインページへリダイレクトする
【この機能の工夫点】
ログインした後も管理者は病院ページに、病院は管理者ページにアクセスできないようにした点
## ・QRコード機能
【どのような機能の開発・実装か】
・ワクチンパスポートを登録したユーザーがQRコードを自分で読み取るor読み取ってもらってワクチンパスポートを表示させるようにする機能
【使用した技術】
next-qrcode
【この機能の工夫点】
作成されたQRコードが「img」ではなく「canvas」だったため、そのままではiOSやAndroidのサイト内読み込みができなかったため、cavasをimg要素に変換してサイト内読み込みを可能にしたこと。
## ●バックエンド
## ・画像を合成し一枚の画像にし、S3に保存する機能
【どのような機能の開発・実装か】
・リクエストで送られてきた複数の画像を合成して一枚の画像にしてからS3に保存。
・画像名はハッシュ化してからクライアント企業が開発していたブロックチェーンサーバーに保存する。
・ブロックチェーンに保存した後はブロックチェーンサーバーから問い合わせ用のIDが来るのでそれをユーザーのデータに登録。
【仕様した技術】
・sharp
・@aws-sdk/client-s3
・ioRedis
【課題・問題点】
S3の画像に保存する操作は良かったが、S3から特定のオブジェクトを取得する操作がaws-sdkのv2とv3で大きく異なっており、また公式ドキュメントも不親切かつ情報も日本語英語問わずかなり少なかったため実装するのに苦労した。
【この機能の工夫点】
・画像名をブロックチェーンに保存した後ブロックチェーンから問い合わせ用IDは別リクエスト&いつ来るかはっきりと決まっていない(ブロックチェーンサーバーはブロックチェーン内すべてのノードに情報を登録した後に問い合わせ用IDを送るので、ノードの数等によって登録時間がまちまちになる)ので、登録が完了した後にレスポンスで来るacceptKeyとuserIdの組み合わせをRedisに保存し、別リクエストでacceprKeyと問い合わせ用のIDが来た時にuserIdと関連付けができるようにした点
## ・ログイン機能
【使用した技術】
・cookie-parser
・jwt
・express
## ・メール送信機能
【使用した技術】
・node-mailer
# ``5・【出したバリュー】``
・大きなバグが無く、一ヶ月半程度で実装を完了させることができ、テスト工程に余裕を持って進むことができたこと
・予め使うUIパーツ(ボタン、テーブル、テキスト入力欄等)はコンポーネント化して開発メンバーに共有することで他の開発メンバーは部品を再利用するだけでページを作成できるようにしたこと
・Dockerを使用したことで開発環境構築時に開発メンバー間で不具合が無く環境構築ができたこと
# ``6・【この案件から自分ができること】``
・React+Typescriptを使用したフロントエンド開発
・React-testing-libraryを使用したフロントエンドの結合テスト
・再利用性の高いUIコンポーネントを作成することによる開発効率の向上
・Typescriptを使用したバックエンド開発
・Jestを使用したバックエンドの単体テスト