Classi開発者ブログ

教育プラットフォーム「Classi」を開発・運営するClassi株式会社の開発者ブログです。

【開発者インタビュー #3】小林 健太

こんにちは!Classiで働く開発者インタビューシリーズ企画の第三弾は、プロダクト開発部の小林さんです。

まず簡単に自己紹介をお願いします

小林健太と申します。私はClassiのQAチームに所属し、QAエンジニアとして働いています。 Classiに入社する前は、第三者検証サービス*1を提供する会社で新卒で入社し約2年間ほど働き、その中で保険やECSサービスに関する検証業務を担当していました。

Classiには2020年2月に業務委託としてジョインし、2021年4月から正社員として働いています。主にClassiのプロダクトに関する検証業務や、Classi全社の品質情報見える化の取り組みなどを行っています。

ー なぜ新卒でQAの仕事をしようと思ったのですか?

元々はエンジニア志望で1社目に入社をしましたが、配属希望を検討する中でQAの仕事は「最後の砦」「安心した品質を届ける」というとても大切な仕事なんだと知りました。そして、自分の几帳面で細かい部分にも気を配れるという性格も合っていると感じてQAを志望しました。

Classiへの入社経緯、入社理由は?

最初は業務委託という形でClassiでお仕事をしていました。その中でClassiやQAチーム内での働きやすさを実感し、この会社で長く働きたいと思うことが増え、正社員としてClassiに転職することにしました。

ー 具体的にどんなところで働きやすいと感じましたか?

まずは人ですね。Classiのエンジニアはフランクで優しく、コミュニケーションが活発な人が多いです。そして感謝の言葉も沢山いただいています。

第三者検証サービスで色々な現場を回っている時は少し堅い文化の業界にいたこともあって最初はすごくギャップもあり驚きましたが、徐々に慣れていく中でとても働きやすい環境だと感じました。 そして、ちょうど新型コロナウイルスの流行の始まりのタイミングだったこともあり、リモートで仕事ができるということも大きかったと思います。感染拡大に合わせて勤務場所や業務時間に融通を効かせられるようにルールを整備していて、従業員にしっかりと寄り添ってくれる会社だなと思いました。

ー Classiで働き始めて業務に関する意識の変化はありましたか?

正社員になってから感じた違いは、検証だけでなくClassi全社に関わる取り組みが重要視されることですね。第三者検証サービスの業務委託として働いている時は検証をすることがメインだったので、見る観点が違うんだなと思いました。

正社員だとQA情報を集めてどう活用していくのか、どういった観点で不具合が出ているのか、どうやったら不具合を減らせるのか、を探るということも期待されました。最初は不安で心配な気持ちも大きかったのですが、上司や先輩がしっかりとサポートしてくれてとても頼りになりました。今では「こんな改善をしてみたい」と自ら思えるようになりました。

全社に向けた取り組みの一例

Classiでの仕事内容を教えてください

Classiの学習領域で検証業務を担当しています。またQA情報を見える化する取り組みや、チームが抱えている不具合情報の棚卸し運用などのClassi内領域横断の取り組みも行っています。

ー 具体的なClassi全社の取り組みはどんなことをしているのですか?

品質情報の見える化を行っています。元々は検証結果をチケットとして報告するのみで、結果の傾向などを活用するまでには至っていませんでした。それらを見ることでどんな不具合が多い、どんな時に不具合が混入しやすいかが見えてくる これまでの不具合をダッシュボード化して「こんなところに不具合が多い」「この月は何件不具合があった」などを見える化して開発本部の全体発表をしています。

品質情報の見える化の一例

ー 学習領域の検証について具体的に教えてください。

学習領域は生徒さんが色々問題を解いたり、学力向上したり、よりよく勉強できるようにプロダクトを提供しようとしている領域です。 領域に専任QA担当を置くという形で行っており、仕様の部分から色々とキャッチアップできているので、QA観点としてはこうした方がいいのではということを上流工程から入ってやっています。

ー 専任QAについてもう少し詳しく教えてください。

専任QAは開発チームがアジャイル開発のスタイルをとりはじめたことに、QAチームも対応していこうと始めたチャレンジです。

元々のQAチームは開発の設計ミーティングなど上流工程には入らず、一通り作ってからQAチームが対応するという形でした。でもそうすると仕様もわからない、本当にやりたいこともわからない中でQA対応する状態でした。2020年後半から専任QAのデモ運用を開始し、2021年から正式に専任QAの体制にしていき、去年頃から全チーム専任QA体制となっています。

専任QAを置くことで上流工程からQA観点を入れることができるようになって、とてもやりやすいです。

Classiでの仕事の面白さや、やりがいについて教えてください。

ClassiのQAチームは、様々なことにチャレンジできる環境が整っている為、仕事をしながらいつもやりがいを感じています。 前職ではただひたすらに検証を行うのみでモチベーションが上がらないことが多々ありましたが、Classiでは品質情報の見える化や自動化ツールの推進など、検証業務以外にも積極的に取り組んでいて、今までやったことがない業務に取り組めて毎日仕事の面白さを感じています。

ー これまでに小林さんはどんなチャレンジをしてきたのですか?

品質情報見える化の取り組みなどですね。その他に、そういった取り組みの全体への共有や発表など、自ら手を上げて新しいチャレンジをしたいと言うと、受け入れて背中を押してくれる上司や先輩のサポート体制があると感じています。 これまでの仕事では検証のスキルしか上げていけないのではという不安がありましたが、今は運用の部分だったり発表だったり検証以外で成長できる機会が沢山あって、日々成長ややりがいを感じています。

ー ここは成長したなと思うところはありますか?

開発チームも巻き込んで、サービスの不具合を棚卸しして運用していることですね。 運用ルールを作ってみんなに展開し、実際に自分が主導で色々な人が関わる中の運用を回すことをしていますが、これまでの自分だったらそんなことできなかっただろうなと思います。しかも取り組みの結果、不具合が目に見えて減ってきて実績にも繋がっていて、やってよかったなと思うし成長を感じます。

ー なぜ色々なチャレンジができたと思いますか?

QAチームのサポートはもちろんですが、エンジニアさんやその他の方々も非常に協力的に動いてくれることが大きいと思います。不具合棚卸しも普通は面倒だと思うのですが、こんなに真摯に取り組んでくれるエンジニアさんはなかなかいないなと思っています。 毎月全体に共有している不具合報告についても「やってくれてありがとう」と言ってくれていて本当に良い環境だなと思っています。 そういったClassiの環境だからこそチャレンジができていると思っています。

社内発表の様子

Classiでの仕事の難しさや課題について教えてください。

教育系に関する用語やClassi独自の用語などが、入社した当初はどのようなことを指しているのかがわからず困ったことがあります。今は定着したのですが最初は話をきいてポカーンとなってしまったりしたこともありました(笑)

ー どのように克服しましたか?

社内のドキュメントを色々読んだり、ミーティングで出てきたタイミングで聞いたり調べたりしました。ドキュメントは沢山あるのですが、パッと網羅できるものはまだない印象もありそこは課題だと思っています。

ー 教育業界について知ることは難しいですか?どうやって学んだのですか?

教育業界の状況や学生の状況など最初はキャッチアップできなかったですね。 でもQAチームは学生の状況や、Classiを使う際にどこを見ているかなどわからないと正しくQAできないなと思いました。

最初はニュースなどのチェックをしていて、今は生徒さんのインタビューの場にオンラインで同席させてもらったりなどしてキャッチアップしています。 生の声を聞いて「こういうところが使いにくいと思っているんだ」と言うのもわかってきました。今後はもっと気軽にキャッチアップしていけるようにしていきたいと思っています。

働く上で大切にしていることは何ですか?

自分の仕事は、誰の為に・どんな形で役に立つかを考えることを大切にしています。

ー 今やっている仕事は誰のためにどんな形で役立っていると感じますか?

不具合があるところはもちろんシャキッとしないとと思いながら、エンドユーザーの不便に思っているところをなんとかしたい、そしてそれだけじゃなく開発の人たち、会社全体に対しても不便が減ったらなという思いも持っています。

エンドユーザーを頭におきながらそこにつながる社内の色々な人のことを想い、場面場面に合わせて誰にどう役に立ったらいいかを考えている感じでしょうか。

