🔍

株式会社ジンジブの技術と労働環境を紹介します

2024/05/28に公開

はじめに

株式会社ジンジブの涼です。この度、Zenn Publication を開設したので、今回は会社名義での記事を書きます。弊社は今年、グロース市場への上場を果たしました。本記事では、弊社がまだ開発チームを持っていなかったスタートアップから始まって上場を果たした今(2024年5月時点)、どのような開発体制や労働環境でどのような技術を使っているのかを紹介します。本記事は将来のエンジニアの採用を想定して労働環境を紹介する目的で執筆しています。まずは弊社が扱っている技術を簡単に述べた上で、それらの技術で開発をどのような労働環境や体制で進めているかについて解説します。

主要システムの技術構成

スタートアップから6年、弊社はPHP、Ruby on Rails、Next.js、React Native、Flutter 等の様々な技術を渡り歩きながら大小合わせておよそ50のシステムを開発してきました。(リポジトリ数調べ)
本記事では、弊社の主要なサービスであるジョブドラフトのシステム構成を紹介します。

サービス構成

本サービスの内容について記事内で詳しく述べることはしませんが、システム構成の紹介に欠かせない部分だけを軽く紹介します。システム全体としては高校生の就職活動を支援するものであり、高校生が求人を探したり弊社のキャリアコンサルタントとメッセージでやり取りを行ったりする「ジョブドラフトNavi」、企業様が掲載求人を編集したり求人活動を支援するサービスを提供する「ジョブドラフト for Company」、学校の先生が自校の生徒の就職活動状況を管理したり指定校求人を管理したりする「ジョブドラフト for Teacher」、弊社のスタッフが求人情報を入力したり広告やお知らせを発行したり等の様々な管理業務を行う「ジョブドラフト for Staff」、その他複数のサブシステムに分かれています。

アプリケーションサーバー

全体の大半としては1つの Ruby on Rails で開発されたモノリシックなアプリケーションで、クライアントは高校生向けの「ジョブドラフトNavi」だけが Flutter (web & iOS & Android) で提供しています。そして、各ログインユーザー種別毎のサブシステムが Ruby on Rails 上に複数存在し、それと別に API を Flutter アプリや各種サブシステム向けに提供しています。サブシステム毎にアプリケーションを分ける取り組みは何度か行ってきたのですが、最終的に1つのモノリシックなアプリケーションが一番扱いやすいということで戻ってきました。アプリケーション内部としてはサブシステム毎に名前空間で分かれており、例えば Controller のディレクトリ構造はこのような形になっています。

現状の rails stats はこのようになっています。Controller クラスの数は373、Model クラスの数は198、テストコードの割合は1:0.5と算出されています。規模の大きなアプリケーションではありますが、rubocop の規約は Metrics (AbcSize 等)をデフォルトから一切緩めていないので、全体規模に対して各クラスはコンパクトで美しく保守できていると思います。このアプリケーションは現在は高卒入社で今年2年目に入ったエンジニアが主に2人でタスクマネジメント及び開発を行っています。

% rails stats
+----------------------+--------+--------+---------+---------+-----+-------+
| Name                 |  Lines |    LOC | Classes | Methods | M/C | LOC/M |
+----------------------+--------+--------+---------+---------+-----+-------+
| Controllers          |  13350 |  11039 |     373 |    1512 |   4 |     5 |
| Helpers              |    408 |    346 |       0 |      50 |   0 |     4 |
| Models               |   6534 |   5671 |     198 |     323 |   1 |    15 |
| Mailers              |    244 |    229 |      28 |      30 |   1 |     5 |
| Channels             |     83 |     67 |       4 |       8 |   2 |     6 |
| JavaScripts          |   9806 |   7457 |       0 |     560 |   0 |    11 |
| Libraries            |   2741 |   2412 |       0 |       2 |   0 |  1204 |
| Model specs          |   3908 |   3224 |       0 |       0 |   0 |     0 |
| Request specs        |   3186 |   2764 |       0 |       0 |   0 |     0 |
| System specs         |   9411 |   7946 |       0 |      91 |   0 |    85 |
| Controller specs     |    353 |    281 |       0 |       0 |   0 |     0 |
| Helper specs         |     17 |     15 |       0 |       0 |   0 |     0 |
+----------------------+--------+--------+---------+---------+-----+-------+
| Total                |  50041 |  41451 |     603 |    2576 |   4 |    14 |
+----------------------+--------+--------+---------+---------+-----+-------+
  Code LOC: 27221     Test LOC: 14230     Code to Test Ratio: 1:0.5

インフラ

