睡眠をテーマにした新しいSNS「SwimIn」を紹介させてください

# 自己紹介
2023年の9月ごろにプログラミングと出会い、のめり込み、今まで独学でずっと勉強してきました。運が良かったのもあって、12月ごろに某Web系の自社開発企業に内定をいただき、来年の4月からエンジニアとして働けることが決まっています。
就職活動中にも、ポートフォリオ(勤怠管理アプリ)を作成したのですが、今思い返せば、あまりモダンな開発ではなかったなぁと思います。バニラjavascriptを使って、htmlファイルを複数個用意したり、O/Rマッパーの存在も知りませんでしたから、SQLをゴリゴリにベタ書きしていました。（確かProgateでそのやり方を見たからだと記憶しています）
勿論、現場でもこういう構成で開発されている場合もあると思いますが、モダンな、流行ってる開発を体験してみたかったんです。
そういうわけで、フルスタックな開発に着手し、一ヶ月ほどで「SwimIn」を完成させました。


# SwimInとは？
**友達が寝ているかどうかがわかる**、睡眠SNSとなっています。

<a href="https://gyazo.com/141b37190b778b6693a26822779cf951"><img src="https://i.gyazo.com/141b37190b778b6693a26822779cf951.gif" alt="Image from Gyazo" width="200"/></a>　　<a href="https://gyazo.com/6970601238dd06aee552f388ac1c8a69"><img src="https://i.gyazo.com/6970601238dd06aee552f388ac1c8a69.gif" alt="Image from Gyazo" width="198"/></a>

URL ▶︎ https://swimin-app.com
※5/27時点ではサービスを停止しています。
Github ▶︎ https://github.com/YutaKakiki/swimIn 

   
もう少し具体的にいうと
- いつ寝たのか/起きたのか
- いつ起きるのか（目標起床時刻）
- 目標起床時刻と実際起床時刻の差
    - 目標ピッタリに起床
    - 〇〇時間〇〇分寝坊
    - 〇〇分早く起床
- 寝坊しているかどうか（目標起床時刻を基準に）
- コメント

といった情報を、閲覧できるようになっています。

「機能」にて後述しますが、ユーザの寝る時、起きた時の「打刻」によって睡眠情報が管理されており、その情報から**平均睡眠時間、睡眠時間、目標起床時刻の達成度**が週/月スパンで可視化できるようになっています。

また、当アプリはモバイル端末のみ対応しており、PCへのレスポンシブ対応は行なっておりません。というのも、寝る前と起きる時にPCを立ち上げないだろうという想定です。

# SwimIn開発の経緯
このようなアプリを構想したキッカケは、位置共有サービス「Zenly」の終了にあります。ご存知でない方もいるかもしれませんが、Zenlyには「睡眠中」と表示される機能がありました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657525/ffc4e680-0997-3e48-ebc2-11c764d3b175.png" width="400px"/>
今も位置共有サービスが代替して現れていますが、このような機能は見当たりません。
しかし、私自身、この機能はとても気に入っていましたし、周りの友人も「こいつ寝てるから学校こないんやん、電話して起こそう」みたいな使い方をしていて、結構使い勝手が良かったのです。
そこで、他人の睡眠中/起床中がわかるSNSを作ろう！と思い立ったわけです。
SwimInという名前の由来は、睡眠（すいみん）→スウィミン→Swim In→SwimInという流れで付けました笑

# 機能

### 認証系
- サインアップ/サインイン/サインアウト
[devise_token_auth]("https://github.com/lynndylanhurley/devise_token_auth")を使って実装しました。

### プロフィール機能
|ユーザ情報の編集　|
| ---- |
|<a href="https://gyazo.com/3fdec7cb7cd005077dd272f24399d1d9"><img src="https://i.gyazo.com/3fdec7cb7cd005077dd272f24399d1d9.gif" alt="Image from Gyazo" width="200"/></a>|
|・名前/email/プロフィール画像の編集<br>　現段階において、プロフィール画像に関しては、[Gravatar]("https://ja.gravatar.com/")を使用しています |