第三者検証をやっている時は「仕様通り動いている」というところだけをみてユーザーの声に耳を傾けられていなかったなと思います。今はエンドユーザーさんにこう使ってもらった方が良いということを見失わないようにしないといけないと思っていて、生徒さんのインタビューは本当に大切だなと感じています。

ー 今役立っている実感が湧くのはどんな時ですか

ユーザー観点で役立っている実感が湧いたのは昨年リリースしたCALE*2(個別最適化学習を実現するためのアダプティブラーニングエンジン)の事例ですね。自分も携わりQAチームとしても頑張ったリリースでした。 CALEを使って成績が上がったという声を聞いて実績に結びついているのはとっても嬉しかったです。 開発の方々や社内の観点ですと、運用、不具合チケット、情報の見える化の報告など、ちゃんとシャキッとしてくれて嬉しい!という声をもらったりして、役に立ってるんだなと感じてモチベーションもあがりますね!

最後にひとこと

私のインタビューを読んでいただきありがとうございます! 少しでもClassiにご興味を持っていただけたら嬉しいです!!


小林さんの積極的でポジティブな取り組みが社内で良いサイクルを回してくれています!次回もお楽しみに!

Classiでは「子どもの無限の可能性を解き放ち、学びの形を進化させる」というミッションに、ともに向き合っていただける仲間を募集しています。ご興味をお持ちの方は、 お気軽にお問い合わせください!

■採用ページ

corp.classi.jp

■各ポジションごとの求人

*1:第三者検証とは、ソフトウェア/システムの開発者ではない者が、第三者の視点から対象のソフトウェア/システム品質の検証・評価を行うことです。 第三者検証によって、当事者では気づかない不具合や欠陥を検出し、信頼性が高く高品質なソフトウェアを構築する事が可能です。

*2:現在は学習トレーニング機能を通して提供されています。

GitHub Actions と Release Please を使ったアプリケーションのリリース自動化

GitHub Actions と Release Please を使ったアプリケーションのリリース自動化

こんにちは @lacolaco です。最近は、先日プレスリリースが出された「学習トレーニング」機能を裏で支えているコンテンツ管理システム(以下内部CMS)の開発に携わっています。

corp.classi.jp

この記事では、内部CMSのフロントエンド(Angular アプリケーション)のリリースフローを自動化している仕組みを紹介します。現在のリリースフローの全体像は次の図のようになっています。この中にある Release Please というのが、今回特に紹介したいツールです。いくつか日本語でのブログ記事などもあるので特にマイナーというわけではないと思いますが、多くの場合はライブラリのリリースに使われています。一方、アプリケーションのリリースで使っているケースはあまり発信されてないように思われたので、この記事が事例の一つとして参考になれば幸いです。

Release Please

Release Please は Google がOSSとして公開しているツールのひとつです。READMEに書かれているように、このツールではGitレポジトリのコミットログをもとにしてCHANGELOG ファイルの生成・GitHub Releases の作成・プロジェクトのバージョン更新などを一挙に自動化してくれます。

github.com

Release Please automates CHANGELOG generation, the creation of GitHub releases, and version bumps for your projects.

Release Please の仕組みは Conventional Commits をベースとしており、レポジトリのコミットログを Conventional Commits の仕様に準じて解析します。 前回のリリースバージョンから最新のコミットまでの間に、 fix や feat のように「リリースする必要がある変更」があれば、Release Please はリリース用のプルリクエスト(リリースPR)を作成します。リリースPRはデフォルトだと次のようなものです。

https://github.com/googleapis/release-please より

リリースPRには次回のリリースに含まれる変更内容が CHANGELOG として記述されており、開発ブランチに新たなコミットが追加されればそれに追従して更新されます。このプルリクエストをマージすることで、レポジトリの CHANGELOG.md やバージョンファイルが更新され、GitHub Releases も作成されます。

Release Please 自体は単なるCLIツールなので、GitHub上のレポジトリでは release-please-action を使うのが便利です。これも Google が公開しているもので、簡単なセットアップでレポジトリの GitHub Actions に Release Please を導入できます。

github.com

ここからは具体的にrelease-please-actionを導入するためのステップを説明します。

release-please-action の導入

Release Please はその仕組み上、レポジトリのメインストリームとなっている開発ブランチのコミットを追跡する必要があります。以後は main ブランチを対象に考えますが、それぞれのレポジトリの事情に合わせて読み替えてください。まずは、Release Please を実行するワークフローファイル .github/workflows/release-please.yml を作成します。次の例のように、 main ブランチへコミットがプッシュされるたびに実行されるようにトリガーを設定し、 google-github-actions/release-please-action アクションを呼び出します。

name: release-please

on:
  push:
    branches:
      - main

permissions:
  contents: write
  pull-requests: write

jobs:
  release-please:
    runs-on: ubuntu-latest
    steps:
      - uses: google-github-actions/release-please-action@v3
        with:
          release-type: node
          package-name: my-app

google-github-actions/release-please-action アクションは振る舞いをカスタマイズするオプションがたくさんありますが、たいていの場合で最低限必要なのはプロジェクトの種類を指定する release-type と、プロジェクト名を指定する package-name です。今回は Angular アプリケーションのリリースのためにセットアップするので、 package.json のバージョンをリリースバージョンとして使うために release-type: node を指定しています。Node.js以外の場合や、Monorepoの場合などはまた違った指定になるので、READMEを頼りに適切な設定をしましょう。

このワークフローだけでリリースPRの作成ができたので、CHANGELOG.md ファイルの更新・バージョンファイル(この場合は package.json の version)の更新・GitHub Releases の作成が行われるようになりました。しかし、これだけではアプリケーションのデプロイが実行されていません。

今回のアプリケーションは、Amazon S3に格納したファイルをAmazon CloudFront によって配信しています。GitHub Actions からデプロイするためには、Angular アプリケーションをビルドし、その成果物をAmazon S3へアップロードするステップが必要です。リリースPRのマージ後にこれらのプロジェクト独自のステップを追加で実行するため、もう少しワークフローを記述します。

リリースPRマージ後のデプロイ実行

google-github-actions/release-please-action が作成したリリースPRがマージされると、当然ですがマージコミット(以後リリースコミット)がプッシュされます。このリリースコミットに対しても release-please ワークフローが実行されますが、リリースコミットに対して実行されたときに限って release_created という特別な出力を持ちます。この出力を読み取ることで、リリースPRがマージされたあとにだけ実行したいジョブを記述できます。

次の例のように、google-github-actions/release-please-action を呼び出したステップの出力を release-please ジョブの出力として再定義し、次の deploy ジョブの実行条件に利用します。 needs フィールドでジョブの完了を待ち、 if フィールドでリリースコミットのときだけ実行されるようにしています。

name: release-please
on:
  push:
    branches:
      - main
jobs:
  release-please:
    runs-on: ubuntu-latest
    outputs:
      release_created: ${{ steps.release.outputs.release_created }}
    steps:
      - uses: google-github-actions/release-please-action@v3
        id: release
        with:
          release-type: node
          package-name: my-app

  deploy:
    runs-on: ubuntu-latest
    needs:
      - release-please
    # リリースコミットに対してのみ実行する
    if: ${{ needs.release-please.outputs.release_created }}
    steps:
      - uses: actions/checkout@v3
      - ... # Amazon S3 へのアップロードなど

このようにワークフローを定義することで、Release Please が提供するデフォルトの機能に加え、プロジェクト独自のステップを加えたリリースフローを自動化できます。

リリースの流れ

このワークフローがあることで、普段は次のような開発からリリースまでの流れになっています。

  • main ブランチからトピックブランチを作り、コードを書いてコミットする。
  • 変更がまとまったところでプルリクエストをつくり、後に main ブランチにマージする。
    • 当該のレポジトリでは常に Squash Merge をするので、マージコミットのメッセージで Conventional Commits に従う。
  • main ブランチにリリースが必要なコミット(fixやfeat)がプッシュされると、リリースPRが作成される。
    • まだ追加の変更を加えたい場合はそのままにする。
  • リリースする内容が固まったら、リリースPRをマージする。
    • あとはすべて自動でリリースフローが進行する。

