# 業務内容
スタートアップの会社に参画し、美容部員を目指している方向けの就活・口コミサイトの開発・運用を担当していました。
具体的な業務内容としては、
- Nuxt.js, Vuetify, TypeScript, Firebaseを用いたフロントエンドの開発
- 初期フェーズでのFirestoreの設計・実装
- Node.js, Nest.js, TypeScript, Postgres(CloudSQL)を使ったAPIの開発
- Dockerを使ってサーバーサイドの開発環境構築
- Jest, CircleCIを使ってサーバーサイドの自動テスト・デプロイを導入
- GAEを使ってインフラ構築
- Algoliaの検索システムの導入
- SendGridを使用してメールシステムの導入
- Twillioを使用してSMS通知の導入
- Cloud Functionsを利用してのクーロン,バッチ処理
- monaca, vue.jsを使用してアプリ開発
- 初心者のエンジニアの教育・マネジメント
---
# 開発の課題
- コアメンバーのエンジニアが抜け1人でフルスタックに開発する必要があった
- 0ベースから開発することが多かった
- 運用や技術的負債を後回しにして、開発していたことでの問題の顕在化
# 解決策
> コアメンバーのエンジニアが抜け1人でフルスタックに開発する必要があった
初期のプロダクトがない状態では、とにかくスピーディーに開発することが必要でした。
すでに営業をかけている状態でのコアメンバーの離脱もあり、0ベースという状況で3週間でリリースしないといけない。という状況でした。
1人でAPIを0から作りフロントエンドまでということもできませんでした。そこでFirebase, Firestoreを利用して開発を行いました。
Firestoreでの知見は少なかったので、どういう設計にすれば良いのか?を学ぶために勉強会に参加したり、勉強会での登壇者に個人的に質問をしにいったりしました。また、簡単なアプリケーションを実装したりもしました。
このプロジェクトや個人で実装したのもあってFirestoreを使ってのアプリケーションを作る力が身につきました。Firestoreはフロントエンドで完結するので結果的に3週間で開発を終えることができてリリースまで持ってくことが出来ました。
細かい要望やビジネスロジックはCloud Fucntionsを使って実装したりすることもできました。1人で開発を行うのにFirebaseはとてもよかったです。
しかし、Firestoreはまだ発展途上というのもあり設計が確立されていなかったり、情報が十分でないので困る場面も多々ありました。クライアント(顧客)がいくつかつき始め、クライアント向けの管理画面を作成するタイミングで、Node.js, Nest.js, TypeScript, Postgres(CloudSQL)を使ったサーバーサイドの開発をし書き換えました。
フロントエンドはTypeScriptで書いており、Repositoryパターンを実装していたので、Firestore→REST APIへの変更はスムーズに行うことができました。
### SaaS
1人で開発するために積極的にSaaSを利用しました。
検索サービスにはAlgoliaを利用しました。Algoliaを利用した理由は,Firestoreとの相性が良く、公式のドキュメントでも紹介されていたので実装がスムーズだったからです。
Algoliaを利用することで主に2つメリットがありました。
- 複雑なクエリを考慮したサーバーサイドの設計をしなくて良い
- フロントエンドで完結できる
CQRSを考慮することもAlgoliaを利用することでかなり減ります。またその後ジョインするフロントエンドとのコミュニケーションも最小限ですみ、フロントエンド側の細かい要望もAlgoliaが吸収してくれることになります。
### 設計
設計に関する深い知識がほとんどなかったこと、経営者に近い環境で開発していたこともあり、DDDに興味を持ちました。
DDDの全てを設計に盛り込んだわけではないですが、ドメイン知識の深い理解とユビキタス言語を正しく扱うという点を重視して設計をし開発できるようにしました。
### インフラ・自動化
またCircleCIとGitHubを使ってCI/CD環境を整えました。自動化できるものは積極的に自動化しました。
他にも分析して欲しいデータなどは、大体決まっていたのでCloud Functionsでバッチ処理を書いてクーロンで分析データを通知→管理画面で表示できるようにしました。
人材系のサービスだったので、履歴書の作成がとても手間になっていました。
そこで、ユーザーの応募情報を元に履歴書を自動で生成できるようにしました。
ユーザー応募→Cloud Functionsのtiggerを実行→REST APIから応募情報を取得→PDFで履歴書を生成→Cloud Storageに保存→ダウンロード ができます。
インターン生が初心者エンジニアとして入ったタイミングで、簡単に環境構築できた方が良いと考え、Dockerで環境構築しました。
### Pマークの取得
Pマークを取得する必要が出てきたので、セキュリティ領域もしっかり実装することにしました。
GCPのIAM管理, インフラのアーキテクチャ構成, VPNの設定, Firewallの設定, ホワイトリスト, ブラックリストの登録なども行いました。
### 知識の共有
1人での開発でどうしてもコアな知識が足りなかったり、未経験領域の十分な知見がないのは1つの課題でした。そこで勉強会に参加した際にできた友人などとslackでチームを作り情報交換を行うようにしました。
突然起きたインシデントを質問したり、新しい実装をするときにお互い設計をレビューしあったりすることで閉鎖的にならないように心がけました。勉強したことのアウトプットもみんなそこでやっているので、自分の知らない領域の知見も入ってくるのはとてもよかったです。
---
> 0ベースから開発することが多かった
0ベースからの開発、SaaSの導入、など新しい技術を使ったり、知識を入れながら手を動かすなど難しい点もありました。
新しい知識に関しては2種類の方法で学習しました。
1. 時間がある時(1, 2週間ほど)
- 学びたい対象に対しての有名な本を1,2冊準備します。
- 有名な本は難しいことが多いのでそれを補うための簡単な本(絵でわかる・漫画でわかるなど)を3冊準備します。
- 簡単な本を1冊は熟読して、残りに2冊は1冊目になかった知識を入れることだけに集中します。
- 有名な本を読むだけの準備としての知識があるので、最後にその本を読みます。
この方法だと何かに偏ることが少なく、深い知識が得やすいと感じています。
2. 時間がない時(2,3日後)
- 有名な本を1,2 ~冊調べます。
- その本に関するまとめの記事を10 ~ 20ほど集めて読みます。
- その本に関するslideを5 ~ 10ほど集めて読みます。
この方法だと記事やスライドがライトで、要点をまとめてあるので効率的に学ぶことが出来ます。
最後にアウトプットは、友人たちとのslackで常にアウトプットしているので
そこで質問をしたり、フィードバックをもらったりすることが出来ています。
---
> 運用や技術的負債を後回しにして、開発していたことでの問題の顕在化
初期のフェーズはとにかくプロダクトを作ることに専念していたので、セキュリティやテスト環境など運用するにあたっての不安がどんどん顕在化し始めました。
具体的に発生したものは、
1. リリースした後に別の機能でバグが発生が頻発した
2. ロジックが間違っていたことで短時間の間だけ個人情報が一部公開されてしまった。
この2つのインシデントから、テストの重要性とセキュリティ向上の重要性を感じました。
そこで行ったのはJestを使ったテストの自動化です。
テストの観点は2つ
- 機能は正しく動くか?
- 適切な権限で機能が実行できる or 実行できないか?
何も変哲もない解決策に思えますが、このテストを心から重要だと思って書くことができると自負しています。この自動テストを導入したことで、当時ご迷惑をおかけしてしまったクライアントにも改めて信用を得ることが出来ました。
また、依存関係による思わぬバグもすぐに検知することができることで開発を行いやすくなりました。
具体的な数値では出せませんがテストを導入することで
- テストを書くとコードが綺麗になる。
- テストを書くと健康になれる。
- テストを書くとモテる。
**テストはエンジニアを幸せにする。** と思います。