### フォロー機能
|友達検索　→　友達追加|「追加されています」|
|:----|:----|
|<a href="https://gyazo.com/ad2dda7358d7940f1ae3801b42b93af6"><img src="https://i.gyazo.com/ad2dda7358d7940f1ae3801b42b93af6.gif" alt="Image from Gyazo" width="200"/></a>|<a href="https://gyazo.com/2b48c844f98297e532159ab93529e1a8"><img src="https://i.gyazo.com/2b48c844f98297e532159ab93529e1a8.gif" alt="Image from Gyazo" width="200"/></a>|
|・メールアドレスで他のユーザーを検索、追加|・自分を追加しており、<br>　かつ自分が追加していないユーザーを表示　<br>・ここからユーザをーを追加することも可能|

### コア機能
|おやすみ打刻|おはよう打刻|
|----|----|
|　<a href="https://gyazo.com/d34c204da455b56648aecc6fd3af4e71"><img src="https://i.gyazo.com/d34c204da455b56648aecc6fd3af4e71.gif" alt="Image from Gyazo" width="200"/></a>　|　<a href="https://gyazo.com/2e38cfb6f236d69a3ced23c9c4f4cd2f"><img src="https://i.gyazo.com/2e38cfb6f236d69a3ced23c9c4f4cd2f.gif" alt="Image from Gyazo" width="200"/></a>|
|・目標起床時刻を設定<br>・睡眠時間（予定）を表示<br>・コメント|・睡眠時間が算出してして、表示<br>・目標起床時刻との差を表示<br>・「ぴったりに起床！」<br>　「〜分寝坊...」<br>　「〜分早く起床」　のパターン

|友達の睡眠状態閲覧|||
|----|----|----|
|一覧|詳細||
|<a href="https://gyazo.com/0812d2516bbf38ae38c8974d28963fe5"><img src="https://i.gyazo.com/0812d2516bbf38ae38c8974d28963fe5.png" alt="Image from Gyazo" width="200"/></a>|<a href="https://gyazo.com/3234fecb49b428fdd1c666ef42471a10"><img src="https://i.gyazo.com/3234fecb49b428fdd1c666ef42471a10.gif" alt="Image from Gyazo" width="200"/></a>|<a href="https://gyazo.com/78e5fc4d02577f469166529c54b8fa6c"><img src="https://i.gyazo.com/78e5fc4d02577f469166529c54b8fa6c.gif" alt="Image from Gyazo" width="200"/></a>|
|・睡眠中/起床中を表示　<br/>・寝坊アラート表示|・目標起床時刻<br/>・就寝時刻|・起床時刻<br/>・睡眠時間|

|睡眠履歴閲覧||
|----|----|
|機能説明モーダル|平均睡眠時間・グラフ|
|<a href="https://gyazo.com/4caeb5885e72b815e22445219b72ba8e"><img src="https://i.gyazo.com/4caeb5885e72b815e22445219b72ba8e.gif" alt="Image from Gyazo" width="205"/></a>|<a href="https://gyazo.com/b0d392036502025265d38bcbe5ab58c4"><img src="https://i.gyazo.com/b0d392036502025265d38bcbe5ab58c4.gif" alt="Image from Gyazo" width="210"/></a>|
|・グラフの読み方などを説明|・週 / 月単位の切り替え <br> ・平均睡眠時間 <br> ・グラフ表示　<br>　・睡眠時間（棒グラフ）　<br>　・目標起床時刻との差<br/>　　(折れ線グラフ)|



## 使用技術
|カテゴリ|技術|
|----|----|
|フロントエンド|typescript(5.0),React(18.0),Next.js(14.1.4)|
||・Yup(フォームバリデーション)<br/> ・MUI（UIコンポーネント）|
|バックエンド|ruby(3.1.2),rails(7.0.8)|
||・devise_auth_token(認証系)|
|データベース|mySQL2|
|インフラ|AWS ECS Fargate|
|Webサーバー|Nginx|
|環境構築|docker , docker-compose|
|CI/CD|GithubActions|

