8年間ほぼコードを書かなかった客先常駐型SE 無謀にも会社を辞めてSNSを作る

# はじめに
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628254/7ba23633-5520-10fa-8eb5-52667439d26d.jpeg" width=100%>

はじめまして。
こちら、個人開発の記事になります。
良ければ読んでみてください。

# 対象読者
* SNS系のWebサイトの個人開発に興味のある方。
* あまりコードを書いてこなかった30代が、仕事を辞めて開発に専念するとどうなるのかが気になる方。
* エンジニアに転職するなどを目的に一旦無職になって開発してみるという選択肢を検討中の方

# 開発者のスペック
* 34歳
* 私立文系学部卒
* 大学卒業後、事務職を2年間経験。その後、`約8年間`IT系企業（客先常駐）に勤務し、昨年退職。
* プログラミングの実務経験：PL/SQL⇒`約3か月`。
その他Javaの改修などを合計すると数か月程度。

# 経緯
昔からSNS、マッチングアプリ系のサイトを自分で作ってみたいと思っていました。
現在1人が大勢に発信するタイプのSNSが主流な気がしますが、
どちらかというとマッチングアプリのような、1対1でやり取りを行うサービスの方が好きでした。
あとはマッチング（ユーザーとユーザーを結びつける）の契機を、『選書（本のオススメ）』というのは変わっててアリなのでは…と思い、開発しました。

# 作ったもの
本をオススメし合うSNS
『BookFellows』（※β版）

https://www.bookfellows.jp/

他の人の好きな本やプロフィールをみて、その人に合いそうな本をオススメし、
お互いに本を1回以上オススメした場合、メッセージのやり取りが可能。

# 開発期間
企画なども含め全部で`約7か月`かかったと思います。
よく経験者の方や未経験者の方が仕事しながら3か月、1か月、1週間などで作っているのを見て、その凄さがよくわかりました。
この間、実家の手伝い（自営業）をしたり他のこともやってはいたのですが、BookFellowsの開発に一番時間を割いていたと思います。

# 技術・環境
* Python3
* Django
* jQuery（JavaScript）
* Redis
* WebSocket（Django Channels）
* Cloudinary
* SendGrid
* Windows10
* VisualStudioCode
* Heroku

# 主な動作

- 本の選書
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644007/ab5d4910-1fbe-fb8f-d305-4a4231999d75.gif" width=30%>

- 選書された本を開封
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644007/ddd34610-49ce-3e49-9c6b-a20f9041ad3d.gif" width=30%>

- マッチング
相手側から既に選書されている場合、自分も選書することで、マッチング（メッセージ交換が可能な状態）が成立します。（その逆も然り）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644007/01d512ac-018d-f8c2-b9a4-db0ad891e260.gif" width=30%>

- メッセージ送受信（マッチング後）
マッチングすると、メッセージの送受信が可能になります。（リアルタイムチャット）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644007/1176391b-61e3-2ac3-e988-96dc8a7cf526.gif" width=30%>

# 画面
主要な画面のみ説明します。

<details><summary>ログイン画面</summary>

メールアドレス、Google、Twitterのアカウントで登録可能です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628254/81dee431-e779-28a2-2fb6-00cdddc64ede.jpeg" width=60%>

</details>

<details><summary>ホーム画面</summary>

新着情報、タイムライン、おすすめユーザーなどを表示。
本の選書（オススメ）があったり、メッセージが届いたりすると、新着情報としてホーム画面に表示されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644007/7f7f0769-d158-5547-af60-9d10d1d6fe85.jpeg" width=60%>


タイムラインにはみんなに選書された本が表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644007/861d9215-4a45-bd55-bf1c-74474b5a54df.jpeg" width=60%>

</details>

<details><summary>マイページ</summary>

マイページにはログインユーザーの情報が掲載されます。
編集アイコンを押下すると各項目の編集画面に遷移します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628254/c72c49e6-46fa-d3d9-111f-78855f1abc13.jpeg" width=60%>

</details>

<details><summary>ユーザー検索</summary>

ユーザーを検索する画面です。
性別、年齢、エリアで検索可能です。
ログイン順、新規登録順で並び替えができます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644007/494c5c2e-dabf-1c9d-e81d-251da8654d75.jpeg" width=60%>

</details>

<details><summary>選書画面</summary>

選書する本を選ぶ画面です。
ユーザー画面の「選書する本を選ぶ」ボタン押下して遷移します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628254/383cd86f-4d8e-6c7b-2063-8eebc70e27f5.jpeg" width=60%>

<details><summary>『この本を選択』ボタン</summary>

『この本を選択』ボタン押下するとモーダルウィンドウが表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628254/e8175e22-092e-4d4d-7a28-7db349b660a8.jpeg" width=60%>

</details>

</details>

<details><summary>選書された本</summary>

自分宛に選書された本が表示される画面です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628254/7de39f4c-7c34-7785-3917-214b758f1266.jpeg" width=60%>

</details>

<details><summary>本の情報</summary>

本の情報を表示する画面です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628254/32cf5223-d848-77a8-4722-f961022ad4bf.jpeg" width=60%>

</details>

<details><summary>選書仲間</summary>

自分に選書をしたか、自分が選書したユーザーを選書仲間として一覧表示する画面です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628254/10544ec4-9ce0-04a0-965d-b7234c913694.jpeg" width=60%>

