「エンジニアDB」というサービスを開発しました！【Next.js / Rails / AWS / Terraform / Docker / GitHub Actions】

## はじめに
こんにちは！ ひらぬま（[@koocookooc](https://twitter.com/koocookooc)）と申します。

「[エンジニアDB](https://engineer-db.com/)」という、『〇〇なエンジニアを検索できるサービス』を開発したので、紹介します。

ターゲットは、エンジニアの皆さんに向けていますので、ご利用いただけると嬉しいです。

https://engineer-db.com/

無料でご利用頂けます。

### 自己紹介
大学院（建築学）を卒業後、新卒で大手ハウスメーカーのIT事業部に入社しました。３年ほどITの企画、PM、設計、開発、テストなどを通して、ITのイロハを身につけました。

その後、より良いサービス・プロダクトを作れる人になるためには、開発サイドの経験もしておきたいと思いから、Web受託開発のスタートアップ会社にエンジニアとして転職しました。　今でちょうど２年目になります。

### 勉強したこと、使ったサービス
下記、1年間の勉強方法、使ったサービスをざっくり紹介しておきます。 結構幅広く手を出していました。
- 実務でフルスタック開発
- メンターのアルバイト
- 業務委託で開発
- [Happiness Chain](https://happiness-chain.com/)で、フルスタックに勉強
- [Cloud Tech](https://kws-cloud-tech.com)で、AWS勉強、SAA,DVAを取得
- [IT KINGDOM](https://it-kingdom.com/)で、最先端のフロントエンドのキャッチアップ
- [connpass](https://connpass.com/)のオンラインイベントに参加
- XやQiita,Zenn,Udemyなどでインターネットから情報収集

そんな筆者が開発したサービスを紹介します。
ポートフォリオや個人開発の参考になればと思います。

## 目次

[1.「エンジニアDB」の紹介](#1エンジニアdbの紹介)
[2.企画〜基本設計について](#2企画基本設計について)
[3.インフラ（全体構成）について](#3インフラ全体構成について)
[4.フロントエンドについて](#4フロントエンドについて)
[5.バックエンドについて](#5バックエンドについて)
[6.さいごに](#6さいごに)

## 1.「エンジニアDB」の紹介
![ogp.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258821/b8af7756-d011-8f1d-8914-27528e1ba940.jpeg)

### サービス概要
[エンジニアDB](https://engineer-db.com/)は、エンジニアデータを集約させて、エンジニア間の技術的なつながりをするプラットフォームです。求人検索や求職、開発仲間の発見をスムーズに行えるよう設計されています。

#### 全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258821/e110baae-882a-895d-e909-0e490f37c7ad.png)

#### ご利用手順
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258821/e6fd9be0-a149-0b34-bf30-1d71902434b7.png)

#### ▼サービスURL
https://engineer-db.com/

レスポンシブ対応していますが、PCファーストで実装しています。

### 開発背景
現在、エンジニアの求人には、SNSや人材サービスを活用することが多いですが、
その求人と求職の体制にはいくつか課題がある考えています。

SNSは検索性に欠け、特定の人材を見つけにくいという問題があります。また、人材サービスはデータを独占する傾向にあり、複数のサービスに登録する必要が生じます。

このような課題を解決するために、「エンジニアDB」を提案します。

エンジニアDBは、登録されたデータを独占せず、共有し、その民主化を目指しています。
このアプローチにより、エンジニアや企業が互いに結びつきやすい状態が生まれ、エンジニアの探索や仕事の探求に役立ちます。

さらに、エンジニアDBに蓄積されたデータを分析することで、より価値ある情報を提供していきます。

最終的なビジョンは、
**「本サービスに登録するだけで、企業やエンジニアと繋がる状態を実現すること」** を目指しています！

図解するとこんな感じです。
```mermaid
graph TD
    A[現状のエンジニアの求人と求職市場] -->|問題点| B[SNSの検索性不足]
    A -->|問題点| C[人材サービスのデータ独占]
    B --> D[エンジニアDBの提案]
    C --> D
    D --> E[エンジニアDBの実装]
    E --> F[データの共有と民主化]
    E --> G[エンジニアや企業とのつながりが促進]
    F --> H[価値ある情報の提供]
```


## 2.企画〜基本設計について
### アイデアを出し
初期段階でのアイデア出しについて、具体的な指針がない状態だと、非常に難しいです。
なので、はじめに、以下の基本方針を設定することにしました。
- 人の役に立つものを作りたい。
- スクール課題レベルの技術（基本的なCRUD・認証など）で、価値あるサービスを作りたい。
- ターゲットは、エンジニアの皆さんにしたい。
    - 理由は、Webアプリに慣れている & XやQiitaなどでリーチしやすそう & フィードバックを頂きやすい（かも）といった点です。

この方針でアイデアを考えていると、
エンジニアという特定の属性データを集約し、それをユーザーに共有・還元することで、魅力的なサービスを開発できるのではないかという考えに至りました。

バージョン１として、求人・求職に利用できる機能のみにフォーカスを当てて、実装し、リリースしています。
今後、需要に合わせて、機能を拡張していきます。

### 要求定義と要件定義
ざっくりですが、説明します。

「〇〇を△△したい」という形でまとめられるのが、要求定義と位置づけています。
つまり、このサービスで実現したいことです。

- エンジニアのデータを集めたい。
- エンジニアを検索できるようにしたい。
- サービス内で連絡を取れるようにしたい。
- イベントや求人・求職をアピールできる場を設けたい。

要求定義を基に、次は要件定義に移ります。
要件定義は、どのようなシステム・機能が必要なのかをまとめます。

- エンジニアのデータを集めたい。
    - ユーザー（エンジニア）がアカウントを作成できるようにする。
    - プロフィール情報を入力できる機能をつける。
- エンジニアを検索できるようにしたい。
    - 検索機能をつける。
- エンジニアと連絡を取れるようにしたい。
    - メッセージ機能をつける。１対１のメッセージで十分である。
- イベントや求人・求職をアピールできる場を設けたい。
    - 投稿機能をつける。

ここまでの構想をまとめると、
下記のように図解することができます。

```mermaid
flowchart TD
    A[サービス利用開始] --> B[プロフィール情報を登録]
    B --> C{エンジニアを<br>探している?}
    C --> |Yes| D[エンジニアを検索する!]
    D --> E[メッセージを送信]
    B --> O{イベントや求人を<br>周知したい?}
    O --> |Yes| P[postを投稿する!]
    B --> V{仕事を探している?}
    V --> |Yes| W[プロフィールを充実させて待つ!]
    V --> |Yes| X[postを確認する]
    X --> E
    E --> F[新しい仕事&仲間に出会える]
```
ここまでくると、ユーザーの動線がわかってきますので、
必要なページや機能が明確になり、ワイヤーに落とし込めるようになります。

### 画面（ワイヤー）設計
今回のプロジェクトは一人で全て実装したため、詳細なワイヤーフレームの作成は行っていません。
しかし、ユーザーの動線の確認と画面構成の概要を理解するために、Figmaを用いてモックアップレベルの設計を行いました。

実際に作成したモックワイヤーはこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258821/e5e61f62-0dee-7ded-9433-acbbeadefc0c.png)

ここまでの設計をフローにまとめると、下記のようなイメージです。

```mermaid
    flowchart TD
        A[アイデア発想] -->|基本方針設定| B[方針決定]
        B --> C[ターゲットユーザー特定]
        C --> D[サービスアイデア形成]
        D --> E[初期機能の実装とリリース]
        E --> F[機能の拡張と改善]
        F --> G[要求定義]
        G -->|エンジニアのデータ集積| H[アカウント作成機能]
        G -->|検索機能| I[検索機能]
        G -->|メッセージ機能| J[メッセージ機能]
        G -->|イベント求人機能| K[投稿機能]
        H --> L[ユーザープロフィール登録]
        I --> M[ユーザー検索]
        J --> N[メッセージのやり取り]
        K --> O[イベント求人投稿]
        L --> P[サービス利用]
        M --> P
        N --> P
        O --> P
        P --> Q[ユーザーの動線と画面設計]
        Q --> R[Figmaでのモックアップレベル設計]
        R --> S[実装とフィードバック]
```

### 機能一覧
続いて、機能一覧とそれぞれの説明をします。スクショを併せて記述します。
UIUXやURL設計は、ZennやX、食べログなど、有名なtoCサービスを参考にさせていただきました。
（有名なサービスがデファクトになっていると思ってますので）

#### 認証機能
ログインは、GitHubログインのみにしています。
1人あたり１アカウントのみの作成にしたかったのと、ユーザー対象をできるだけエンジニアだけにしたかったためです。
GitHubを使用しないエンジニアにも将来的にはアクセスを拡大する計画ですが、現段階では特定のターゲットに焦点を当てています。

#### ユーザーのプロフィール設定
基本情報やスキルセットを登録できるようにしています。
これにより、ユーザー検索する際や、そのユーザーについて知ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258821/35132621-66e7-6e35-194d-4ff4df2f4ecb.png)

スキルセットについて、様々なスキルを細分化して、それぞれにレベルを登録いただけるようなUIにしています。

#### 検索機能
ユーザーのプロフィール情報とスキルセットを検索条件にして、検索できるように設計しています。
この機能がサービスの肝になります。現状は、基本的な検索条件のみを設けています。
今後、ユーザーの声が聞けたら、もっと検索方法を改善していきたいと思っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258821/c1568f4c-4812-5e59-3fec-be10e88912de.png)

#### 投稿機能
特定の人を探したり、イベントなどをアピールしたりするときに、自分から発信できるようにするために投稿機能を設けています。
ターゲットをエンジニアにしていますので、マークダウンで投稿できるようにしました。
リッチでスタイリッシュな投稿ができます。
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258821/69fddc86-cdcf-dd69-bd16-dc61c1bf7a0f.png)

#### メッセージ機能
求めるエンジニアに連絡を取るために、メッセージ機能を設けています。
最近では、SNSでメッセージができる環境があるので、あえて本サービスでメッセージのやり取りはしなくてもいいと思い、軽めに設計・実装しています。

今後、Webプッシュ通知を導入できれば便利になるかなと思っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258821/0c76f825-13a9-7f2b-dacb-e68364853616.png)

#### ダッシュボード機能
ユーザーデータをいい感じに集計して表示できる機能があったら面白いな〜っていうので設けることにしました。
データが集まったら、もっと価値のあるダッシュボードを提供していきたいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258821/6018c97b-5811-b0a5-12d2-a2c1068ed9a3.png)

#### URL設計とページ一覧
下記のようになっています。

|URL|ページ
|---|---|
|/login|トップページ  |
|/engineers  |エンジニア一覧（ログイン後のトップページ）  |
|/engineers/dashboard  |データダッシュボード  |
|/engineers/{id}  |特定エンジニアのプロフィール  |
|/engineers/{id}/skill  |特定エンジニアのスキルレベル  |
|/engineers/{id}/post  |特定エンジニアの投稿一覧  |
|/posts |投稿一覧 |
|/messages |DMグループ一覧 |
|/messages/{id} |特定エンジニアとのDM内容一覧 |
|/mypage  |自分のプロフィール  |
|/mypage/skill  |自分のスキルレベル |
|/mypage/post  |自分の投稿一覧 |
|/policy  |プライバシーポリシー |

## 3.インフラ（全体構成）について
ここから技術的なことについて話していきます。

まず大前提として、プロジェクトの全体構成は、[Happiness Chain](https://happiness-chain.com/) の卒業課題の条件に基づいて決めれらていました。これらの条件には以下が含まれます
- Rails APIモード / Reactで完全SPAのポートフォリオを作る。
- 本番環境と開発環境にDockerを使う。
- 本番環境にはECS Fargateを使う。
- GitHub Actionsを使ってAWSに自動デプロイする。
- Terraformでインフラをコード化する。

なので、これに倣って実装しています。

### アーキテクチャの全体像 
フロントエンドはVercelにデプロイして、バックエンドはAWSのECSにデプロイしています。

ブランチ運用は、GitHub flowを採用しています。
プルリク時にテストが走り、mainブランチにマージされるとデプロイされる感じでCICD設計しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258821/d59aaad9-65d0-33a0-4235-347f49b9c9b1.png)

AWSリソースは全てTerraformで書いています。
こちらの記事にまとめていますのでご参照ください。

https://qiita.com/hiiragiya/items/00a41f2c340b7d176274

### 認証の仕組みについて
今回、フロントエンド側でNextAuth.jsを用いてGitHub認証のみでログインできるように実装しました。

FIDO Allianceを中心に推進されている 「パスワードレス」です。 セキュリティやユーザービリティが向上すると思っています。
さらに１ユーザー１アカウント、かつユーザーはエンジニアのみ、という条件にもぴったりです。

APIの認証は、NextAuthで生成されたJWTトークンをheaderに含めたリクエストをRailsに投げて、Rails側でJWTトークンを検証することで実装しています。

下記のようなフローになっています。

```mermaid
sequenceDiagram
    ユーザー ->>Next.js (Frontend): ログインボタンをクリック
    Next.js (Frontend)->>NextAuth.js: GitHub認証の開始リクエスト
    NextAuth.js->>GitHub: GitHubでの認証をリクエスト
    GitHub->>NextAuth.js: 認証情報を返す
    NextAuth.js->>NextAuth.js: 認証情報をもとにJWEを生成
    NextAuth.js->>Next.js (Frontend): 生成されたJWEを返す
    Next.js (Frontend)->>ユーザー: ログイン成功とともにJWEを保持
    ユーザー->>Next.js (Frontend): 保護されたページにアクセス
    Next.js (Frontend)->>Rails (Backend): JWEを付与してリソース要求
    Rails (Backend)->>Rails (Backend): JWEの復号化とJWTの検証
    Rails (Backend)->>Next.js (Frontend): 検証の結果とリソースの返却
```

JWTトークンは、Next.jsのサーバーサイドのみで扱うようにしています。
サーバーサイドでのみJWTを処理することで、クロスサイトスクリプティング（XSS）などのウェブベースの攻撃からトークンを保護できます

状態管理が簡素化されるので実装がシンプルになり、さらにクライアントサイドの負荷が軽減されるので、よりスムーズなユーザー体験を提供できていると考えています。

以降、フロントエンドとバックエンドの設計、実装内容を説明していきます。
実装したコードはこちらで公開しています。

https://github.com/sora33/engineer_db-frontend

https://github.com/sora33/engineer_db-backend

よくないところは、率直にご指摘いただけますと嬉しいです。

## 4.フロントエンドについて
使っているフレームワークや主要なライブラリ、テスト手法について記述していきます。

### フレームワーク
Next.js13のApp Routerを採用しています。 言語はTypeScriptです。

#### 採用理由
キャッチアップを兼ねて、このサービスは、Next.jsの最新に追従していきたいので、採用しました。 
下記の記事を参考にして、リリース段階ではApp Routerの機能へ深入りはせず、
必要になったときに、必要な分だけアップデートしていく感じで、考えています。

https://speakerdeck.com/izumin5210/findy-2024-01-24

#### 良かった点
サーバーサイドデータフェッチが容易になっており、Railsとやりとりする部分は、全てサーバーサイドで処理するように実装しました。 データフェッチの部分では、状態管理が不要となるので、実装がシンプルになりました。

ルーティングとレイアウトの設計がしやすく、ディレクトリ構成から設計の意図が伝わりやすくなったように感じます。

学習教材としては、Next.js が公式で出している、Learn Next.js がわかりやすいのでおすすめです。

https://nextjs.org/learn

### CSSやUIコンポーネントのライブラリ
Tailwind CSS で実装しています。

UI コンポーネントとして、Shadcn/UIを採用しています。
Shadcn UIは、Radix UIとTailwind CSSを用いたコンポーネントで、必要なUIのみをプロジェクトにinstallできるようなツールになっています。

https://ui.shadcn.com/

#### 採用理由
Tailwind CSSは、クラス名など考える必要がなくスラスラ書けるので、開発速度が圧倒的に速いと思っています。
ネットではコードが見にくくなるようなデメリットの懸念が散見されましたが、一人で開発していたことや小規模なサービスだったので、気になりませんでした。

UI コンポーネントのShadcn/UIについて、
[2023 JavaScript Rising Stars](https://risingstars.js.org/2023/en)で、スターの増加数が高かったJSのOSSのラインキングで１位にもなっててかなり注目を浴びています。

使ってみた感想として、
プロジェクトに応じてスタイルを変更しやすく、ライブラリのような依存関係がないので取り入れやすかったりするので、Tailwind CSSを採用している場合はおすすめです。

### Storybook
#### 採用理由
コンポーネントの採用利用率を上げるため、UIテストを実装できるため、今後の保守運用の3点です。
このうち最も魅力に感じているのは、UIのテストを実装できることでした。

Storybook の採用デメリットとして、メンテコストが高い、腐らせてしまうなどが多いようでしたが、下記記事が参考にすると、それらの懸念は解消されると思いました。

つまり、Storybook を採用しても、「プロジェクトの複雑化を避け、ファイル生成のコストを共通化で抑え、スナップショットテストと絡めてリターンを得る。」ことが可能になります。

- [Storybook を導入する際にやるべきこと 3 選](https://zenn.dev/sum0/articles/9463d16d9d40e2)
- [React 向け Storybook のチュートリアル](https://storybook.js.org/tutorials/intro-to-storybook/react/ja/get-started/)

### テストについて

ESLint と Pretiier による静的解析、Storybook による UI の単体テストと結合テスト、Jest によるビジネスロジックや関数の単体テストを実装しています。
Github Actions でプルリク時に、これらのテストが自動で走るように設定しています。

なお、E2E テストはコストがかかりすぎので、導入を諦めました。手動でチェックします。

フロントエンドのテスト手法として、Jest や React-testing による単体テストや結合テストが散見されましたが、〇〇コンポーネントに「〇〇」と書いてあればテスト OK のような例が散見されており、効果が薄そうだなぁ感じていました。

Storybookを使ったテストでは、インタラクションテストやビジュアルテストリグレッションテストが実装できることがわかりました。なので今回、UI に関するテストはStoryBookで実装するように決めました。

参考
- [フロントエンドのテスト戦略について考える](https://zenn.dev/koki_tech/articles/a96e58695540a7)
- [[Next.js]フロントテストのコストは Storybook で削減出来る](https://zenn.dev/sora_kumo/articles/8a79531e726b29#storybook-%E3%81%AE%E8%A8%AD%E5%AE%9A)

### ディレクトリ構成

\_components というディレクトリを切って、いい感じにコンポーネントを管理しています。
urlに関わるディレクトについて、ディレクトリ名は小文字ハイフンで統一しています。

大まかな構成は下記のような感じです。
```
.
├── app
│   ├── _components  # 全てにコンポーネント
│   │   ├── ui # atom, moduleレベルのコンポーネント
│   │   └── layout # 共通のheaderやfooterなど
│   ├── (authenticated)  # 認証後のページ
│   │   ├── _components # 認証後の共通コンポーネント
│   │   ├── engineers # エンジニアページ
│   │   │   ├── _components # エンジニアページの共通コンポーネント
│   │   │   ├── (root) # /engineersページ
│   │   │   │   ├── _components # /engineersページのコンポーネント
│   │   │   │   ├── layout.tsx # /engineersページのレイアウト、メタ情報
│   │   │   │   ├── page.tsx # /engineersページのデータフェッチ、コンポーネント配置
│   │   │   ├── [id] # /engineers/[id]以下のページ
│   │   │   └── layout.tsx # エンジニアページのレイアウト
│   │   ├── messages # DMページ
│   │   ├── mypage # マイページ
│   │   ├── posts # 投稿ページ
│   │   ├── quit # 退会ページ
│   │   └── layout.tsx
│   ├── (unauthenticated)  # 認証前のページ
│   ├── api  # Api Route
│   ├── globals.css
│   ├── layout.tsx  # 前ページ共通のレイアウト
│   ├── not-found.tsx
│   └── page.tsx  # 認証前後で、リダイレクトを設定している。
```

詳細は、こちらを参考にしてください。
App routerでは、このようなディレクトリ構成を採用&おすすめしているケースが多いです。

参考

- [Next.js 13 の ディレクトリ構成](https://scrapbox.io/wwwy-dev/Next.js_13%E3%81%AE_%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E6%A7%8B%E6%88%90)

### 開発で工夫したところ

- 画像投稿機能について、画像投稿前に、フロントエンド側で画像圧縮するようにし、無駄なサーバーやストレージのリソースを利用しないようにしました。
- レンダリングについて、基本的に SSR として、フォームなど状態管理が必要な部分のみを CSR にするようにしました。 また、ダッシュボードページ等の処理が重いページかつ、最新データでなくてもOKなページは、ISR にし、キャッシュしたデータを扱うようにしました。　（0.5hごと更新）
- url設計やUI, UX は丁寧に設計しました。 トップページなどのクリエイティブが必要な点は、外注すべきと思いました。。
- 無限スクロールとページネーションを使い分けています。使い分けのポイントは、UI・UXとURLが必要かどうか と思っています。　（今回SEOは関係ないので無視する）
    - 検索ページは、検索条件やページ数をクエリパラーメータで持たせるようにして、ページネーションを採用しています
    - それ以外のページは、UIUXの良い無限スクロールでを採用しています。
- 「[Next13NProgress](https://dev.to/designly/implementing-nprogress-in-the-nextjs-13-app-router-2aff)」というライブラリで、画面遷移時のプログレスバーを実装しています。ページ遷移待ちのユーザーの心理状況がかなり向上すると思っています。導入が簡単なので、おすすめです。

## 5.バックエンドについて
使っているフレームワークや主要なgem、テスト手法について記述していきます。

### 開発環境
Dockerを使っています。
Appサーバー用とDBサーバー用の２つのコンテナを起動させています。

```mermaid
graph TD
    subgraph コンポーズグループ [Docker Compose]
        subgraph DBグループ [PostgreSQL Container]
            DBサービス(PostgreSQL)
            ボリューム[データボリューム]
            DBサービス -->|データ保存| ボリューム
        end

        subgraph APIグループ [Ruby on Rails Container]
            APIサービス(Ruby on Rails)
            ポート3000[3000番ポート]
            APIサービス -->|ポート3000で公開| ポート3000
        end

        コンポーズ[Docker Compose] -->|定義| DBグループ
        コンポーズ -->|定義| APIグループ
    end

    APIグループ -->|依存関係| DBグループ
```

ローカルPC（macbook air メモリ16GB）で、Docker起動すると、PCが重すぎて作業が捗りませんでした。。
なので、AWS EC2(linux)にremote SSH接続した環境内で、Dockerを起動させるようにしていました。。

### フレームワーク
Ruby on Rails7　のAPIモードで実装しています。
前述の通り、スクールから指定があったので採用しています。特に採用理由などは書きません。

### gem
特殊なものは採用しておらず、あまり説明することがないです。
下記のような、多くの人から支持されているgemを採用しています。

#### active_model_serializers
APIのレスポンスボディを構成するために、採用しました。

#### aws-sdk-s3
Active Storageの保存先を、S3に設定するために採用しました。

### テスト
 テスト戦略として、RuboCopによる静的解析でコードの品質を保ち、モデルスペックでバリデーションやアソシエーションの正確性を確認しています。さらに、リクエストスペックを用いてAPIの結合テストを行い、システム全体の動作を保証しています。
 
#### モックデータの作成
モックデータの作成には『factory_bot_rails』と『faker』を使用しています。これらのgemにより、テスト用のリアルなデータセットを容易に生成でき、テストの正確性と効率を大幅に向上させています。

#### モデルの単体テスト
shoulda-matchersというgem使っています。 バリデーションテストなどを１行で記述できるようになので楽になります。

モデルスペックでは、バリデーション、アソシエーション、メソッドのテストを実施しています。 

#### APIの結合テスト
ユースケースに基づいて、正常系と異常系の動作を確認しています。

正常系は、レスポンスのステータスとボディの確認をしています。
異常系は、認証エラー、not found、リクエストパラメータのバリデーションなどを確認しています。

参考

https://qiita.com/KNR109/items/fe331069c4f958efbd96

### DB設計
主要な部分を記述します。

```mermaid
erDiagram
  Users {
    uuid id
    string provider
    string provider_id
    string name
    string purpose
    string comment
    string work
    string occupation
    string gender
    integer experience
    text introduction
    text hobby
    datetime birthday
    string location
    string website
    datetime last_sign_in_at
  }

  UserSkills {
    uuid id
    string user_id
    string name
    string level
  }
  Posts {
    uuid id
    string user_id
    string category
    string content
  }
  Group {
    uuid id
    string name
  }

  GroupUser {
    string group_id
    string user_id
  }

  GroupMessage {
    uuid id
    string group_id
    string user_id
    string content
  }


Users ||--o| Avator : "active_storage"
Users ||--o{ UserSkills : has
Users ||--o{ Posts : posts
Users ||--o{ GroupUser : belongs
Group ||--o{ GroupUser : has
Group ||--o{ GroupMessage : has
```

### 開発で工夫したところ

- 開発面では、Rails Wayに従い、MVCアーキテクチャを厳守し、DRY原則を適用してコードの重複を避けるようにしています。
- パフォーマンス面では、n+1問題、データアクセス回数、メモリ使用量などに注意して実装しています。
- Primary Keyは、UUIDを採用しています。インフラとバックエンドを移行する可能性があるので、移行性を考慮しての対応です。セキュリティ的にもUUIDの方が良いみたいでした。

参考

https://zenn.dev/yukito0616/articles/d3b7032e9f1e90

https://zenn.dev/kaorumori/articles/08ff8106300a7b


## 6.さいごに
ここまで読んでありがとうございます！。

「エンジニアDB」は、エンジニア間のコネクションを深め、求人やプロジェクトへの参加機会を広げることを目指すプラットフォームです。エンジニアの皆様にとって、新たな出会いやチャンスの発見の場となれば幸いです。

今回の開発は、[Happiness Chain](https://happiness-chain.com/) で学んだ知識と経験が基盤となっています。 ロードマップがしっかりしてるので、効率的にフルスタックな技術が身につきました。 　最後まで・ご指導、レビューいただいた皆様に感謝申し上げます。

今後も「エンジニアDB」のさらなる成長と、エンジニアの皆様にとっての価値あるサービスづくりに努めます。ご興味を持っていただいた方は、ぜひ下記のリンクよりサービスをご利用いただければと思います。

https://engineer-db.com/

また、私の活動やサービスに関する最新情報は、「X」で随時更新していますので、ぜひフォローしていただけると嬉しいです。

https://twitter.com/koocookooc

改めて、この記事を最後までお読みいただき、ありがとうございました。

以上