web サーバーには nginx を使用しており、/company, /teacher, /staff 等といった特定のサブディレクトリの URL に来た場合は Ruby on Rails アプリケーションに、そうでない場合は Flutter on the Web アプリケーションにルーティングしています。世の多くの Flutter on the Web アプリケーションはインフラ周りを Firebase Hosting 等に任せることが多いと思いますが、弊社では一台のクラウド仮想マシン上に Flutter on the Web と Ruby on Rails を併設し、その他細々としたサブシステムや cron 等も併用しています。Flutter on the Web と Ruby on Rails を nginx で上手くルーティングするには、assets ディレクトリ衝突問題等といった少し癖のある作業がいくつか必要だったため、以前に Zenn で参考記事を書いています。
[nginx] Flutter on the Web with Ruby on Rails

データベースはバックアップ等の障害対策機構を備えていて、求人解禁時やメディア露出時等のスケールに楽に対応できる Azure Database for MySQL のフレキシブルサーバーを用意しており、ストレージは求人票やその他の様々なファイル等の保存に Azure Storage を用意しています。Flutter アプリを開発するにあたって Firebase も利用しています。web の検証環境として Firebase Hosting で Pull Request 毎に検証環境が自動構築されるようにしており、Firebase App Distribution でモバイルの検証もできるようにしています。また、アクセス等の解析には Firebase Analytics、プッシュ通知には Firebase Messaging、その他細々としたものを Firebase に寄せています。

以上に例を挙げたようなシステムを、現在は全エンジニアがフロントもサーバーもインフラも全て扱うフルスタックエンジニアという形で開発しています。今後は各種専門性に特化した技術者の採用を予定しています。

開発体制

人数と役割

本記事執筆現在の開発チームは組織図上は7人で、うち1人が産休中、そして外注のデザイナーさんやイラストレーターさんが何名か、という人数体制です。指示系統は基本的には取締役から幹部会議を通じて開発チームに降りてきており、仕様周りのグリップや納期設定等は取締役が行い、開発チームのメンバーはその指示に従って開発業務を行っています。その取締役も何故か結構開発業務を行っています。上記の主要システムは前述の通り高卒入社の2年生が2人で開発しています。私と私の妻は Ruby on Rails7 と tailwind.css を用いた社内業務管理システムを開発しており、Next.js の新プロジェクトのプロトタイピングを1人で行っているメンバーもいます。もう1人は社内 SE として各営業拠点の物理インフラ管理や各サービスのドメインや証明書周りの管理、空いた時間で各プロジェクトの細かなタスクの開発支援を行っています。その他にも開発チームが関わっていない開発プロジェクトやコーポレートサイトや各サービスのLP等の様々な作り物もあり、これらはパートナーさんに発注していますが開発チームはほとんど関わっておらず、基本的には自分達の開発に集中できる環境があります。

プロジェクトマネジメント

アジャイル開発

開発チームでは毎週金曜日15時に30〜45分程度のスプリントミーティングを行い、そこで起こした Issue を起点に行っています。基本的には検証環境の仕上がり具合で事が進みます。検証環境は Flutter を使ったシステムでは Pull Request 毎に Firebase Hosting から自動的にブランチ専用の検証環境が構築されます。その他のシステムについては、自由に扱って良い検証用仮想マシンが用意されているので、必要に応じて都度デプロイするような形を取っています。上記主要システムのプロダクトマネージャーは高卒2年目のメンバーが1年目の頃から実装と兼任しており、スプリントミーティングによるタスクの確認やアサインまでを1人で担当しています。弊社は高校生の就職を支援するサービスを提供していますが、この開発チームのメンバーは高卒入社でエンジニアとして即活躍している良いモデルケースになっていると思います。

GitHub Projects

タスク管理システムは様々なツールを試みてきましたが、現在は GitHub の Issue と Projects のみで行っています。最近は看板とロードマップが非常に使いやすくなっています。各メンバーが自由に Issue を起票して、プロダクトマネージャーがアサインしたり、各メンバーが自由に拾ったりしています。

品質保証

コーディング規約

基本的にシステムで利用している技術の最も標準的なコーディング規約やツールのデフォルトに準拠しており、CI の GitHub Actions で Pull Request を自動チェックしてコードレビューに記法等のノイズになる指摘が発生しないようにしています。rubocop の Metrics/AbcSize 等、多くの開発現場ではキツすぎると言われている規約に関しても特別な理由がある特定の箇所以外はデフォルトのまま運用しています。これは長さと複雑さが割れ窓になりやすいためです。コードの美しさや品質については非常に強いこだわりがあるチームだと思います。