コミットメッセージのルールを守ることと、リリースPRをマージする作業以外は自動化されており、レポジトリへの書き込み権限さえあれば誰でもリリースを開始できます。

緊急時の手動リリース

型化され自動化されたリリースはすべてがうまくいっている間は便利ですが、時には例外的なリリースをすることもあります。リリース直後に致命的な問題が発覚したときなど、なんらかの理由で過去のバージョンをリリースし直す必要が生まれます。そのようなケースに備えて手動で任意のバージョンを再リリースできる脱出ハッチも用意しています。

手動リリース専用のワークフローファイルを作成し、実行トリガーに workflow_dispatch を指定します。このトリガーは GitHub のWeb画面やAPI経由などから呼び出せて、呼び出し時に入力変数を渡すことができます。この入力として ref を受け取っており、任意の Git コミットへの参照を渡します。Release Please のリリースコミットにはそのリリースのバージョンが Git タグとして紐づいているため、任意のバージョンへのロールバックが簡単にできます。

name: manual-deploy-production
run-name: Deploy Production from ${{ inputs.ref }}

on:
  workflow_dispatch:
    inputs:
      ref:
        description: 'Git ref to deploy (e.g. main, v1.0.0, c91ee3c, etc.)'
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ github.event.inputs.ref }}
      - ... # デプロイ処理

まとめ

学習トレーニング機能の内部CMS開発でリリース自動化のために活用している Release Please の紹介をしました。似たような機能を持ったツールは他にもありますが、Google 製であり、多くのOSSのリリースで使われていることから長く使えそうだと感じて採用しました。実際に使ってみるととてもよくできていて、今回はあまり説明していませんがMonorepoへの対応が充実しているところにはGoogleらしさを感じています。(内部CMSとは別のレポジトリでは実際にMonorepoで管理している社内ライブラリのリリース自動化にも使っています)

ところで、Release Please のバージョニング規則はデフォルトで Semantic Versioning (Semver)に従いますが、ライブラリはともかくアプリケーションのバージョンに Semver は合わないだろうという意見はあるだろうと思います。内部CMSのフロントエンドでは Semver をそのまま使っており、これは「何をもって破壊的変更とするか」の基準によって、アプリケーションのリリースにおいてもそれなりに意味のあるバージョニングができるように感じているからです。具体的には、内部CMSのフロントエンドでは「アプリケーションの使い方を学び直さないといけない」ような変更をアプリケーションにとっての破壊的変更とみなして運用しています。ロジカルではないですが、この基準であればUI設計やユーザーストーリーの定義の時点で判断できますし、リリース内容をユーザーにアナウンスする上では変更の規模を伝えるサインとして十分に機能すると考えています。

もしアプリケーションやライブラリのリリース自動化のツール選びで困っている方がいれば、ぜひ Release Please を一度試してみてください。

In-App Reviewで荒廃したアプリ評価が爆上がりした話

突然ですが、観た映画やドラマやアニメなどがすごく面白くて世間の評価はどうなってるんだろうとレビューサイトを見てみたら、思いのほか評価が悪くてしゅんとなった経験はありますか?ちなみに僕はあります。

ご挨拶が遅れてごめんなさい、こんにちは!Classiでモバイルエンジニアをしています、楠瀬大志(id:indiamela)です。

今回はIn-App Reviewを用いて弊社のAndroidアプリの評価が1.8→3.7まで爆上がりしたお話をしたいと思います。
In-App Reviewを簡単に説明すると、アプリ内で任意のタイミングでアプリのストアレビューを依頼できる、というものです。わざわざストアを立ち上げて該当のアプリページに遷移してから評価するという煩わしさと比べてアプリ内でポジティブな体験を得た直後にレビュー依頼できるのが強みです。また、その施策がユーザーに受け入れられているかを測る指標としても有効だと思います。

ユーザー視点でのアプリ内レビューのフロー

また、アプリ評価に関してはGoogleが近年信頼できる適正な評価を目指していて、しっかりとガイドラインが設けられています。過度なレビュー依頼や先に高評価してもらえそうか質問してからの訴求やポイントを付与してからの評価依頼などは以前はよくありましたが、それらはNGとなっています。

アプリ内レビューをリクエストするタイミング. ユーザーにアプリ内レビューをリクエストするタイミングを決める際は、次のガイドラインに従ってください。

有用なフィードバックが得られるように、ユーザーがアプリやゲームを十分体験してから、アプリ内レビューのフローを開始する。
ユーザーに過度にレビューを求めない。この方針により、ユーザーの不満を最小限に抑え、API の使用量を抑えます(割り当てに関するセクションをご覧ください)。
評価ボタンや評価カードを表示する前または表示中に質問をしない(「アプリを気に入りましたか?」といったユーザーの意見に関する質問や、「このアプリを 5 つ星と評価していただけますか?」といった予断を与える質問)。

私は自己紹介する時に「アプリレビューが荒れている事でおなじみのClassiでアプリエンジニアをやっております」と自虐ネタを言う事がありました。悲しい事にClassiのアプリの評価は低い状態でした。ユーザーからしてみたらダウンロードするのをためらってしまうレベルだと思います。勿論この結果には原因があるので真摯に向き合って解決していかないといけません。その施策の1つとしてClassiホームを最初にリリースして以来、ずっと課題だった「兄弟姉妹を持つ保護者のアカウント切り替えが面倒」という課題を解決するマルチアカウント機能を今年の3月にリリースしました。

Classiホームは初の保護者も対象にしたアプリだったのですが先程もお伝えした通り、リリース以来ずっと「簡単にアカウントが切り替えられるようにしてほしい」という要望を多く頂いていたため、これはユーザーに受け入れられる機能だと自信を持って言える状態でした。そのため、In-App Reviewを活用することでストアの評価の改善も合わせて行うことにしました。。過去に一度In-App Reviewの施策を行ったことがあり、十分な効果を得られた実績があったため、今回も十分な効果が見込めました。In-App Reviewは表示テストが非常に面倒です。会社のGoogle WorkSpace(旧G Suite)アカウントではストアから内部テスト版でリリースしても表示されないのでテスト用の@gmail.comアカウントを用意する必要があります。

In-App Reviewの実装自体は数行で終わる簡単なものですが、前述のテストの実施が手間な点と、どのタイミングでユーザーにレビューをお願いするかが重要です。Googleの定めるガイドラインに、

有用なフィードバックが得られるように、ユーザーがアプリやゲームを十分体験してから、アプリ内レビューのフローを開始する。

とあり、この「十分体験してから」とは何かを科学する必要があります。この方法論については様々なアプローチがあり、頭を悩ませるところです。

  • 時間(利用している時間帯や累計のアプリ起動時間など)
  • 回数(〇〇の機能をn回利用しているやコンバージョンに紐づくアクションの回数など)
  • ユーザー属性(Classiなら先生か生徒か保護者かなど)

色々とチームで検討した結果、今回はシンプルにアカウント切り替えをn回行った時に表示するとしました。このnに代入する数字についても議論がありましたがRemoteConfigを使っていつでも変更できるようにして一旦5回としました。
一般的に…という表現が適切か分かりませんが、コンバージョンに紐づくアクションを2〜3回繰り返し行ってくれたら表示させるケースが事例としては多いですが、アカウントの切り替え自体が簡単な操作な済んでしまう為、5回ほどアカウント切り替えを体験したもらった方がより適切な評価をしてもらえるだろうとチームで話し合いました。さて結果は・・・.

リリース後、一定期間が経ってから評価が急上昇しました。この一定期間は恐らくアカウント切り替えを5回実行するに達するまでの期間と読んでいます。面白い事に高評価が増えて低評価が減るという非常に理想的な推移を見せました。なかなかこんなに分かりやすく結果が出る事ってあまりないですよね。

