新入社員が入社後数ヶ月でコミックリーダーアプリのレビュースコアを 1.4 → 4.7 に改善した話


はじめに

この記事は株式会社TORICO Advent Calendar 2021 の7日目の記事です。

こんにちは!開発部の三枝です。

やや誇張気味なタイトルのようでもありますが、「新入社員が入社後数ヶ月でコミックリーダーアプリのレビュースコアを 1.4 → 4.7 に改善した話」とし、2021 年末のアドベントカレンダーの一記事として投稿します。

同僚の Flutter エンジニアが、同じアドベントカレンダーの記事「Flutter でECアプリを新規開発してみて」で、弊社の別の Flutter 製の EC アプリの新規開発の過程や選定技術・アーキテクチャについて書いているので、そのような話題についてはぜひそちらの記事もご覧ください。

この記事では、新入社員だった私がどのようにコミックリーダーアプリの開発タスクに関わったかに触れながら、TORICO の開発体制や環境の魅力や楽しさも伝えられたら良いなと思います。

MZ Reader review score before after


私は 2021 年 3 月に Flutter エンジニアとして TORICO に入社しました。以前はヨーロッパの自動車産業系の会社で機械振動の解析の研究に従事したり、医療業界を対象にした SaaS のサービスを開発する会社に勤めたりしており、漫画やエンタメ業界については知らないことばかりだったので、入社して最初に驚いたのは、毎日たくさんの漫画が購入され日本中・世界中の多くの人々に楽しまれているということです。

電子コンテンツについても同様で、弊社のコミックリーダーアプリ「MZ Reader」でも漫画を読むのを楽しむことができます。

入社前の面接のときから、この MZ Reader の開発を担当することになるのは聞いており、新規開発したい機能があることも聞いていました。

本棚機能の開発

弊社の提供するコミックリーダーアプリは、それまで他社製のものを提供していたものを、Flutter を用いて社内で開発された MZ Reader がリプレイスする形でリリースされたものだと聞いています。MZ Reader ではじめに提供すべき機能を選定する際に、以前のコミックリーダーアプリにはあった「本棚機能」を削ることにした結果、それが想像以上にお客様に重宝されていたこともあり、レビューのスコアが 1.4 と悪化してしまっていました。

「本棚機能」とは、私たちが紙の本を本棚のスペースごとに区切って整理するように、お客様が購入済みの書籍をアプリ内で自分の好きなように分類するような機能です。YouTube や Spotify などの動画・音楽のストリーミングアプリで、プレイリストとして、同ジャンルや好きなコンテンツを集めて整理する機能に似ています。

お客様のレビューの内容を見てみると、Flutter 製の新たな MZ Reader をシンプルで良くなったと言って下さる方もいる一方で、やはり自分好みに書籍を整理するための「本棚機能」がなくなって使いづらくなったという意見を仰る方がいました。

そこで、入社後少ししてから初めての中規模程度以上の開発タスクとして、本棚機能の開発にアサインされました。

開発タスクの主な内容

上で述べたような「本棚機能」の開発タスクとは、単に Flutter のクライアントアプリにその機能を実装するだけではありませんでした。入社前から聞いていましたが、弊社の開発部では、モバイルアプリ、Web クライアントサイド、Web サーバサイドのエンジニアといった明確な区別や役割分担はありません。メンバーや領域によって経験や習熟度の違いはあれど、いろいろなタスクを皆で協力しながら進めています。

たとえば、入社直後には、会社のビジネスの主な流れや、サービスに関するどんな情報がどんなテーブルに保存されていて、他のどんなテーブルを参照しているのか、ソースコードのどこにどんなロジックが書かれているかなど、何が何だか全く分からなかった状態から、お客様からの注文に関する問い合わせや、電子コンテンツのデータの不整合の確認、運営チームからの突発的なビジネスデータの集計依頼なども、少しずつ対応できることが増えていきました。