自動テスト

基本的にはテスト駆動開発一本で、テストを書いた方が実装が早く済む場合にのみ各人がテストを書いています。稀にコードレビューで内容によってテストの追加が要求されることもあります。上記の主要システムであれば前述した rails stats にあるように全体のおよそ5割程度のテストが書かれています。今後は後追いでテストを追加してくれる技術者の採用も考えています。CI の GitHub Actions による自動テストは、System Spec や Feature Spec のようにブラウザーを起こして操作をシミュレートする類のテスト以外が走るようになっています。これは単純に時間と料金の問題です。

労働環境

弊社は一従業員の私から見ても非常に働きやすい職場です。弊社では「働き方最先端宣言」という取り組みを行なっており、フルリモートフルフレックスで自由な働き方が推奨されており副業もでき、技術的な挑戦機会も多く、GitHub Copilot 支給といった開発環境への支援も行なっています。

フルリモート

弊社のエンジニアは全員フルリモート勤務です。外注さんもリモートです。新卒入社のエンジニアは別の雑務で出社を命じられることもあるようですが、エンジニアリングに関わる作業においては完全にフルリモートです。開発マシンには MacBook Pro が支給されます。常にビデオ通話を繋げておくようなことはせず、基本的には個人作業で週一のスプリントミーティング等、必要に応じてビデオ通話を繋いでいます。コミュニケーションは会社全体の Microsoft Teams と開発チームだけの Slack の有料プランを契約しており、基本的には開発チームのメンバーは Slack を利用してテキストコミュニケーションを行っています。

フルフレックスと勤怠

勤務体系は基本的にフルフレックスとなっていますが、現状は全員デフォルトの9時〜18時で勤怠設定しています。現状の開発チームは強烈な成果主義なのでその時間に席に居るかを監視していませんし、slack 等のオンライン状態も誰も気にしていませんが、10代も多く非常に年齢層が若い職場なので皆まだ真面目に働いています。ただ、レビュー依頼や仕様確認や技術相談等でメンションは昼間にそこそこ飛んできます。そういう意味ではフルフレックスという制度は表向きにはあまり活用されていません。

また、上場を前にして大きく変わったこととして、勤怠システムが支給ラップトップの起動状態で出退勤管理されるようになりました。我々のようなフリーランス出身の自由な時間に働くタイプの人間は夜も休日も自由に働いて代わりに平日の昼には気分が乗らなかったらサボりたいものですが、そういった働き方を自由にしてしまうとシステム上は過労やサービス時間外労働が可能になってしまうので、これからの会社を守る意味でもこれから入社してくる従業員を守る意味でも勤怠をクリアにすることや過労をシステム上不可能にすることを求められており、良くも悪くも好き放題働くことはできなくなりました。勿論、都度勤怠申請をして稼働調整をするのであれば夜や休日に働くこともできますが、今のところはその制度を利用している人がいないのがリアルな現状となっています。

AI 利用

弊社では GitHub Copilot が支給されるため、AI によるコード補完や GitHub Copilot Chat によるコーディング相談等の機能を利用することができます。また、現在は個々人で契約している Chat GPT4o を使っているメンバーが多いですが、近いうちに Azure OpenAI Service で gpt-4o モデルを Slack から利用できるようになるかもしれません。(取締役がそんな遊びをしているのを Slack で見ました)

研究開発

弊社では、通常のアプリケーション開発とは別に新しい技術の開発とプロダクトへの反映にも努めています。例えば、複数の OCR(光学文字認識) AI を組み合わせた求人票 PDF ファイルの自動読み取り技術、上述の Flutter on the Web と Ruby on Rails の共存サーバー構築、Ruby on Rails の ActionCable を用いた Flutter on the web アプリケーションと Ruby on Rails アプリケーション間のチャット機能、TikTok や YouTube ショート等のような動画配信サービスの再発明、その他現在も様々な技術に取り組んでいます。

おわりに

ここまで書いてきたように、今までは「生産性で殴れば大抵の問題は解決する」という暴論と共に少数精鋭属人化万歳の精神で成り立ってきました。しかし、上場も果たして組織も開発チームも一気に大きくなっていく中で、これからは会社組織としての安全性や、エンジニア個人の技術力や成長幅に依存しないチーム作りが求められていくと思います。そういった中でも古き良きベンチャー精神やスピード感を共存させつつ開発チームを成長させていきたいと思っています。そんな弊社の開発チームはエンジニアの採用を予定しています(過去の求人ページ)。ここまでお読み頂き、ありがとうございました。

Discussion