LINE株式会社は、2023年10月1日にLINEヤフー株式会社になりました。LINEヤフー株式会社の新しいブログはこちらです。 LINEヤフー Tech Blog

Blog


【インターンレポート】LINEポイントの営業を支援するために社内レポートを改善した話

はじめまして、熊倉秀人です。8/7から9/15まで開発4センター/Point Devチームのバックエンドエンジニアとして技術職就業型コースのインターンシップに参加しました本レポートではインターンシップで取り組んだ課題について説明します。

取り組んだ内容

本インターンではLINEポイントクラブの広告案件の操作や設定を行うことができる社内用管理画面(以下、管理画面)に変更を加え、既存のレポート画面では見ることの出来なかった情報であるpre_conversionの件数を見れるようにしました。pre_conversionとはユーザーがポイントをもらうためにエントリー(サービスの登録など)を行った後、実際にポイント付与されるまでの状態を管理するためのデータです。この機能は以前から事業企画側からの要望があったのですが他に優先度の高い案件が多く存在しており、工数もかかるため手つかずのままでした。

campaign report画面について

複数のページに変更を加えたのですが、一番実装が重かったのはcampaign reportページでした。campaign reportページはあるcampaign関連の集計情報が見れるページです。campaignとはユーザーが特定の条件を達成した際にポイントを獲得できる案件を指します。例えば、「あるサービスに登録すると300ポイントもらえるcampaign」などがあります。

campaign report画面の主な機能を以下に示します。

  • 開催中もしくは過去に開催したcampaign一覧が見れる
  • それぞれのcampaignのクリックされた回数、campaignによって発生した売り上げなどの集計が見れる
  • 集計の間隔を指定でき1時間ごと、1日ごと、全期間を選択できる(大元のデータは1時間単位で集計されている)

簡略化した画面のイメージについて示します

このページにpre conversionの数などを表示するための改修をしました。pre conversionの列を追加したイメージについて示します。

設計

今回変更を加えたページの設計について説明するためにシステムの設計について軽く説明します。詳しい内容は、このシステム全体のリニューアルを行ったときのLINE DEVDAY 2021での発表スライドで解説しています。

https://speakerdeck.com/line_devday2021/story-of-rewriting-8-year-old-perl-product-with-kotlin

管理画面ではページを表示するために必要なデータをadminアプリケーション(管理画面に関係するロジックを取り扱うアプリケーション)とcoreアプリケーション(ビジネスロジックの根幹を扱うアプリケーション)を経由してMySQLから取得しています。使用している技術は主にKotlin/Spring Bootで、管理画面のフロントエンドにはNuxt.jsを利用しています。

この構造ではどのレイヤーで既存のデータに新しいデータを付け加えるかについて複数の選択肢があり、それぞれの選択肢にメリットとデメリットが存在します。最終的にcampaign reportページの改修では、データベース内の関連するテーブルを結合することで追加するデータを取得する設計としました。

また、pre conversionを管理するテーブルのレコード数がかなり多いため、リクエストの度に集計しているとDB負荷も大きく、レスポンスを返すのにも時間がかかるという問題もありました。これを解決するためにpre conversion reportというテーブルを新しく作り、定期的にpre conversionの集計処理を行ってデータを格納しておくことで、リクエストの度に集計を行わずに済ませるような設計変更も途中で行いました。既存のreportに合わせて1時間単位での集計を行い、pre conversion reportテーブルに保存するようにしました。

開発した流れ

課題を始めて3日ほどは課題の理解を深めるとともに、事業企画側の方に質問を行い仕様の詳細について確認を行っていました。仕様確認をかなり注意深く行った結果、事業企画側との仕様の認識違いはなく求められている機能を適切に開発することができました。

ある程度仕様が固まったところで実装を始め、仕様に関して不明な点などに気がついたらそのたび事業企画側の方に質問をしていました。今回の実装は変更量が多かったため、レビューの負担を小さくするためにPRを複数に分け、作業が終わったところからレビューをお願いするという方法で進めていました。

開発に入る上で、当初は素朴な実装で試行錯誤していました。しかし、開発を進めていく中でパフォーマンス上の問題がありそうなことがわかり、チームメイトと相談してより詳細な設計を行いました。その後実装を進めたところ、問題に直面したため設計を再度行うことになりました。

設計案1

設計: pre conversionの集計を定期実行で事前に行い、集計したデータを取得するAPIを作成する。既存のAPIに加えて新しく作成したAPIも呼び出すようにし、管理画面上で情報を結合する。

この設計になった理由:

  • API設計としてシンプルになる
  • pre conversionを取得する個別のAPIがあったら他のページでpre conversionの情報が欲しいときに使いまわせる
  • 既存のreport機能を修正してデータを追加する場合、データを取得するためのSQLが複雑になる

この設計で一旦開発を進めてみましたが、期間中にpre conversionが発生しているが、クリックや売り上げが発生していないタイミングのデータ取得で問題が発生しました。レポート表示の機能にはページングが実装されており、かつクリックや売り上げが発生していないタイミングの行は表示されないという動作をしていました。pre conversionのデータを取得するAPIを分けてしまう現在の設計では、データが抜けてしまうか、ページングの行数条件と矛盾する表示になってしまうかのどちらかは避けられない状態でした。

ページングの設定で1ページに4行表示したいと仮定すると、以下の左下例ではデータはあるものの1ページに5行のデータが表示されてしまいます。右下の例はページングの設定を優先したパターンで、既存のcampaign reportの表にpre conversionの値をinner joinするような形で実現できます。しかし、そうすると11:00のデータがcampaign reportで表示されなくなってしまいます。

設計を行う前で機能を追加する画面をもっと触っておき、細かな挙動を観察しておけばこの問題に早く気がつくことができたかもしれません。

設計案2

設計: 定期実行で集計したデータを作成し新しい情報をデータベースからアクセスできるようにする。campaignの取得方法を変更しデータベース内で既存の情報に新しい情報を付け加える。

この設計になった理由

  • pre conversionのみが存在するcampaignを取得できる
  • SQL内でデータの結合を行っているためページングの問題も回避できる

この設計で実装を行ったところ無事開発を完了することができました。関係者にデモを行ったところ好評で、欲しかった情報が見れるようになって嬉しいとのコメントを頂きました。

感想

大変だったこと

  • データ構造が複雑な上に仕様書にも明示されていない内容が複数あり、それらの内容を把握できず手戻りが発生したこと。
    • ポイントクラブが10年以上続くサービスで、過去のさまざまな経緯があってデータ構造が複雑になっていた
    • システムが複雑すぎて詳細な仕様を把握するのが難しかった
  • データベース周りのテストに3000行のテストファイルが存在して書き直すのがかなり辛かった
    • 新しいテストケースを加えることで既存のテストにも影響があり、想定している挙動などを考えるのが大変だった
  • 30ファイルぐらい変更して実装量がかなり多かった気がする、めっちゃレビューしてもらえて面白かった

良かったこと

  • 社員さんのslackの返信速度、レビューの速度がすごい早くリモートでの仕事効率がすごい高かった
  • 四谷本社に出社して1日働けたこととその後飲み会に行けたこと!
  • めちゃめちゃ実務っぽい課題をやらせてもらえたこと