</details>

<details><summary>メッセージ</summary>

本の選書をお互いに1度以上行った相手とメッセージ交換が可能になります。
WebSocketを使って双方向通信を可能にしています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628254/69931523-0222-e096-bcef-554cec1c3c77.jpeg" width=60%>

</details>

# 機能など
上記「主な動作」でこのサイトの主な動きは提示しましたので
その他細かい機能などを列挙します。

#### 1. トップページの表示 

トップページの「よく選書されている本」、「ユーザーの本棚紹介」欄に表示される本などはバッチ処理で定期的に更新しています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628254/bf67b901-1ebc-7197-8620-90879d3ada99.jpeg" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628254/c4a3e013-331e-5530-de30-f8116637f03d.jpeg" width=50%>

* Djangoのバッチ処理
Djangoではコマンドでバッチ処理を実行できる機能があるようです。
所定のパスにBaseCommandクラスを継承したクラスを用意して処理を記述し、コマンドで実行できます。

```terminal
python manage.py batch_command_sample
```

本番環境（Heroku）ではHeroku Schedulerというアドオンを使用して定期実行しています。

#### 2. 何かイベントが起きたら、別の何かを実行する
Djangoには、何らかのイベントが起きたタイミングで処理を実行するSignalsというものがあります。
ユーザーの新規登録が行われたことを契機に、いくつかのテーブル更新などの処理を行うために利用しました。

```python:signals.py
@receiver(post_save, sender=CustomUser)
def create_user_notification(sender, instance, created, **kwargs):
    # CustomUserテーブルが更新されたら、UserNotificationテーブルを更新。
    obj = UserNotification.objects.create(userId=instance)
    obj.user_notification = "ユーザー名をマイページから変更してください。"
    obj.save()

# 実際のコードより簡略化して記載しています。
# 他の記述は省略。
```

新規登録時にホーム画面に一度だけ下記お知らせが表示されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644007/67f1f417-176a-d1d1-2e2a-5c77cd9835fe.jpeg" width=50%>

#### 3. ソーシャルログイン
Google,Twitterアカウントによるログイン機能を搭載しました。

#### 4. 非同期チャット
DjangoChannelsを用いてWebsocketを実装。
Redisサーバーを使用。

#### 5. その他
いいね機能。フォロー機能。ブロック機能。
選書を依頼機能。（本を選んで欲しいユーザーにリクエスト）
オススメユーザーの選定機能。（バッチ処理）
FAQ。報告機能。お問い合わせ機能など。
レスポンシブ対応。PWA対応。

# ER図
![graph-model.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644007/fff73e38-a6c9-4484-ab95-9551bd7bf929.png)


# 開発のために勉強した本
* Django、Python
『実践Django Pythonによる本格Webアプリケーション開発』
『現場で使える Django の教科書《基礎編》』
『動かして学ぶ！Python Django開発入門』
『Djangoのツボとコツがゼッタイにわかる本』

* UI
『オブジェクト指向UIデザイン──使いやすいソフトウェアの原理』
『やってはいけないデザイン』
『UI/UXデザインの原則』
『作って学ぶ HTML&CSSモダンコーディング』
『HTML5/CSS3モダンコーディング フロントエンドエンジニアが教える3つの本格レイアウト』

* DB
『SQLアンチパターン』（つまみ読み程度）
『情報処理教科書 データベーススペシャリスト 2021年版』（試験受けたら不合格）

* 規約
『【改訂新版】良いウェブサービスを支える 「利用規約」の作り方』

* Web全般・その他
『Webを支える技術 ―― HTTP，URI，HTML，そしてREST』
『体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践』（部分的に）

# 技術選定理由
* Django
この先機械学習関係のアプリ開発も将来やりやすくなるかなと思いPythonのフレームワークを覚えることにしました。
* jQuery
JavaScriptのフレームワークを使用するべきだと思ったのですが、
あまり色々新規で手を出すと大変かなと思って断念しました。
一時的な勉強時間を費やす必要があったとしてもReactなどでやるメリットが大きかったのかもしれません。

# 大変だったこと
* メンタル
30半ばでどこに向かっているのかわからなくなる作業をひたすら継続することは辛いです。

* 自力で解決していくこと
会社などの組織に属していたり、質問できるメンターなどがいたらすぐに解決できるかもしれない問題に、多くの時間をかけたこともありました。
はじめからこの大変さはわかっていたのですが、とはいえスクール的なところに行くのも有効だったかもしれないとは思います。

# 課題
* 本の検索結果が微妙。
本を選書するサイトなのに本の検索機能が、現状はいまいちです。
* 何をするサイトなのかわかりにくい。
* 登録しなくても閲覧できる箇所が少ない。
* 検知している軽微なバグがある。
（時間の都合で致命的なものは対応したつもりです。）
* そもそも`需要がない。`
見てもらった友人たちに一番言われたのがこれです。

# 最後に
読んでくれてありがとうございました。
感想、意見、指摘、苦情などありましたら当記事コメント欄（やTwitter）にいただけると幸いです。
この先エンジニアに無事なれるかわかりませんし、自分のように一旦会社を辞めてしまうという選択をする方は少ないと思いますが、
同じようなことを考える方に、少しでも参考になったら嬉しいです。

# 参考
* 記事タイトル名の参考
『鳥類学者 無謀にも恐竜を語る』川上和人