### アーキテクチャ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657525/559a6482-8f37-0d07-3b65-67bba8a25deb.png)
(https://zenn.dev/ddpmntcpbr/books/rna-hands-on/viewer/intro#%E6%A7%8B%E6%88%90%E5%9B%B3)
　
### ER図
- (書き方合ってるのか...?)
<a href="https://gyazo.com/66bbadfe863eb74f24eb2cb2287e7d58"><img src="https://i.gyazo.com/66bbadfe863eb74f24eb2cb2287e7d58.png" alt="Image from Gyazo" width="546"/></a>

## 技術選定理由

#### 「使いたい技術」から開発に着手した

- まず、あまり好ましくない選定理由かもしれませんが、開発を進める前に「最近の開発現場でよく行われているような、フロントとバックを切り分けたモダンなフルスタック開発をしてみたい」という思いがありました。本来であれば、アプリの内容や用途で決めるべきだと思います
    - その際、参考にした記事が以下です。参考というか、アーキテクチャは全て模倣させていただきました
     [【独学ポートフォリオ開発応援】実務未経験から学べる！Rails×Next.js×AWSハンズオン解説]("https://zenn.dev/ddpmntcpbr/books/rna-hands-on")
    - また、フロントにnextを使用した理由として以下の記事を見たことも影響しています
        - [RailsエンジニアのためのNext.js入門](https://speakerdeck.com/hokaccha/railsenziniafalsetamefalsenext-dot-jsru-men?slide=9)
        kaigi on rails 2021のトークです。この中で触れられていたのですが、フロントとしてHotWireを使用してSPAライクに作ることも可能ですが、「フロントはフロントのでファクトスタンダードに乗っていたい」という考えもありました。フロントを書くなら、せっかくだしnextを学びたいな！と思ったわけです。
        
　　 
- **フロントエンド**
    - React
        - SPAに作れる
        - UIコンポーネントが使える
    - ReactのフレームワークとしてNext.js
        - ルーティング設定が不要で、ディレクトリ構成で組める
        - デフォルトで全ページSSGを組める（今回SSRは使用していない）
            - ビルド時にHTMLをpre-renderingしてくれるので表示が早い
            - 本アプリでは[CSR+SSG]("https://rakuraku-engineer.com/posts/nextjs-app-ssgssr/#SSG%20+%20CSR")の仕様となっている
    - typescript
        - 変数や配列、オブジェクトに型を定義することができる
            - 安全性もありますが、定義した型エイリアスを見れば何が入っているか分かり易いのでそれもよかった
    　
- **バックエンド**
    - Rails
        - Restfulな開発がしやすい
        - APIモードを使用してフロント/バックの棲み分けができる
    　　
- **docker**
    - 開発環境をコードでかけて環境構築がしやすい
        - docker-compose.yml と Dockerfileで完結するのが良かった
　　
- **AWS ECS Fargate**
    - コンテナのサーバレス化
    - インスタンスタイプやクラスター管理が不要
    ※メリットやそもそもAWSについては完全に理解したとは言い難いです。「なんとなく」の理解です。

    　　　
- **GithubActions**
    - CI/CDのワークフローをコードでかける
    - 最初はCI/CDについてすら知りませんでしたが、gitへのプッシュ時にテストを走らせたり、自動デプロイができたり、メリットがいろいろ知れてよかった

## 工夫した点
#### ページ遷移を少なくした
<a href="https://gyazo.com/3234fecb49b428fdd1c666ef42471a10"><img src="https://i.gyazo.com/3234fecb49b428fdd1c666ef42471a10.gif" alt="Image from Gyazo" width="200"/></a>
- モーダルやスライドを使用して、ページ遷移を少なくすることでストレスを軽減するよう工夫しました。

#### 睡眠時間の記録の仕方
<a href="https://gyazo.com/eda013da8121faf863085652c5916535"><img src="https://i.gyazo.com/eda013da8121faf863085652c5916535.png" alt="Image from Gyazo" width="308"/></a>
- 説明しづらいのですが、例えば、5/26の23:00に就寝→5/27の7:30に起床する日があれば、5/27の1:00に就寝→5/27の7:30に起床する日（つまり日が回ってから寝る日）もあると思います。どちらの場合であっても、データの日時は5/26である必要があります。日が回って5/27に寝たとしても、それは私たちの感覚では「昨日」の話なのです。
※分かりにくくてごめんなさい！とりあえず条件分岐を工夫したという話です。

#### 友達が寝てるかパッとみてわかる
<a href="https://gyazo.com/0812d2516bbf38ae38c8974d28963fe5"><img src="https://i.gyazo.com/0812d2516bbf38ae38c8974d28963fe5.png" alt="Image from Gyazo" width="200"/></a>
- 青が睡眠中、緑が起床中と分かり易いようにしました。また、睡眠状態の更新があったユーザーから上に表示されます。

## 参考記事
- [【独学ポートフォリオ開発応援】実務未経験から学べる！Rails×Next.js×AWSハンズオン解説]("https://zenn.dev/ddpmntcpbr/books/rna-hands-on")
本文で一度触れましたが、この記事は本当に良かったです。この記事で、フルスタック開発を学び、実践することができました。 AWSでのデプロイもかなり苦戦しましたし、理解したとは言い難いですが、経験できたのは良かったと思っています。さらに、GithubActionsも学べるので、CI/CDの概念すら最初は知りませんでしたが、「あ、こりゃいいな」と思えました。
これを機に、書籍でdockerも学びました。最初はよく分かりませんでしたが、環境構築のしやすさというメリットはとても感じました。


## 今後の展望
本番環境でアプリを使ってみて、また、使ってもらった友人からの意見を交えて、今後追加したい機能を以下に上げてみます。

- LINEによる通知
    - 「おやすみ打刻」「おはよう打刻」は、かなり忘れやすいことがよく分かりました。そのため、LINE連携を行なって、LINEによる通知を行なっておけば、忘れずに済むのではないかと思います。
        - LINEから出ているAPIを叩けばいけるでしょうか？
- 就寝時刻、起床時刻の事後申請
    - これも、打刻を忘れたときに関する改善です。現段階では、リアルタイムに打刻し、自動で値が算出される使用になっていますが、事後申請ができれば、睡眠記録を正確につけることができます。
    - ちなみに、現在の仕様では、打刻をしなかった場合の睡眠時間は０となり、平均睡眠時間には含めません。
- プロフィール画像を直接アップロード
    - 現在の仕様では、プロフィール画像のアップロードをGravatarに任せています。当初の予定では、Active Storageを使用する予定だったのですが、なかなかうまくいかなかったので、こういった形になりました。
    - しかしながら、一度別のサービスに遷移するということはストレスなので、改善しなければならないなぁと思っています。

　
また、睡眠履歴のグラフ部分がまだ少し不具合が起きており、意図せぬ結果になってしまっていることがあります。ここも今後修正しなければならないところです。

ちなみに、「この友達に追加されています！」の機能は友達からの意見からアプデして加えたものです。やっぱり、使ってみないと粗は見えてこないので、フィードバックをもらう＆自身がユーザーとなって使用する→改善するという流れがとても大事ですね。

一旦個人開発からは離れますが、上記に挙げたことを今後やっていきたいと思っています。
やりたいことがあるので当分はしないかもしれません笑。

## 感想
ruby、rails、typescript、react、next、docker、フルスタック開発（上述のZenn記事）を一通り勉強し理解（もちろん完全にではなく、基本的な部分を「なんとなく」）するのに、5ヶ月ほど要し、この個人開発に1ヶ月かかりました。使用した技術の選定理由が簡単に言えば「流行ってて使ってみたかったから」という「ミーハー」な感じでしたが、NextもRailsも、いうまでもなく開発体験がよく、とても楽しかったです。RailsでAPIを作って、それをNextで叩いて、という流れが個人的にはたまらなかったですね。最初のヘルスチェックで興奮しました。また、コンポーネントを組み合わせてUIを作っているときはレゴブロックみたいで楽しかったです。
アプリ自体は、友人に試用期間一週間ほど使ってもらっていて、お金もかかるので一旦サービスは止めている状態です。
まだアプリに粗がまだまだあるでしょうが、使えるアプリを作れたという経験はとても価値のあるものになったと思います。