上手くいったら上手くいったでなぜ上手く行ったのかも考えてみたいところです。先述の通り、兄弟姉妹を持つ保護者はアカウント切り替えが面倒なので簡単にアカウントが切り替えられるようにしてほしい、というご要望を多く頂いていましたが、その期待に応えられる機能を提供できたのではないかと思います。そして適切なタイミングでレビューを促す事ができたのも大きいはずです。一方で同じ施策をiOSでも行いましたがAndroidほどの劇的な成果は現状出ていません。
その原因として考えられることは2つあります。1つは、レビュー訴求の体験自体がiOS/Androidで違っていることです。レビュー訴求の表示/非表示はある程度OSによって制御されているので、狙ったタイミングで必ず表示されるとは限りません。iOSの訴求方法がダイアログなのに対して、Androidはボトムシートな点も訴求力に差があるのではないかと考えられます。

このように下から出てくるのがボトムシートです。ハーフモーダルや半モーダルとも言われています。ダイアログと比べて画面占有率が高いのとAndroidだと比較的ハーフモーダルの概念が新しめである事も関係しているかもしれません。

もう1つ考えられる原因は、シェア率の違いです。生徒はiOSのシェア率が圧倒的に高いですが、保護者はAndroidのシェア率が高いです。今回の施策でAndroid利用率の高い保護者の不満は解消された一方、生徒の利用率も多いiOSは別の理由から低評価をされているのではと考えられます。

と、ここまで書いてきていきなりGoogle Playの評価が1.0に爆下がりしました。タイトルに偽りありなのでこの記事はお蔵入りになるかもしれません。こんな事ってありますか?何らかのバグである事を願うしかありません(その後、1日経ったらほぼ元に戻りました。よかった!)

稀にこういう事もあるのでアプリの評価はあくまで1つの指標に留めておく方が良いと思います。とは言えアプリの評価が突然理不尽に下がるのは死活問題なので常に監視は続けていかないといけないですね。

In-App Reviewでわかった事を一言で表すと

アプリ内レビューは局地戦である

冒頭の質問にあるように私だったら自分が面白いと思った映画を観て感情が盛り上がってるタイミングで評価を付けて下さいと言われたら⭐️5を付けるかもしれませんが、レビューサイトを見てから評価をして下さいと言われたらもしかしたら⭐️4くらいに下がるかもしれません。

それは批判的なコメントで「言われてみれば確かに・・・」とあまり自分で気付けていなかった部分に気付けた場合や時間が経って冷静になって総合的な評価を出せるようになった為です。

もちろん映画もアプリも「面白い」や「使いやすい」というポジティブな体験を提供できたという前提ではありますが、その感情のままシームレスに評価してもらう、というのが重要に感じました。

このブログを読んでくださっている方々の中でアプリの評価が伸び悩んで困っている方は是非In-App Reviewの導入をおすすめします。その際はアプリを使っていて嬉しいポイントをユーザーの顔を思い浮かべながら考えてみて下さい。

中立的なGraphQLスキーマの管理

こんにちは、id:aerealです。

今回はGraphQLのスキーマ管理を工夫している点について紹介します。

背景

対象となるアプリケーションは先日プレスリリースが出された学習トレーニング機能を裏で支えているコンテンツ管理システム (以下、内部CMS) で、エンドユーザ向けを含む複数のサービスから呼び出されます。またAngularで書かれたWeb UIを備えます。

内部CMSを開発するチーム内には主にサーバサイドを担当するメンバーと、主にクライアントサイドを担当するメンバーとがおり、どちらもGraphQLを用いた開発経験があります。

この内部CMSはスクラッチから開発を始めており、目指すリリース予定日に対してやることは山積みなのでうまくタスクを分担したい状況にありました。

時と場合によってはクライアントサイドのチームの手が空いていたりあるいは逆になったり、状況は目まぐるしく変わります。

ですから手が空いた方がスキーマの設計に手をつけられるような分業体制を整えるモチベーションが強くあります。 *1

つまり スキーマの管理を特定のチームやコンポーネントに寄せず、責任・主導権を関係者の誰もがとれる ようにすることを狙って設計しました。 この点を指してタイトルにあるように「中立的な管理」と表現しています。

これから具体的な手法について紹介しますが、同等のコードを含むリポジトリを公開しましたのでぜひこちらも併せてご覧ください: https://github.com/classi/example-graphql-api-schema

内部CMSの構成

クライアントサイドはフレームワークにAngularを、GraphQLクライアントにはApollo Clientを採用し、TypeScriptで書かれています。

TypeScriptの型生成にはGraphQL Code Generatorを使っています。

サーバサイドはGoで書かれておりフレームワークの類は採用せず、標準のnet/httpのみでHTTPサーバを書いています。 GraphQLのサーバサイド実装およびコード生成はgqlgenを使っています。

スキーマの配置

クライアントサイド・サーバサイドのどちらからも中立させるためにスキーマは独立した単体のリポジトリに配置します。 簡便のため以後の文中では単に「スキーマリポジトリ」と呼びます。

スキーマリポジトリではGitHub Package RegistryのNPM registry (以下、単にGitHub Pacakge Registry) を介してスキーマファイルを含んだNPMパッケージを配布し、スキーマを利用するリポジトリはこのNPMパッケージを利用します。

後述するリリース関連のスクリプトや各種設定ファイルを除けばスキーマファイルのみが置かれています。 以下はファイル配置をtree(1)で出力したものです:

# tree --gitignore
.
├── LICENSE
├── README.md
├── analyzer
│   └── requireauthorize
│       └── checker.go
├── go.mod
├── go.sum
├── graphql.config.yml
├── index.ts
├── package-lock.json
├── package.json
├── schemata
│   └── main.gql
├── tools
│   ├── analyze
│   │   └── main.go
│   └── generate-manifest
│       └── main.go
└── tsconfig.json

開発者はスキーマファイルを変更するPull Requestを送り、関係者のレビューを経てマージされたあと新しいNPMパッケージがリリースされます。

スキーマのリリース

前述の通りスキーマはNPMパッケージとして配布されます。

このリリース手順は自動化されており、変更したい開発者の視点では単にPull Requestを送りマージするだけで新しいスキーマが配布されるようになっています。

既存のOSSを参考にsemantic-releaseを使って新しいバージョンの発行とGitHub Package Registryへの公開を自動化しています。

開発者に求められるのはConventional Commitsに従ったコミットメッセージを書くだけです。

Conventional Commitsを内部向けリポジトリに採用することへの懐疑や批判を抱かれる読者もいるかもしれません。

今回取り上げる内部CMSのスキーマリポジトリでは単に「semantic-releaseによって新しいバージョンを発行するための規約」としてConventional Commitsに従っているものとしており、厳密なsemantic versioningに従うものではないということを合意しています。

つまりごく単純化すれば「新しくバージョンとしてリリースしたい変更を含む場合は fix:, feat: などのタグをつける」「それ以外のリリースフローの改善などのみを含む変更はその他のタグ (e.g. chore:, build:, etc.) を使う」というルールしか強制しません。

いずれにせよシステムに変更を加える際には動作確認をすることを前提としているので「後方互換性を保つかどうか」といった含意を重視してないということです。

スキーマの利用

GitHub Package Registryは対応するリポジトリ自体の公開範囲とは別にパッケージ自身の公開範囲を定義できます。

たとえばリポジトリXからは読み取り (= インストール) のみ許可し、リポジトリYには加えて書き込み (= アップロード、新規リリース) を許可する……といった風です。

我々の内部CMSにおいてはクライアントサイド・サーバサイドそれぞれのリポジトリに読み取り権限を許可し、スキーマリポジトリに管理権限を許可しています。

読み取りたいリポジトリのGitHub Actionsワークフローで packages: read の権限を与えると、リポジトリが読み取りを許可されているパッケージをインストールすることができます。

これら詳細についてはPublishing and installing a package with GitHub Actions - GitHub Docsを参照してください。

もし単にGit submoduleやworktreeを用いてリポジトリを参照しようとすると現時点のGitHub Actionsないし類似のCIサービスでは、より複雑かつ潜在的な危険性を孕んだ構成が求められます。

細やかな権限付与により安全でありながら、利用する際に複雑な設定の既述や手順が求められないためGitHub ActionsとGitHub Pacakge Registryを採用しています。

Goで書かれたサービスでNPMパッケージを利用する?

クライアントサイドはパッケージレジストリのエコシステムとしてのNPMに既に乗っているから良いとして、Goで書かれたサーバサイドのリポジトリではどうするんだ? という疑問をお持ちかもしれません。