はじめは先輩や同僚がそのような対応をしているのを横で見ることしかできずに歯がゆい思いもしていましたが、時には分からないことを尋ねて必要なサポートをしてもらいながら馴染んでいくことができる環境です。

さて、コミックリーダーアプリの「本棚機能」の話に戻りますが、上で述べたような何でも挑戦していく弊社の開発チームの環境では

  • Flutter のクライアントアプリに本棚機能を実装する
  • 本棚機能に関わる Django の API を実装する。その際、本棚機能に関する全く新しいテーブルをいくつか DB に追加する
  • Web 版漫画全巻ドットコムのマイページに、同等の本棚機能を Nuxt.js で実装する

というのが「本棚機能」の開発タスクに含まれました。

Flutter, Dart 以外にも Python 言語自体には多少の経験はありましたが、業務レベルで Django (Django REST framework) によるサーバサイドの開発をすることも、Nuxt.js や TypeScript を書くことも初めてだったので当初は不安もありつつも、なんとか最後までやりきることができました。

開発の流れ

MZ Reader は購入した書籍をオフラインでも読めるコミックリーダーアプリなので、「本棚機能」は、それぞれのユーザーの本棚(プレイリスト)は Django の API を通じて作成・保存・更新しつつも、その本棚情報の API のレスポンスを元に、Flutter で SQLite を扱う sqflite とその ORM である sqfentity を用いてローカルストレージに保存することで、オフラインでも動作するよう実装する必要がありました。

前に述べた通りの理由で、Django の API の実装には時間がかかると判断し、まずはローカルストレージだけで、Flutter のクライアントアプリで本棚機能が動作するように実装をしました。

冒頭で紹介した記事の EC アプリと異なり、ある程度の規模の Flutter アプリの状態管理の定番が Provider (Riverpod) + StateNotifier + freezed に収斂されていくような昨今の流れ(異論もあるかもしれませんが...)が出てくる随分前から開発されていた MZ Reader は、かっちりとした特定のアーキテクチャを採用している訳でもなく、シンプルな MVVM + Store パターンといったところですが、登場するレイヤーが少なく新しく入った私にもキャッチアップしやすい内容でした。一長一短ではあるでしょうが、何でも流行りの方法でやるべきだ、みたいな開発上の前提がそれほどないことや、ビジネスの成功のためのアプリや Web サービスだという前提(上司である部長がよく言っているので心に残っています)が浸透しているように思えるのも、TORICO の開発チームの好きなところです。

Flutter アプリのオフライン機能としてある程度動作するようになった後は、Django の API の実装に進みました。「本棚」と「本棚に保存した本」という機能を実現するために、「本棚」に相当するテーブルと、「本棚」とユーザーの購入済みの書籍(ある「本棚」には複数の書籍が紐付けられるし、ある書籍は複数の「本棚」に属して良いので N 対 N の関係)を結びつける「本棚内書籍アイテム」といった意味合いの中間テーブルと、それらに対応するモデルを新規作成して、本棚を作成・編集・削除・並び替えするような API と本棚に書籍を追加・削除・一括追加・一括削除するような API を、Django の APIView や ModelViewSet を継承したクラスに実装していき、それぞれのユニットテストの記述まで済ませました。

その後は、Flutter アプリからそれらの API をコールし、必要なレスポンスを端末の DB に保存していく実装を済ませて、ようやく Flutter アプリに「本棚機能」を実装することができました。ここまでで一ヶ月半ほどかかったと記憶していますが、多くの学びがあった貴重な機会だったと思います。

その間の週末や退社後の趣味の時間に Nuxt.js や TypeScript を触って遊んでいたので思ったよりはスムーズに、それでも 2〜3 週間ほどかかりましたが、Web 版漫画全巻ドットコムのマイページに同等の本棚機能を実装を済ませて、一通りのタスクを完了させました。

心に残っていること