答えとしては「Goで書かれたサービスのリポジトリであってもpackage.jsonを置けば良いじゃない」というものになります。

おもむろに npm i -D @classi/example-graphql-api-schema (パッケージ名は例です) すれば node_modules/@classi/example-graphql-api-schema/schemata/main.gql が手に入ります。

gqlgenの設定ファイルでスキーマのパスをこれに揃えておけば、問題なくコード生成もできます。

サーバサイドのリポジトリを扱う際にもNodeやNPM/Yarnが必要になりますが、Classiの開発者はWebアプリケーションエンジニアですから大した支障にはなりません。

ローカル環境にインストールする

各開発者のローカル環境にインストールする際には公式のAuthenticating with a personal access token - Working with the npm registry - GitHub Docsというドキュメントに従います。

Classic Personal Access Tokenを発行し、npmrcに「npm.pkg.github.com を参照する際はこのclassic PATを使え」という設定を既述することで認可されインストールできます。

執筆時点ではGitHub Package Registryの認可にFine-grained PATsは対応していません。

Fine-grained PATsは必要最小限の権限のみを付与できるのに対してclassic PATsは大雑把な権限付与しかできないので漏洩したり誤用した時のリスクは大きくなります。

具体的には「リポジトリコンテンツの読み取り」という権限が少なくとも必要になりますが、対象リソースを絞れないので PATの所有者が権限をもつすべてのリポジトリを読み取れる ということになります。

相対的にリスクはあるものの、classic/Fine-grained共にPATの利用を追跡する仕組みがGitHubにより提供されていることもあり、利用を渋るほどではないと評価して呑んでいます。

Fine-grained PATsは若い機能で継続的に改善されているので、今後の改善に期待したいところです。

今後の改善点

classic PATs脱出

ローカル環境へのインストールにはclassic PATsが必要で、classic PATsはセキュリティ上の懸念があるということは既に述べた通りです。

これはGitHubがFine-grained PATsに対応させるしか本質的解決を望めないので座して待っています。

Renovate対応

依存パッケージの自動更新をしてくれる[Renovate]ですが、開発・提供するMendがホスティングするGitHub Apps版ではGitHub Package Registryでホストされているパッケージの更新にはPATが必要です。 これは前述のclassic PATの懸念に加え、[machine user]のPAT管理という新たな問題も生じます。

これはGitHub Package Registryの認可の仕組み上、仕方のないことではあります。

現時点では、スキーマをインストールする各リポジトリのGitHub Actionsワークフロー内でRenovateを実行するとこの制約を回避できます。

ただSaaS版と共存させようとすると煩雑で、GitHub Actionsで実行するということは、managedにせよself-hostedにせよrunnerの計算機資源を消費することになり、SaaS版と比べてクレジット消費増加やインフラコストの増加に繋がります。

我々はスキーマの利用者と密にコミュニケーションできる体制なのでRenovateによる自動アップデートを諦めています。 スキーマの利用規模が大きい組織ではこの問題はより深刻になるかもしれません。

むすび

我々が開発・運用している内部CMSで扱うGraphQLスキーマの管理・運用について紹介しました。

とても凝っているという印象を受けたでしょうか? あるいは意外と普通だなと感じましたか?

実際、筆者としては特別新規性のあることはやっていないと考えています。実はこうしたワークフローの設計・整備は特にOSSではよく見られるものです。

近年は、semantic-releaseのようにコモンセンスになっていたワークフローをロジックとして実装したソフトウェアや、内部向け用途にカスタマイズされたGitHub Package Registryなどの登場により、内部向け固有の要求を満たしつつ慣れ親しんだワークフローを実現しやすくなったと感じます。

また自動化されたワークフローとはワークフローがコード化されていることとほぼ同義です。

ソフトウェアエンジニアにとってコード化されたソフトウェアほど雄弁な文書はないというのが持論ですが、コード化されていれば変更を提案しそれを直ちに普及させることは、素朴な慣習や自然言語によるルールより、圧倒的に省力で済むのは間違いありません。

この記事で紹介したワークフローを提案し実装したのは主に筆者自身ですが、自動化されて考えることが少ないワークフローが整備されていることによって、実際に慌ただしい時にそのありがたみを感じることができました。

なにより便利さと「やりすぎなさ」のバランスをとりながらワークフローを設計するのはとても楽しい時間です。

エコシステムの成熟に感謝しながら、ぜひ身近なワークフローを自動化してみませんか?

*1:また、今回は深く触れませんがスキーマ駆動開発の実践として、モックレスポンスの生成・利用もしておりサーバサイドの実装を待たずにクライアントサイドの実装を進める余地があったことも手伝っての判断です。

SRE留学で体感したプロダクトチームとSREチームの違い

こんにちは。プロダクト開発部の id:ut61z です。

私は 2022/10 からSRE留学という社内制度を利用して、SREチームに所属しています。弊社のSRE留学制度については以下のliaob88さんの記事に詳しいので興味がある方は御覧ください。

tech.classi.jp

もともとバックエンドエンジニアとしてRailsのアプリケーション開発を行っていましたが、運用の一環でアプリケーション実行環境をEC2からECSへ移管する経験をし、それを皮切りにインフラ、AWS、SRE、DevOps などに興味を持ちました。

あるとき上司にSRE留学をしてみない?と提案されたのをきっかけに、自分でもできるのか?と不安を抱きながらもおもしろそうだなという感情が勝り、SRE留学を希望しました。

この記事では、実際に日々の業務を行っていくなかで感じたプロダクトチームとSREチームの違いや、ソフトウェアエンジニアとSREの業務の性質の違いについてなどを挙げていきたいと思います。

普段プロダクト開発に従事しているけれど、SREはどのようなことをしているのか?興味はあるけど専門知識が必要でハードルが高いのでは?といった疑問に対してなにかヒントになれば幸いです。

日々の仕事の進め方

日々の仕事の進め方は、プロダクトチームとSREチームでほぼ差異はないと言っていいでしょう。

今はカンバンでタスク管理をしていて、毎朝優先度の高いものを確認し、上から順に取り組むというスタイルで進めています。月に一度タスクのリファインメントを行い、優先度の見直しも行います。また、隔週で振り返りを行い、2週間で起こったできごとをベースに次の2週間でトライすることを定めて、業務のカイゼンにつながるように努めています。

タスクの性質

SREチーム特有の性質として、各プロダクトチーム、あるいは他部署からの依頼やシステムアラートなど、リアクティブに反応するようなタスクが比較的多いということが挙げられるでしょう。

  • インフラリソースの追加・変更・削除 (Terraform修正) のレビュー
  • 各チームから依頼を受けて行うSRE管轄のインフラリソースの操作オペレーション
  • システムアラートや障害発生時の対応
  • その他インフラに関する相談受付

SREは、サービスの信頼性を維持しつつ、プロダクト開発を行うエンジニアがより安全に素早く開発を行うことをサポートする責務があるため、直接的なフィードバックを得る「顧客」は、サービスのユーザーであると同時に、プロダクト開発を行うエンジニアでもあります。

誰に価値提供を行うか?という点でプロダクトチームがサービスユーザーであるのに対して、SREはプロダクトチームのエンジニア(の比率が高い)という捉え方もできるでしょう。

チームトポロジーでいうところの、ストリームアラインドチームとプラットフォームチームの違いと言い換えることもできそうです。

それ以外にも、トイルになりがちな、利用している各外部サービスとの契約、見積、アカウントの作成、権限付与なども行っています。このあたりの作業は、自動化したり、権限を渡して各チームでできないかというのを模索している最中で、エンジニアリングが求められるところだと感じています。

インフラ知識

言わずもがなですが、SREはインフラ知識が必要で、プロダクトチームのソフトウェアエンジニアより多くのそれを求められます。

しかし、SRE留学をしてみて逆説的に体感したのは、プロダクト開発においてもインフラ知識は必要だということです。

SREとして相談を受ける立場に立ってみると、要求を実現するための要素としてインフラ知識は一定欠かせず、インフラとアプリケーションを総合的に考慮したうえでの意思決定が求められるシーンがあると感じました。

「これを実現したいからインフラについてこうしようと考えている」という相談ができるような知識がプロダクトチームにあると、SREはそれに対する適切なフィードバックをしやすいです。少し話はそれますが、そういったプロダクトチームになるために、SREとプロダクトチームのエンジニアで接点を持つ機会を増やすべく、まさにSRE留学を含めたいくつかの施策をSREとして行っています。

プロダクトの知識

逆にアプリケーションの振る舞いや、ドメイン知識、事業戦略などについてプロダクトチームのみが知っているべきで、SREは知らなくてもよいかといえば、それもNOだと言えます。

インフラ設計や、SREingを実践していくうえで、それらのプロダクトの知識もまた必要不可欠だからです。

とはいえ、各チームが担当するすべてのアプリケーションの振る舞いを詳細に把握するのは現実的ではないでしょう。とくにClassiは、様々な機能を提供しているので全体像を把握するだけでも一苦労です。

ただ、各プロダクトチームから相談を受けることで、俯瞰的にプロダクトを見ることができるのもSREチームの特徴だと感じました。SRE留学前の一プロダクトチームに属しているときの自分では、そこまで解像度が高くなかった別チームの機能についても、インフラ面でのサポートやTerraformのPRレビューを通して理解を深めることができました。

システムアラート

システムアラート対応はSREだけが責任を持って対応しているかというと、弊社の場合はそうではありません。プロダクトチームのエンジニアであっても、即座に気づいた人が反応します。自チーム/他チーム問わず、まずはなにか起きれば反応して有識者を募れる組織だと言えます。

そのような姿勢は以下の記事でも紹介されています。

tech.classi.jp

システムアラートの発生から各チームのエンジニアが協力して最速で解決を目指すという姿勢は、SREの立場に立ってみると改めてとても頼りになります。

そもそもアラートのためのモニタリング設定や、すぐに切り戻しができるようなデプロイパイプラインの構築などがプロダクトチームで当たり前にできているからこそ、そのように反応ができる状態に至っているので、単にシステムアラートに反応するということを超えて、SREingがプロダクトチームに浸透していることを実感します。

システムアラートへの反応及び信頼性への意識については、SREとプロダクトチームで差異はないと言えるんじゃないでしょうか。

違いに注目することで見えてきたもの

いくつかプロダクトチームとSREチームの違いを挙げてみましたが、SRE留学を通じて私が感じたのは、プロダクト開発・運用の一側面を担っているという観点においては、SREチームもプロダクトチーム(の亜種)のような存在ではないかということです。

実はSRE留学をする前は、SREと聞くと特殊な領域で作業する特殊な技術分野に尖った"専門家集団"のような印象があり、少し敷居が高かったのですが、中に入ってみると、プロダクトをよりよいものにするという目的下において、SREチームはプロダクトチームと地続きな存在では?という印象に変わりました。

また、プロダクトをよりよくするには、インフラの知識やSREingのスキルやマインドセットがどうしても必要になってくるという逆の視点からも、プロダクトチームとSREチームは地続きな存在だと言えそうです。

もちろん違いもあり、さきにあげたように、プロダクトチームはストリームアラインドチーム、SREチームはプラットフォームチームという捉え方もできるので、業務の性質として異なる点もあります。たとえば、特定のインフラリソースの取り扱い方のポリシーを定めてそれに則ってもらうように働きかけるなどです。

そういった意味ではSREチームはプラットフォームチームとして、全体最適が図れるような動きが求められ、プロダクトチームはストリームアラインドチームとして、顧客価値を最大化するために、絶えずプラットフォームチームにフィードバックする動きが求められます。

さいごに

SRE留学を通して感じた、プロダクトチームとSREチームの違いを列挙してみました。

しかし、違いについて深堀りしていくと、そこには共通性があり、両チームは断絶されたチームというよりは地続きであるという視点が得られました。

Classiでは仲間を絶賛募集しています!SREをキャリアの選択肢として考えている方や、SRE留学制度のような組織文化に興味を持っていただけた方などなど、ぜひカジュアル面談などでお話しましょう!

【開発者インタビュー #2】藤田 勇希

こんにちは!Classiで働く開発者インタビューシリーズ企画の第二弾は、プロダクト開発部の藤田さんです。

まず簡単に自己紹介をお願いします

藤田勇希と申します。 仕事でもプライベートでも「ゴリラ」か「ハシビロコウ」の画像をアイコンにすることが多く、社内でも「ゴリラアイコンの人だ」というような認識をされているかもしれません。

藤田さんといえばゴリラのアイコン

経歴は、音楽・書籍・コミックのようなコンテンツ配信サービスのバックエンドの開発に、新卒から約5年間携わりました。 その後、スペースシェアのCtoCサービスのバックエンド開発・運用を2年ほど行ってきました。

Classi には 2021年7月にジョインして、この4月にリリースされた「学習トレーニング」のコンセプト検証を目的とした前身サービスの開発に関わりました。

ー これまでどんな軸で転職をしてきたのですか?

それぞれの転職のタイミングで大切だと思う軸が変化しています。

1社目から2社目はエンジニアとしてもっと挑戦的な立場で、スタートアップでの青春を味わいながらエンジニアとしての力量をプロダクトに直結させたい、という思いが強かったです。Classiへの転職の際は、スタートアップでの青春の卒業をし、次なるチャレンジをしたいと思っていました。あとは待遇や働く環境というところも気にしていたと思います。

Classiへの入社経緯、入社理由は?