Flutter の開発以外にも、入社前にはほとんど経験のなかったことを含めて色々な学びがあった「本棚機能」の開発は、入社後に任せてもらった最初のタスクで良かったなと思っていますが、他にも心に残っていることがあります。

というのは「本棚機能」全体に比べると細かい話にはなるのですが、コミックリーダーアプリで「本棚」に追加する書籍を選択する際のアニメーションに関するものです。「本棚」に追加する書籍を複数選択するために、対象書籍を長押しすると、iOS の写真アプリの選択モードのように、選択された書影に薄暗い影がついた上で、書影の隅に丸囲みのチェックマークがつくような UI を実装していました。ちなみに弊社にはアプリケーションの見た目に関するイニシアティブを取るデザイナーのような役割はいないので、クライアントアプリの開発者が自主的に提案しつつ他の開発者や運営チームと議論し合意を図るようになっており、やはり、単に仕様通りに機能を実装する以上の自主性が求められますし、良い意見であればそれが尊重されます。

それを Flutter アプリの開発レビューをしてもらっていた開発本部長 (CTO) に見せてみると「ちょっとで良いから...。なんか... もっと色気がほしいな」といった趣旨のフィードバックを受けたのです。

明確に不可ということはないだろうとは思っていましたが、聞いた瞬間「色気を求めらるとは!」と少し驚き、その数秒後にはすごく納得したのをよく覚えています。

TORICO は「世界に『楽しみ』を増やす」をミッションとしています。

コミックリーダーアプリにせっかく実装した「本棚機能」はなるべく多くのお客様に、便利に、そして楽しく使ってもらいたいものです。実装にかかった工数は Django の各種 API の方がよっぽど多いのですし、Flutter の Animated Widget のひとつを使用したたった数行の内容ですが、「色気がほしい」というフィードバックと一緒にもらったアドバイスをもとに、書籍を複数選択する際の、波紋を出しつつ、コインが裏返るようアニメーションでチェックマークが付く(つまり丸囲みのチェックマークの幅方向に長さ 0〜直径のアニメーション)機能は個人的に気に入っていますし、そのお陰で少しでも多く・楽しくお客様に「本棚機能」が使用されていたらな、と思っています。

その後

「本棚機能」が少しずつ使用され始め、アプリのその他の機能も改善されたり安定化されたりしたというタイミングでレビュースコアの改善施策にも取り組んだこともあり、タイトルのように、2021年12月20日時点で、iOS の App Store では 349 件の平均レビュースコアが 4.7 まで回復しました。

また、「本棚機能」のタスクが済んだ後は、ますます Django や Nuxt.js の開発タスクに従事する機会が増えて、いまでは業務中は毎日 Django, Python に多くの時間を割いています(一応アイデンティティは Flutter エンジニアのつもりなので、業務後や週末の趣味や個人開発の時間では、毎日欠かさず Flutter と Dart を書いて、最新の SDK バージョンにもキャッチアップしています)。

先日 Web 版漫画全巻ドットコムのサービスについて、カート機能や決済機能の比較的規模の大きいリニューアルがあったのですが、その決済手段のひとつの Django での実装を主に担当するなど、まだまだ他の同僚や先輩のように素早いスピードで開発をどんどん進められないことには自信を持てないところがあるものの、入社した頃よりはできることことも増えたなと実感していますし、そのような環境で働かせて下さっている上司やチームの皆さんには感謝の気持ちでいっぱいです。

最後に

技術ブログというよりは、新入社員のエンジニアが TORICO の開発チームに馴染んでいったか、その中で印象に残っていることや、新入社員だった私にとって TORICO の開発チームや環境がどのようなものに映っていたか、といった内容にフォーカスした記事となりました。

弊社のサービスや開発チームに興味をもって下さる方の参考になれば幸いです。

ありがとうございました!

現在の評価: 5

コメント

コメントを投稿
コメントするには TORICO-ID にログインしてください。
ログイン コメント利用規約