最初は転職エージェントを経由してClassiに出会いました。そして、EdTechという難しい業界でマネタイズができている点や「学校教育」という社会貢献性が高い問題に携われることに魅力を感じて入社を決めました。 ジョイントベンチャーとしての土台があってスタートダッシュができた結果、成長してきたという納得感もありました。(参考資料:Classi会社紹介資料

ー 元々教育に興味があったのですか?

EdTechは前々から面白そうだと思っていました。

自分の人生を振り返った時に、学生時代の大部分を勉強のみに費やしたことに後悔のようなものがあるんです(笑) 勉強はもちろん大切だし今にも繋がっていますが、勉強以外にも大事なことって沢山あったなと。 なので、もう一度やり直して自分を変えられるとしたら教育なのでは思っています。将来の子どもたちには、私の数倍の効率で学力を得ることができて、残った時間を勉強以外にも使って有意義に過ごしてほしいなと思います。そして、自分と同じように学生時代を後悔する人が少しでも少なくなるような教育にすることが出来たらいいなと思っています。

また、前回のonigraさんのインタビューブログの中で機会の均等化の話があってすごく共感しました。貧富の差によって教育の優劣がつく状況を打破したいですね。

Classiでの仕事内容を教えてください

学習領域のプロダクトのバックエンドを中心に機能開発・運用を担当しています。 ユニットリーダーとして、学習領域のエンジニアが抱えるテックイシューへの取り組み、メンバーのコーチングなども行っています。 業務の割合としては、大体、9割が開発業務で、1割がユニットリーダーとしての仕事だと思います。

ー 学習領域についてもう少し具体的に教えてください。

「学習領域」とは Classi が提供するサービスや機能の中でも

  • 生徒に取り組んでもらう問題コンテンツを提供する
  • 生徒の苦手・得意に応じておすすめの問題を提供する
  • 模試に向けての対策テストを提供する

といったように、「学習」の体験を高めることを目的とした領域です。 この領域では、実際に生徒に解いてもらう各教科・単元の問題コンテンツを制作するシステムや、制作した問題コンテンツに Classi のサービスを使って取り組めるような機能の開発などをしています。

現在、私は Classi が提供するこの大事な問題コンテンツを、高い品質で制作できるように支援する社内サービスの開発を行っております。

ー ユニットリーダーとしてどんなことをやっているのですか?

ユニットリーダーとしてはメンバーと1on1をしたり日々のケアをしたりしています。 メンバーにはグレードが上がっていくのを支援したいと思っていて、「ちゃんとグレード上げていこう!」と日々伝えるようにしています。そして、Classiでは若手の成長や自立によって突き上げがあるので、すごく良い意味で怖いなーと思っています(笑)

ー どんなことを意識してユニットリーダーをやっていますか?

「自分が関わる人が動きやすくなるように、成長していけるように動く」ということを念頭に他者貢献に振って動くようにしています。それが結果的にチームとしてのアウトプットに繋がっていくと思っています。 チームで仕事をする時に私のように動く人は必要だと思うし、そういった自分のムーブはいい方向に行っているんじゃないかなーと思っています。

Classiでの仕事の面白さや、やりがいについて教えてください。

プレイヤーとして非常に優秀なエンジニアの人と一緒に仕事をできること。

あとは、教育現場の先生・生徒といった、ある意味コンテキストが限定されたユーザーの生の声に触れられて、フィードバックをもらいながらプロダクト改善を進められる環境があること。

ー 一緒に仕事ができてよかったと感じるエンジニアは?

何人もいるのですが…まずはlacolacoさんですね。

エンジニアとしてスキルが高いことはもちろんですが、それ以外のもっと抽象的な能力が高いなと感じています。課題を抽出したり物事を捉えたりが上手で、「社会人として強い」という感じです。その産物としてエンジニアリングができるという印象があります。 なので別の領域に置かれてもすぐに色々とキャッチアップできていて、コーポレート部門の課題解決に携わっていた時もとても活躍していたので本当に流石だなと思います。

ー 優秀だと思うエンジニアと一緒に働くことで変わったことはありますか?

だいぶ横暴になったと思います(笑)

横暴というとあんまり表現がよくないかもしれないですが、意見をはっきり言うようになったり、意見をつっぱねたりするようになったと思います。 チームメンバーが良い意味ではっきりと物事をいう人ばっかりで、「いかにシンプルに情報を正しく伝えられるか」というコミュニケーションがされていました。 私はこれまでは「忙しいだろうなー」とか「伝えたらどう思うんだろう?」とか、「シンプルに情報を正しく伝える」こと以外に気を取られることが多くありました。 でもそういった思考に邪魔されてはっきりと伝えられなかった結果、アウトプットが出せない状態の方がよくないということを学びましたね。徐々にそう言った思考が入らなくなっていき、今思うと気にしすぎていてあまり意味がないものだったなーとも感じています。

しっかりとチームに価値を出していきたいと思っている中で、これまでになかったコミュニケーションを取り入れていって変化をしていると感じています。自分を変化させていくことに痛みを伴うと感じることもありますが、本当に良い影響だと思っていて成長を感じます。

ー 「ある意味コンテキストが限定されたユーザー」の生の声があることの面白さをもう少し教えてください!

ICT化された学校を経験していないので「今ってこんな教育業界なんだ、こんな風に勉強をしているんだ」と自分の時代とのギャップが面白いです。 そのギャップや学校という文化に触れることでカルチャーショックもありますが、生の声をいただきながらプロダクト改善を進められる環境があることはとても良いなと思っています。

Classiでの仕事の難しさや課題について教えてください。

業界の文化に慣れる必要があることだと思います。今の学校教育の抱える現状や、先生・生徒の事情の理解が必要になります。

また、ITリテラシーに差がある様々なユーザーの立場を考えたプロダクト提案が必要で、Webサービス界のスタンダードな考え方が適用できない場面があり、それらの Unlearn が必要な点も難しさだと思います。

そして、目的を達成するために必要な衝突に臆せず向かえる強いマインドを持つことが求められます。

ー 学校を理解することは難しいのでしょうか?

先ほどお話しした通り面白さでもありますが、カルチャーショックが沢山あって最初は難しかったですね(笑) 例えば先生の要望を伺って「印刷して紙で見たい!」というアナログなニーズがあるんです。話を聞いて実際に授業で使うことを想定して考えてみると、その場でペンで書き加えたり、その加筆したものをコピーしたりなどが求められていることがわかりました。それは「紙でやる方法に慣れている」ということでもあります。 Webサービス業界の「最新のかっこいいスマートなものをつくる」と衝突して、ナウいものを作りたいエンジニアからすると「なぜ紙??」となるんです。

今後はWebでやることにも慣れていけるように先生も徐々にUnlearnは必要になるとも思いますが、今はそこに向かう過渡期としてのバランスが大切だと思っています。 バランスを大切にしながらしっかりとニーズを汲み取って、機能を改善してWebでできるようにしていきたいですね。

ー 「目的を達成するために必要な衝突に臆せず向かえる強いマインド」とは?

ある意味どこに行っても求められるものだとは思いますが…より良いものを作りたいという目的達成の過程では、適切な衝突をする必要があると思っています。でもそれは元々気にしいな自分にとってはなかなか難しいことでもありました。

全てを受容していたら良くないことが起こってしまう可能性もあるし、考えや意見を言わないことは責任放棄になると思っています。いろいろな目線があるなかで、みんなプロダクトをよくしたいと思っているからこそ、必要な衝突をしないといけない。 そう言った目的を達成するために必要な衝突に臆せず向かえる強いマインドや志を持つ人が活躍すると思います。

働く上で大切にしていることは何ですか?

How にこだわるのではなく、Why にこだわること。

ー なぜWhyにこだわるようになったのですか?

エンジニアがプログラムを書いて作ることは課題を解決する上でのHowの1つだと思っています。 仕事は納期もあるので、工数をかけて作るということをせずに課題解決できる方法があれば最高の仕事です。ただ、自分がプログラムを書くのが楽しいと思っているからこそ余計に、その観点に気がつけず作ることに囚われてしまうこともあると思っています。「作らないと実現できない課題」のために「作る」時間を費やすことが大切だからこそ、本当に「作る」ことが正解なのかを俯瞰してみないといけないと思っています。onigraさんのインタビューブログにも出ていたエンジニアの三大美徳の怠惰の話は私も大切にしています。 なのでいつも立ち返る意味も含めてWhyを常に意識してこだわることは大切だなと感じています。

最後にひとこと

色々話しましたが「こうありたい」という気持ちも含まれているかもしれません(笑) でもそんな思いで今は頑張っていると思っています!常に全てできる訳ではないと思いますが、話したことを体現できるようにできたらと思っています



環境変化を柔軟にキャッチしながら成長し続けている藤田さんでした。次回もお楽しみに!

Classiでは「子どもの無限の可能性を解き放ち、学びの形を進化させる」というミッションに、ともに向き合っていただける仲間を募集しています。ご興味をお持ちの方は、 お気軽にお問い合わせください!

■採用ページ

corp.classi.jp

■各ポジションごとの求人

5日間のハッカソンとフィードバックをもらう重要性

こんにちは。プロダクト開発部の id:tkdn です。本記事では先日チーム合同で行ったハッカソンと、その成果物デモをディレクターや顧客に近いマーケティングのメンバーの前で行い、フィードバックをもらうまでの話を紹介します。

ハッカソンをとおして個人で獲得できた学びもありましたしチームやほかのメンバーとの協働がよりよくなりました。

そして何よりスピード感のあるアウトプットに対してフィードバックをすぐもらうことの大切さを痛感したので、そんなことも踏まえながらお伝えできればと思います。

きっかけ

今回ハッカソンを実施するに至った経緯はいくつかあります。

  • 2022 年度に成果物としたかったプロトタイプのデモアプリに着手できなかった
  • 今のチームだけではパワーが足りないという感覚があり本年度から組織体制の変更を見込んでいた
  • 以上の経緯も踏まえてマネージャーから Slack で以下のような提案があった

私は二つ返事でやりたいと伝えました。

yudai)来週ハッカソンやりますか tkdn)やりたいっすね

担当プロダクトの負の部分から脱却するためにデモアプリで実証したいことはありましたし、守りのプロダクト開発が最近は多かったので個人としてもハッカソンに取りかかりたいという思いがありました。

どうやったか

ハッカソンは 5 営業日使って行いました。もちろん普段担当するプロダクトもあるので、アラートや問い合わせがあった場合は普段のプロダクトを優先するという約束です。とはいえ、5 営業日ハッカソンに全ブッパで OK を出してくれたマネージャーには感謝ですね。

私が普段活動を共にしているエンジニアは 2 名ですが、先にも触れたとおり、平時の運用やアラートを並行しながら「ガッと」やるにはパワーが不足してしまうという懸念がありました。そのため事業として関心のある領域は一緒だが普段は別で活動している、お隣チームのエンジニア 2 名(ブログ執筆でも登場している id:kudoa が在籍しています)を加え、計 4 名のエンジニア体制で取り組むことにしました

またハッカソンでは 「何かを丁寧に教える場にせず自律的にやれることをどんどん見つけていってほしい」といったマネージャーの言葉を強く意識し、特に「丁寧に教える場にしない」ということを徹底しました。

ハッカソン参加メンバーの構成上、相対的にキャリアの長い自分自身がモブプロを主導したり(キャリアに開きがあるメンバー間のモブプロはティーチングになりがちです ※ 諸説ある)主体的に教えに行ったりするのはやめておこうと開始前から意識しています。

初日に最終日の勝利条件を決める

正直初日まで何かを準備するということはしませんでした。
私が Slack チャンネルと空のリポジトリ準備だけをして初日を迎えています。

初日にまずハッカソンで取り組んで作り上げたい成果物のイメージをマネージャーが説明しました。なぜそれが検証すべき機能たりえるのか、取り組むモチベーションは何なのか、ユーザーのターゲット層はどこなのか、それらのイメージを元にエンジニアが作り始めるにあたって前提となるアラインメントを行っていきます。

イメージの共有を終えて最後には「成果物のプロトタイプはフロントエンドのみで動作する Angular を使ったアプリケーションで、それを最終日にはデモできる状態にする」といった勝利条件をその場で決定しています。

4/14(金) 時点の勝利条件を決める
終日の勝利条件も、日々の記録・勝利条件にも GitHub Discussion が利用されました

最終日のゴールイメージ共有後、マネージャーと 4 名のエンジニアで今日の勝利条件を決めていきます。今日の ToDo ですね。

2 日目以降は私が毎朝デイリーで前日のタスク進捗と今日の勝利条件を確認する形で進行していきました。同期的に話す時間は朝のデイリーの時間だけで、あとは必要なタイミングで突発的に同期的に話す時間を作りました。

2 日目の仕切り直し

初日は勝利条件であるそれぞれの ToDo に取り組んでいき、アプリケーションがローカルである程度うごく様が見れるようになったタイミングで壁にぶち当たりました。

ゴールを達成するための How のひとつだった外部プラットフォーム(プラットフォーム A とします)の Web API が、我々が実現したいことにマッチしないとわかりました。

ただそれでも誰もうなだれるようなことはなかった気がします。

これはハッカソン開始前 Slack チャンネルに貼られたツイートですが、初日の段階でピボットできるなんて我々はけっこうやれているんじゃないか・良かったんじゃないか、といった空気が Slack のチャンネルにはありました。私もすぐさま別のプラットフォーム(プラットフォーム B とします)が提供する Web API の使い方を ChatGPT に聞いていました。

ハッカソン参加メンバーがその日のうちに代替となるようなプラットフォームを試したり、次のステップへ進むという動きを見せたりしていたのは、前向きで健全だなとも思いますし驚きでもありました。

メンバーの振る舞い

ハッカソンを通して特徴的だと感じたのは、参加メンバーの振る舞いが自主的でありながらさまざまなバリエーションがあったことです。各人の動きを相互に見る中で、お互いに任せたいタスクの種類が 2 日以降に固まっていたと感じます。

  • Angular アプリケーションを率先してガリガリ進める
  • アプリケーションのレールで実直に画面を作っていく
  • 実現可能性が不明な問題の可否について調査をしつくす
  • 必要だなを思われることを先回りして調べておく

平時活動をともにしているわけではないお隣のチームではありましたが、あまり接点を持たなかったにもかかわらず、短期間でお互いの特性を認知しあえたのはハッカソンだけに限らず平時にも役立てられる旨味でした。

そしてハッカソン中も、普段の担当プロダクトに来るお問い合わせやアラート対応もしていましたし、お隣のチームメンバーはライブラリアップデートのリリースまで済ませていました。そういったことも踏まえると、ハッカソンを始める前に「パワーが不足していた」と感じていたことさえも疑うべきだったのかもしれないと感じます。

年配者としてハッカソンを通じて感じたこと

ピボットした 2 日目の夕方頃にはコミットされていくコードを眺めて改善を考えるくらいには落ち着いた状態になっていました。

3 日目にはガリガリ画面を作ってブラッシュアップや改善をしながら機能を足していきました。やはり形ができていく喜びと実装している楽しさが相まるとテンションも高まります。

はーやっぱフロントエンド実装してんのが一番楽しい〜
生の喜びを感じる様子

それと同時に、2 日目中盤あたりから自ら「ああしたい、こうしたい」を先に Miro で雑な画面設計を書いて共有を始めています。さらにその日のうちに手を伸ばせそうなことを ToDo として追加して参加メンバーにタスクとして取っていってもらうなど促しもしました。振り返って感じますが、スピードを落とさずにハッカソン合同チームを運営する工夫もできたなという実感もありました。

また普段はあまり言わない・書かないようにしているんですが、3 日目後半くらいからメンバーになぜこのコードの方がよいか・どうしてそちらを選んだのかなどを Slack で解説し、後続するコンポーネントにメンバーが反映できるくらいには余裕のある開発ぶりでした。

Slack で Angular v15 から利用できる inject 関数について触れながらコードの書き換えを提案する様子
マウントをとっていく

メンバー間のフィードバックでより良いものへブラッシュアップするということもできています。メンバーそれぞれが「ハッカソン初日に思っていたよりめちゃくちゃ良くなってうれしい」といった気持ちでデモに臨めたのは本当によかったですね。

5 日目途中でインフラチームに許諾のないままパブリックアクセス可能な S3 バケットを作ってしまいセキュリティ警告検出の連絡を受け平謝りするなどのヘマをしてしまいましたが、5 日目の夕方にデモする直前まで改善と機能追加を続けました(もちろん作成時点で検出されているのでバケットにファイルはありませんでした)。

成果物とフィードバック

成果物のデモには、普段のプロダクトチームのディレクターを含んだディレクション部から 2 名とマーケティング部から 1 名参加してもらいました。普段からユーザーのインサイトを得るためにユーザーインタビューの接点を持ってくださったり、学校訪問時に同席していろいろ教えていただいたりとお世話になっているメンバーばかりです。

デモは私の方で画面と機能説明をさせていただき、そのあといくつかフィードバックをいただきました。以下にいくつかフィードバックを紹介します。

開発した画面を Meet で共有しながらデモをする様子
モザイクだらけですが動く画面を見せながらデモにフィードバックをもらう様子

  • 現状の〇〇画面ではたとえば「数学、数 Ⅰ、平方根」と教科や単元を掘っていくと 3, 40 個くらい候補がリストアップされてしまう。ユーザーにどう選んでもらうかは大事なので生徒の判断材料になるものが何なのかは見出して今回のアウトプットをブラッシュアップできるとよい
  • 単元が紐付いているのであれば学トレ(※ 本年度順次リリースされる学習トレーニング機能)での解答後に関連するリンクをつけるという小さな連携からスタートすることも可能そう

最初に画面を見せて「すごい!」と言ってもらえたのは素直にうれしかったです。何より単に「ハッカソンでアウトプットした」にとどまらず、フィードバック内容の吟味や今後について話す中で新しいアイデアや進め方のヒントがでてきたこと、また現実的に前に進められそうだという手応えをフィードバックの中から得られたことは、将来的なプロダクトの方針を見定めていくうえでも重要な対話になったと感じました。

まとめ

ハッカソン前に読んだ書籍だったのですが継続的デリバリーのソフトウェア工学という本の一節そして内容が、妙に今回のハッカソンとリンクします。

ソフトウェア開発は、基本的に学びと発見の分野なので、成功するためには学びのエキスパートにならなければならない。

ハッカソンという短期間のイテレーションで、実験的でかつ漸進的に実行し何よりフィードバックを受け経験主義的に積み重ねを繰り返していくことの重要性に気付かされました。また、そういった現代的なプロダクト開発の営みとしての「当たり前」を普段からできているかといった問いを投げかけられたように感じ、反省も多かったです。

今日はハッカソンとフィードバックをもらうことの重要性について書きました。
長い文章を最後までお読みいただきありがとうございます。

© 2020 Classi Corp.