TECH PLAY

エス・エム・エス

エス・エム・エス の技術ブログ

271

こんにちは、プロダクト開発部人事のふかしろ( @fkc_hr )です。 年の変わり目ということで目の前の数字だけではなく、通年単位での実績の振り返りなどをしていたところ、なんとプロダクト開発部の採用活動の中で、2023年で約400件のカジュアル面談を実施していたことがわかりました!ありがとうございました。 カジュアル面談のFAQページを作りました カジュアル面談の時間をより充実したものにするために、改めてこんなコンテンツを作成しました。 careers.bm-sms.co.jp 上記コンテンツでは、カジュアル面談でよくご質問いただくことへの回答や、補足になるような過去の記事をご紹介しています。 カジュアル面談に参加するかどうか迷っている方もこちらのページをご覧いただいて、興味を持っていただくきっかけになると嬉しいです。もちろん、 カジュアル面談前に目を通していただく必要はございません 。 カジュアル面談の雰囲気 2021年に記事公開したころから、スタンスは変わっておらず、 面談の参加に転職意欲は問いません。 tech.bm-sms.co.jp カジュアル面談は技術責任者の田辺、エンジニアリングマネージャーの古萱、酒井、荒巻、その他状況に応じて現場社員が参加します。 マネージャー陣が現場の状況を知っているので各事業のご紹介はもちろん、一人ひとりのキャリアに向き合って相談する1時間になっています。 人事として採用・広報活動をしている中で、もっとエス・エム・エスのことをいろんな方に知ってほしいな!と考えて作成いたしました。 今年も様々な方とカジュアル面談含めてお話させていただきたいです。 最後に エス・エム・エスのプロダクト開発部では2024年も採用・広報活動を実施していきます!よろしくお願いいたします。 もっと詳しく聞きたい!と思っていただけましたらお気軽に記事末尾のカジュアル面談応募リンクからお申し込みください。
こんにちは、プロダクト開発部人事のふかしろ( @fkc_hr )です。 エス・エム・エスは複数の事業を展開しており、プロダクト開発部もそれぞれのチームが事業ごとに開発を進めているのが特徴です。今回、キャリア分野の取り組みについてまとめた事業・プロダクト紹介のピッチ資料を作成いたしました。本記事では一部抜粋する形で内容の紹介と今後の記事の告知をさせてください! 医療キャリア事業とは? エス・エム・エスのキャリア事業領域では、高齢社会が直面する「質の高い医療・介護サービスの提供が困難になる」という社会課題に対し、「医療・介護の人手不足と偏在の解消」に貢献することで解決を目指しています。 医療キャリア事業とは、その中でも特に医療領域にフォーカスをあてている事業です。医療従事者の長いキャリアを線で捉え、マーケットの真のニーズに寄り添ったサービスを提供しようと考えています。 医療キャリアに向き合う開発組織の変化について ピッチ資料からの引用になりますが以下のような開発組織の現状があり、開発体制を変化させようとしています。 これまで10年以上に渡り医療キャリア事業のサービス運用をしています。市場が伸び続けていることもあり、それに応えるために求められる機能をどんどん積み上げていくような開発をしてきました。 しかし事業フェーズも変わり、この手法ではより大きな課題への対処が難しいと感じています。今後は、開発チームがよりドメインに精通し、プロダクトの検証を重ね、ユーザーに提供すべき価値を洞察するための開発体制を築いていく必要があると考えています。 このような現状や課題以外にも、本ピッチ資料では医療キャリア事業が抱える技術的な課題や組織の取り組みなどについて赤裸々に書いておりますので、ぜひご一読ください。 careers.bm-sms.co.jp プロダクトやチームの裏側を順次公開予定 ピッチ資料は非常に項目が多くなってしまうため、それぞれの具体的な取り組みや組織強化中のチームの社員紹介などもしていきたいと考えています。 すでに数名入社エントリーを公開済みです。 tech.bm-sms.co.jp tech.bm-sms.co.jp さらに、今後、以下のようなテーマで記事を公開していく予定です。 ぜひ Xのアカウント をフォローして新着通知をお待ちください。 プロダクションレディな品質についての記事 各メンバーの入社エントリー記事 カンファレンス登壇内容の資料公開記事 事業責任者のインタビュー記事 プロダクトを支えるメンバーを積極採用中 最後になりますが、このキャリア事業における取り組みは、まだまだ多くのエンジニアの方の協力を必要としています。先ほどご紹介したサイト内に募集中のポジションを記載していますので、興味のある方はぜひご覧ください!また、エンジニアだけでなく、プロダクトマネージャー・UI/UXデザイナーなどプロジェクトに携わるポジションを全方位的に募集しています。 カジュアル面談もやっておりますので「選考に進む気持ちはまだないけどプロジェクトについては面白そうなので聞いてみたい」という方でも構いません。ご興味があれば是非お気軽にお声がけください!
プロダクトマネージャーカンファレンス2023で登壇しました 介護職向け求人情報サービス「 カイゴジョブ 」のプロダクトマネージャーを務めている田中( @tatsunori_ta )です。 株式会社エス・エム・エス Advent Calendar 2023の8日目の記事 でもお伝えしておりますが、会社を代表して プロダクトマネージャーカンファレンス2023(pmconf2023) にて登壇する機会をいただきました。 note.com pmconf2023では「”リビルド”プロダクトマネジメントの極意」のタイトルで発表しております。 発表要旨は以下です。 ある程度の規模、組織では既にあるプロダクトのPMになる方も多いでしょう。創業者からPO・PMを引き継ぐケースや、他PMからPM業を引き継ぐケースなど。キャリアを通して、プロダクトの再検討フェーズに入ることが多い私ですが、今あるもの・プロダクトの「そもそも」から疑い、あるべき価値・戦略を描き直すことを現在も実践しています。既存組織やオペレーションなど制約もある中で、私がどのようなスタンス・動きで「リビルド」を実現しているかをお話します。 2023.pmconf.jp 2024年と年明けになってしまいましたが、この記事では発表資料・録画を紹介し、発表時に寄せられた質問の一部への応答・補足説明をいたします。 発表資料 録画(YouTube) www.youtube.com Q&A Q.(転職して2ヶ月の方からの質問)リビルドできるのは新しく入ったPMならではというのに惹かれました。新しく入った状態で「情報を集めること」に苦労していると話されていましたが、どうクリアしましたか? 誰しも今まで所属していた組織における「情報共有・蓄積の仕組み」があります。その中で慣れ親しんだツールや、情報の保存場所があるはずですが、新しい組織に入るにあたってはこれらをアップデートする必要があるため、まずは以下を理解することが大事です。 どこにどんな情報が蓄積されているのか(そもそもないのか) 誰がどんな情報を持っているのか 前者のどこにどんな情報があるかは、1ヶ月ほど共有フォルダ(BoxやGoogle Drive)を漁っていると分かるようになっています。PMは着任初日から会議等で忙殺されることはないので、時間にゆとりがある着任初期に、格納されている情報・データを漁ってみることをおすすめします。 個人的に後者をどう抑えるかは大事だと思っており、誰がどんな情報を持っているかを知り、その人と信頼関係を早めに作っておくことを心がけています。例えばプロダクトのデータを見たいのであれば、データサイエンティストやエンジニアにどんな情報が取れるかを先んじて確認しておく必要がありますし、業務理解をしたいのであれば業務設計者も業務担当者も接点を持たないといけないでしょう。すべてがドキュメント化されていることは稀なので、私は後者の「人」からの情報を積極的に取りに行くことでクリアしていきました(まだまだ知らないことが多いなと感じており、日々学んでおりますが)。 Q. ユーザーヒアリングする対象を選定される際(サンプリングの際)に気を付けていることや選定の基準などはありますでしょうか? 自分の理解度と学びたいテーマによって変えていますが、以下のようにしています。 ①着任初期 前提:事業・顧客に対して解像度が低い状態 セグメントを定めずに無作為に顧客に会いに行く とりあえずランダムサンプルで10人/10社ほど行く ただし、事前にどのような顧客であるかは調査しておく 目的は業界、顧客、業務をざっと掴むこと(肌感を得ること) 質問事項は事前に用意するが、仮説を固めすぎない 基本調査(業務内容、顧客属性)を実施 業務観察は概要を把握するのみに留めて、細かい点は理解できなくてもOKとする ②着任してから約3ヶ月〜6ヶ月目以降 前提:ある程度ドメイン知識が付いてきている状態 ユーザー、顧客をある程度のロジックでセグメントを作る 例:大手/中小、都市部/地方部、ベテラン/若手、業界A/業界Bなど ターゲットと思われるセグメント(8人ほど)、違うであろうセグメント(2人ほど)とかでヒアリングを実施 違うであろうセグメントのユーザーヒアリングをする理由は、あくまでも確認程度 ①に比べると解像度はもう少し高くなっている 仮説と質問事項を用意する 仮説検証するためにヒアリングおよび観察を行う
エス・エム・エスが提供する介護事業者向け経営支援サービス「カイポケ」では、サービス停止も含めたプロダクトの「見直し」を継続的に実施しています。たとえば、2023年2月には、カイポケ内にて5,000法人が利用していた勤怠管理・給与計算機能をクローズし、株式会社マネーフォワードとの業務提携によって実現した「カイポケ会計・労務 by Money Forward」への一本化を進めました。 カイポケリニューアルプロジェクト が進む中で、介護業界の複雑性と課題の大きさを改めて認識するとともに、限りあるリソースの中でカイポケが本当にユーザーに届けたい価値は何かと問い続けた結果、その他にも、2022年度には7件のサービスや機能のクローズを実施、2023年度も上半期だけで7件のサービスや機能のクローズを実施しました。 プロダクト開発というと新規機能の追加に目が向きがちですが、リソースの確保、ひいてはユーザーにとってより価値あるプロダクトを提供していくという観点では、一部機能やサービスの終了について検討することも重要な取り組みといえます。ユーザーや社内をはじめとするステークホルダーへの説明など大変な場面が多いですが、なぜエス・エム・エスでは継続的に見直しの活動ができているのでしょうか。それによってもたらされる価値とは。カイポケの事業責任者である園田さん、経営企画としてプロダクトポートフォリオ・マネジメントを担う川合さんに聞きました。 よりユーザーに求められるプロダクトにするために ――カイポケの見直しに関する取り組みの概要を教えてください。 園田: 私がエス・エム・エスへ入社したのは2020年7月ですが、それより前からカイポケでは機能追加やサービス追加がされ、「40以上のサービス」というキャッチコピーからも分かる通り、機能やサービスが多い事が美徳とされているように見えました。しかし、カイポケのプロダクトマネージャーに各機能について話を聞くと、本当にユーザーに使われているのかわからない機能が多数あるという状況が明らかになってきました。そこで、カイポケの機能をリストアップし、それぞれに対して利用状況などのデータを1つずつ半年程かけて可視化していきました。すると、開発当時の予想に反して、実際は数十法人ほどにしか使われておらずクローズの判断をしたほうがよい機能や、数千の法人が利用しているもののサードパーティのサービスを利用したほうがよい機能などが多くあることがわかり、そのひとつひとつに対して、定量調査、定性調査、及びそのプロダクトが存在している文脈の調査を行い、①現状維持、②他サービスへの移管、③クローズ、の3つに分けて、それぞれ対応策を検討していくことにしました。 ▲これまでのカイポケの機能リスト一例 ――現時点では実際にクローズしている機能もあります。クローズも含めた見直しをする目的は何でしょうか? 園田: 目的は、希少な開発リソースをサービス向上に向けて100%投下できるようにするためです。これまでは介護経営をあらゆる側面から支援する観点でなるべく多くの機能をプロダクトに搭載しようという方針でしたが、改めて見直してみると、なかには当社が提供することがベストではない機能もありました。たとえば、勤怠管理や給与計算のように、機能というにはあまりに大きいサービスは、その専門プロダクトを開発する企業のものを利用した方が、ユーザーとしては、日々メンテナンス・アップデートされる品質の高いプロダクトに触れることができます。10年前は選択肢が無くて違ったかもしれませんが、現状は他社のHorizontal SaaSを利用する選択肢も増えています。私たちとしては、介護業界に特化した機能に注力するほうが、よりユーザーに求められるプロダクトを作っていけると考えました。 そのようなプロダクトは、現実にはリソースが割かれない結果として、担当が割り振られず、運用やメンテナンスのコストは発生しているのにもかかわらず、障害対応のフローが定まっていなかったり、セキュリティ面での問題があったりという保守運用上の課題も発生します。エンジニアとしても、戦略の存在しないプロダクトを担当するのはなかなか辛いのではないかと思っています。 私たちは、介護業界に特化した機能に注力するほうが、よりユーザーに求められるプロダクトを作っていけると考え、そのためには、常に自分達がその機能開発のベストオーナーかどうかを問う必要があると考えています。 プロダクトドリブン組織へ転換していくうえで見直しは必至 ――カイポケの見直しの取り組みにおいて、苦労しているポイントがあれば教えてください。 川合: ユーザーと社内の双方に納得していただかなければならない点です。ユーザー視点では単に機能縮小と感じられてしまいますし、社内では財務的なインパクトはもちろん、営業のようにユーザーの対応に追われる部署もあります。これまでは、さまざまな機能があるからこその経営支援サービスという方針でプロダクトを開発してきましたが、これからは介護業界において本当に必要なものを提供していく方向性へと舵を切っていきます、という方針転換に納得してもらうストーリーをユーザー向け、社内向けに展開することが求められます。正直にいうと、やはり当初は社内からも大きな反発がありました。 ――抵抗感もあるなかで、どのようにして社内の理解を得ていくのでしょうか。 川合: なぜクローズをするのか、実際に現場でどのような対応が必要になるのかという具体的な進め方を丁寧に説明することが大事だと考えています。たとえば、ユーザーにとっては単なる機能縮小に感じる変更をどのように説明をするのか、ユーザーから値引き対応が求められた際にはどのように対応するのか、他社の代替サービスを紹介できるのか、カイポケ内にあるデータや帳票はどうなるのか、実際の移行オペレーションはどうなるのかなど、細かいところまで検討し、ビジネスのフロントがプロダクトのストーリーに納得するだけでなく、その中での自分たちの役割を具体的にイメージしてもらえるように準備をしていきました。 ▲社内向けの説明で用いた資料一例 園田:かつてエス・エム・エスは、セールスやマーケティングといったビジネスサイドの力が強く、プロダクト文化が弱い環境にありました。しかし今後は、ユーザーにとって本当に必要な機能をユーザー起点で考え、プロダクトドリブンで実現する方針を打ち立てています。そうなると、自ずとプロダクトポートフォリオの見直しをしていく必要が出てきます。それは、たとえ社内のどの部署から反発を受けようがゆるがない結論です。現在では、ビジネスとプロダクトが対等に存在し、お互い理解しようとするカルチャーが醸成されてきており、経営陣の理解も得られやすい環境ができてきているように思います。 なぜ5,000法人が利用する勤怠管理・給与計算機能を停止したのか ――勤怠管理・給与計算機能のクローズは具体的にどのように進めていったのでしょうか? 川合: 背景としては、やはり勤怠管理・給与計算機能に対しては私たちがベストオーナーではないという考えが強くありました。細かいバグ対応なども発生していましたが、プロダクトの中心となるレセプト機能の対応が優先されるため、どうしても修正の優先順位が落ちてしまいます。また、勤怠管理・給与計算機能は毎年法改正への対応が必要になります。サービスとして中途半端なものになっているのに、維持するコストはかかり続けている状況でした。そこで、もともと当社がマネーフォワードと業務提携していたこともあり、同社と連携して同様の機能を提供できるようにする方針を決めました。 園田: ただし、対象となったのは非アクティブユーザーも含め約5,000法人。多くの方が利用する機能のため、ハレーションが起きることは容易に予想できました。サードパーティと連携するにも毎年数億単位でコストが増えるため、社内への合理的な説明が必要です。ユーザーからしても、これまでカイポケの機能の一部として使えていたものが有料化されることになりますし、サービスを移行すること自体への抵抗感もあります。 川合: 対経営層には、サードパーティ移行に必要な費用とその効果、そのままメンテナンスしつづけた際の費用やデメリットなども含め、最終的に事業成長につながるストーリーを組み立てて説明しました。実際、開発費用はほぼ減価償却されていて、現段階では費用がそれほどかかっていないというのも説明しづらいポイントでした。また、ユーザーに対しては、当社からの持ち出しにより移行先となるマネーフォワードのサービスを安価で利用できるようにすることや、セールスやカスタマーサポートを巻き込み、移行についての説明をこちらから電話を架けて行うことなどの対応を行いました。社内に対しては、会社、それを支える人・文化としてどこを目指しているのか、エス・エム・エスの価値観を基本路線にコミュニケーションを取ることを大事にしました。こうした対ユーザー、対経営者、対社内に対する説明がそれぞれ齟齬のないよう丁寧に説明することにも気をつけていました。 園田: マネーフォワードと連携したことにより、今後プロダクトは日々アップデートされ、長期で見るとよりよいものへとなっていきます。これはユーザーにとって価値のあることです。また、当社としては、より注力すべき領域へリソースを割り振ることができ、プロダクトマネージャーやエンジニアはより価値の高いプロダクトに集中して開発に取り組めるようになります。 ▲「カイポケ会計・労務 by Money Forward」 新しいものを生み出すためのプロダクトライフサイクルを実現する ――見直しがなかなかできていない企業も多くあるように思います。なぜエス・エム・エスでは、積極的に見直しに取り組み、筋肉質なプロダクト開発を実現できているのでしょうか? 園田:戦略を考える際に、長期的な視点でプロダクトを見ていることが一番大きいです。これは、介護という市場規模も課題も大きく、かつ長期的に成長しているマーケットで、すでに多くのユーザーを抱えてある程度のビジネス規模を実現しているカイポケだからこそ言えることかもしれません。カイポケというプロダクトはこれから先もずっと提供されていくものですし、ユーザーもずっと変わらず存在していくはずです。こうした観点でたとえば10年後を見据えると、さすがにどこかのタイミングで見直さなければならないし、どうせやるなら早いほうがいいという考え方になります。 ――今後もカイポケの見直しには取り組まれていくのでしょうか? 川合: はい。しかし、見直しだけがすべてではありません。さまざまな機能を追加していた過去の判断は、それによって「経営支援」というコンセプトがユーザーに受容され、事業成長できた面もあるので、現状だけを見て間違っているというのは少し違うと思っています。市場感をつかむためにまず機能追加をして様子を見てみるという方法も、プロダクト開発を進めるうえでは有効だと考えています。そのため、単純に機能追加をしていく姿勢自体を是正したいわけではありません。 そうではなく、各機能は、市場のニーズの変化や事業成長のフェーズにしたがって開発・運用・整理されるべきだと考えています。新しいものを生み出すための開発工数がきちんと担保されるよう、それが必要なものであるかどうかを適宜見直し、プロダクトライフサイクルをきちんと回していくことこそが重要な考え方だと思っています。注力したいところにリソースを投下できる状態をつくることは、結果としてよりよいプロダクト開発を可能としますし、その積み上げがユーザーの生産性向上などの価値につながっていきます。 ――カイポケを今後どのようなプロダクトにしていきたいと考えていますか? 園田: ユーザーの課題を解決できる良いプロダクトとする事を起点に考える、という思想を今後も貫いていくことに尽きます。カイポケが対象としている介護・障害福祉領域には多くの課題があり、それに対して多岐にわたるサービスがあります。カイポケだけで解決できる課題ばかりではありませんし、ユーザーにとって課題解決の手段がカイポケである必要がないサービスもあると思います。ユーザーにとって価値あるプロダクトにしていけるよう、他社との連携も含めて課題解決ができる仕組みづくりが重要だと考えています。
はじめに 介護事業者向け経営支援サービス「カイポケ」のプロダクトオーナーをしている 岩下 真志穂 と申します。 入社して約4年間ビジネスサイドでセールス業務をしていたのですが、2023年中頃に入ってプロダクト開発の知識がほぼゼロに近い状態で異動をして、プロダクトオーナー(PO)をすることになりました。 どんな方に読んでほしいか そんな私がこの約半年間でどういう課題に直面し、それをどう解決してきたのかを本エントリーで共有したいと思います。この記事は ビジネスサイドや事業部での経験はあるが、全くの異職種へ未経験で転向した人の異動エントリが読みたい! Vertical SaaSを提供しているエス・エム・エス/カイポケ事業において、プロダクトオーナーがどんなことをやる人なのか気になる! ドメインエキスパートがプロダクトマネージャーを目指したいときに、どういうスキル獲得が必要なのか知りたい! といった方に、何か一つでもお役立ちできればと思って書いています。 そもそもPO(プロダクトオーナー)とは? エス・エム・エスではプロダクトマネージャー(以降PdM)とプロダクトオーナー(以降PO)をロール=役割として区別しており、平たく言うと以下のような違いがあります。 PdM=プロダクト全体(マルチプロダクト)のビジョンを明らかにし、成功させるためにチームをまとめる人 PO=シングルプロダクトの開発においてユーザーのWhyを考える人 どちらも「いいプロダクトを作るために汗をかく人」という点では同じなので、エス・エム・エスとしてもそこに役職としての優劣をつけていないのですが、上記のように見ている範囲(マルチプロダクトか、シングルプロダクトか)に違いがあります。 また、実際に私が携わっているカイポケリニューアルプロジェクトにおいては、PdMはリニューアルするカイポケのプロダクト全体を見ているのに対し、POである私はその中の細分化された機能であるシングルプロダクトの「ケアマネアプリ」を見ているといった違いが出てきます。 なぜ社内転職を選んだのか ここまで読んでくださって「ちょっと待ってよ岩下さん!異動エントリと思ってこの記事読んでるんだけど!!」とお思いの方がいらっしゃるかもしれません。ご安心ください、今からその話をします。 先述の通り、元々ビジネスサイドに4年間いたわけですが、なぜ畑違いのプロダクト開発部に異動したのかというと、現場経験があるからこそ分かるユーザーの「不」(不便・不快・不満・不安)に対して、開発という分野からチャレンジしてみたくなったからです。 ユーザーのソフト面での「不」とこれからリニューアルするカイポケのハードの特性をフィットさせ、ひいてはユーザーにとってクリティカルな課題の解決をプロダクト自身を通してしていきたいと強く思うようになりました。 セールス視点から見たプロダクトへの「不」 「不」の例を挙げて説明します。 カイポケには請求ソフトとしての機能に加えて、経営状態を見える化するための機能の一つとして「売上管理」の機能があるのですが、この機能について以下のような「不」がありました。 現状:「売上管理」機能は月次でしか見れない 顧客ニーズ:日次で売上を把握したい 運用 提案:日次計算ができる売上シミュレーション(エクセル)を独自作成 「不」ポイント:複雑な加算が絡む介護請求においては「あくまで概算」のシミュレーションしか提供できない 実際に社内転職してみて 最初に感じたのは「安心」でした。 スクラムイベントや開発知識についてのオンボーディングの場があったこと、ワーキングアグリーメントが言語化されていること(これも新しい方がジョインされたらPOやプロジェクトリーダー主導でチームで議論しどんどんアップデートしていきます)、外部講師からの研修が設けられていること、などなど未経験でも安心できる体制があることはありがたかったです。 また、今あるプロダクトに対してユーザーのニーズを知っている人が開発部署に社内転職することは、プロダクトを開発していく上で価値があることだという実感はあります。自分の中に、ある意味ユーザーについてのビッグデータがある状態なので、開発サイクルで検証を重ねる際にも「どこに課題があるのか」や「どこをユーザー価値にするのか」が判断しやすいからです。 ドメイン経験があって社内異動を検討している方がいたら、自分の介在価値がどこにあるのか参考にしていただけたらと思います! エス・エム・エスでの「社内転職」というキャリアパス 上記のような思いがあるものの、事業部経験者がプロダクト開発部へ未経験で異動する、というのは社内でもほぼ初めてでキャリアパスを開拓する難易度は高いだろうな、と予想していました。ですが、実際に具体的に動いてみるとそんなことはなく、事業部長の 園田さん は異動や新しいチャレンジは歓迎!という考えだったので、面談を重ねて異動が決まりました。(ちなみに、事業部側には” 部門の最高責任者とも誰でもカジュアルに1on1できる仕組み ”があって、そこでフランクに話せたのも良かったと思ってます。) ちなみに私の場合、社内転職に向けて以下のようなことを整理してみました。 自分が持っている課題は、今の部署では解決できないのか (具体的な打ち手を考えるとしたらどういうアイディアがあるか) 異動先の部署ではなぜその課題を解決できると考えるのか 異動後、今の自分が持っているどういうスキルが活用できそうか POの魅力 難しさを感じる部分 ビジネスサイドからの異動だったことで当初感じた難しさは「これまでと目標(仕事のゴールやKPI)が全く違う」部分でした。 ビジネスサイド:進捗管理(決められたKPI=数字を達成する、タスクを早く終わらせる)が大事 プロダクト開発:プロセス管理(ベロシティはみるが量的には評価せず、不確実性を消しながら目指すゴールに向かえているかをチェックする)が大事 スクラムという概念を導入した結果、個人としての達成を目指すのではなく、スクラムを組んでチーム全体でスキルや知識を補いながら一緒にちょっとずつ進んでいくということを知りました。 また、開発知識・デザイン知識などが一定ないとスムーズに業務を進められないので、本やポッドキャストなどから常にインプットはしています。今はドメインモデリングの勉強をしているところです。 楽しさ・面白さを感じる部分 一方でやりがいを感じる部分もたくさんあります! 新しい職種POに挑戦してみて、これまでの4年間に現場ユーザーと相対する中で「今のプロダクトでは解決が難しい」部分について考え続けていたことが、一つ一つ解消できていることに充実感と達成感を感じています。 特に、私が携わっているカイポケのリニューアルプロジェクトは「介護業界」というドメイン知識が高度に必要な分野のため、これまでの経験・知識を活かして、エンジニアやデザイナー向けの社内勉強会を定期的に開催しています。物事を型化することは元々好きだったのですが、それを勉強会という場で価値としてコンスタントに発揮できるのは嬉しいですし楽しいです。 エス・エム・エスならではの楽しさもあります。エス・エム・エスの事業内容は大きく4つ(ヘルスケア・医療・介護・シニアライフ)ありますが、カイポケと親和性が高い事業もあります。 外部に頼んだら時間もコストもかかるような調査がすでに行われていて結果を共有してもらえたり、会社のリソースを使った検証やナレッジ共有ができるのはすごいことだと思います。 逆に、カイポケ側からの情報提供もあります。例えば、アドバイザリー契約を結んでいるユーザーやそのコミュニティを活用し、シニアライフ領域のケアマネドットコムなど他事業部へ接点を繋ぐことでエス・エム・エス全体でプロダクトの改善に向けて動く取り組みもしています。 エス・エム・エスの事業領域と展開サービス まとめ 以上、この半年間の私の経験をもとに、未経験からの開発部への社内転職やエス・エム・エスにおけるPOという職種、カイポケリニューアルプロジェクトの取り組みを紹介させていただきました。 Vertical SaaS特有の課題を解決しつつドメイン知識やユーザー理解をしていくプロセスに疑問があった方や、全くの異職種への転向に不安を持っている方が、この記事を読んで安心感を持っていただけたら幸いです。
はじめに この記事は 株式会社エス・エム・エス Advent Calendar 2023 の 20 日目の記事です。 はじめまして、キャリア事業部でマネージャーをしている @kenjiszk です。2023年4月に入社し、はや9ヶ月目になりました。私は、エス・エム・エスのミッションである「高齢社会に適した情報インフラを構築することで人々の生活の質を向上し、社会に貢献し続ける」がとても気に入っているのですが、特にお気に入りポイントである「社会に貢献し続ける」という部分について私の経験をもとに紹介できればと思っています。 ひとこと「社会に貢献し続ける」といっても解像度が荒いので、そのためにはどういったシステム、どういった組織、どういった事業であるべきかといったあたりが少しでも伝わると嬉しいです。 動くものではなく、動き続けるものをつくれ 遡ること十数年前、私は某ソーシャルゲーム開発会社のインフラエンジニアとしてキャリアをスタートします。タイトルにある言葉は当時の上司から頂いたありがたいお言葉です。簡単にいうと、作った時は正常に動いているのは当たり前で、作った後何年経っても正常に動き続けるものを作りなさいということなんですが、当時の私は右も左もわからず、サーバー構築やら何やらを行っていたので、ふーんくらいの気持ちで聞いていました。 そんなある日、作業ミスで割と大事なサーバーを落としてしまったのですが、予想に反してサービス全体は正常に動き続けていました。なるほど、上司が言っていたのはそう言うことね、と腹落ちした経験になります。 また、この時期にクラウドが利用され始めていて、作ったものは壊れる前提でシステム全体として健全に動かし続けるための工夫を学びました。 長期的な開発速度とは その後、ベンチャー企業で働き始めましたが、インフラ基盤としては前職の経験を踏まえてそれなりに堅牢なものを作っていたと思います。ですが、少し目線を広げるとそこには常に忙しそうにしている開発チームがいました。かなり忙しそうにしている割にはそこまで成果が出ていないような状況に見えましたし、実際に開発メンバーからは、短期的に最速の方法をとっていると思うけど持続可能ではない、といった意見も出ていました。 もちろんこれは当時私が感じた一部の側面であり、いろいろな観点で見た時の最適解であったのだろうと今では思っています。ベンチャー企業であればリリースしなければ死を待つのみですし、一時的にストレッチが必要な場面や気合いで乗り切らないといけない場面は多々あります。ですが、長期的に開発速度を出すにはもっと別の問題があるようにも感じていました。 ありがたいことに数年後、開発組織全体の責任者もやらせてもらうことになったので長期的に開発速度を上げるにはどうすると良いのかということをCTOやエンジニアリングマネージャーたちと議論できるようになりました。この時は、チームトポロジーの考え方を参考に「長期的に安定したチーム」による開発を試すことができ、その有効性も実感できました。 開発体制が良ければ大丈夫なのか 「長期的に安定したチーム」が作れて一安心かと思いきや、そういったチームが必ず売れるプロダクトを作れるかというとそんなこともありません。もちろん打率は上がると思いますが、市況、マーケット、さまざまな要因でプロダクトが売れないという状況を何度か体験しました。 「長期的に安定したチーム」が永続していくには、適切な市場選択や戦略などさらに上位の概念が必要になってきます。 PMFしていれば安泰なのか そんなことを考えている時に、ご縁があってエス・エム・エスに入社することになります。エス・エム・エスは19期連続増収増益という実績からもわかるように、伸びるマーケットで売れる事業を作り続けている会社という印象でした。一方で色々と話を聞くとシステム面や組織面の課題はいくつかあり、自分自身が経験してきたことでなんらかの貢献ができるのではないかと感じ入社することに決めました。 という目論見で入ったのですが、現実はそんなに甘くないというのが入社して9ヶ月経った感想です。マーケットで評価されているということは競合が多数出現するということ、10何年も継続しているということはユーザーの世代が変わっているということで求められるニーズが変化し続けていること、など事業・サービスのあり方というところでも常に変化が求められることを感じています。 今は、システム面、組織面を整えながら、今後どういったロードマップでプロダクトに改善を重ねると長期的に価値のあるものをマーケットに届けられるのかということに日々頭を使っています。 まとめ ということで、エス・エム・エス入社前後の経験を振り返りながら、「社会に貢献し続ける」ために必要なことについてつらつらと書いてみました。 経験上、インフラからアプリケーション開発、組織運用や事業へと視点や関心が移っているのですが、単純に事業に関心を持つべきと言ったような話ではなく全ての視点がそれぞれ大事で総合格闘技的な立ち回りが必要になると思っています。 それぞれの項目についてどれも大事でどれも外せない中でどうバランスをとりながら物事を進めていくか、というところに難しさと面白さがあると感じます。 サービスの可用性やセキュリティを担保するインフラ 安定した開発体制により継続的に生み出す開発速度 開発というコストを払うことで着実に積み重ねられる資産 マーケットや競合の変化に対応できる根本的な提供価値の追求 最後に、これらを進めるためには仲間がたくさん必要です!という気持ちなので一緒にこの課題に取り組んでいる人を積極募集しています!よろしくお願いします!
この記事は株式会社エス・エム・エス Advent Calendar 2023の14日目の記事です。 qiita.com カイポケリニューアルプロジェクトのバックエンドチームに所属している丸井です。 私のチームでは Spring for GraphQL を使ってバックエンドサービスを開発しています。監視基盤としては Datadog を利用していますが、トレースやGraphQL クエリ関連の各種メトリクスは java プロセス起動時に javaagent として dd-java-agent を指定することで収集がされています。 dd-java-agent を使うことでアプリケーションコードに何も手を入れなくても収集されるのはありがたいものの、どういう仕組みで動作しているのか分かっていなかったため調べてみることにしました。 ※ Datadog の Metrics メニューを開いてみると、GraphQL 関連のメトリクスが収集されているのが確認できる 参考: OpenTelemetry Instrumentation for Java の仕組み javaagent を利用してよしなに情報を収集するライブラリとしては他にもありますが、dd-java-agent と類似の位置づけのものとして OpenTelemetry Instrumentation for Java があります。 VA Linux エンジニアブログ: OpenTelemetry Instrumentation for Javaの自動トレースの仕組みの調査 という記事にその仕組みが解説されており、分かりやすかったので紹介します。 上記の記事にあるように、OpenTelemetry Instrumentation for Java(や dd-java-agent)は javaagent によってクラスファイルをロードする前にバイトコードを動的に変更して、一般的なライブラリやフレームワークからテレメトリを収集して監視基盤に送信している、というのが基本的な仕組みです。 dd-java-agent が自動的に収集する対象 dd-java-agent も一般的なライブラリやフレームワークをカバーしているため、導入するだけで情報が収集されます。 https://github.com/DataDog/dd-trace-java/tree/master/dd-java-agent/instrumentation 2023/12現在、収集対象は200を超えており、spring、tomcat、servlet など Web サービスに関わるものから、java.lang 系の一部のクラスなんかも含まれています 1 。 Spring for GraphQL が依存している GraphQL Java も対象となっており、そんなわけで GraphQL のクエリ情報が収集され Datadog に送信されています。 GraphQL Java の情報はどのように収集されているか ここからは GraphQL Java 用の instrumentation を見ていきます。 ちなみに instrumentation(計装)とは、 wikipedia: 計装 によると「生産工程等を制御するために、測定装置や制御装置などを装備し、測定すること」とあり、OpenTelemetry のドキュメントの Docs/Concepts/Instrumentation にもシステムを観測可能にするために実施するなにがしかのこと、という趣旨の説明が書かれています。 GraphQL Java の instrumentation コードは dd-trace-java リポジトリ内の /dd-java-agent/instrumentation/graphql-java-14.0 に配置されていますが、先に dd-trace-java の CONTRIBUTING.md: Adding Instrumentations を見てみると、 Must implement Instrumenter - note that it is recommended to implement Instrumenter.Default in every case. instrumentation の追加には Instrumenter の実装が必要とあるので、まずは Instrumenter から見ていきます。 GraphQL Java の Instrumenter 実装 GraphQL Java の Instrumenter は GraphQLJavaInstrumentation.java というファイルに実装されています。中を見てみると以下のように checkInstrumentationDefaultState というメソッドに対する Advice を適用しています。 @Override public void adviceTransformations(AdviceTransformation transformation) { transformation.applyAdvice( isMethod() .and( namedOneOf( "checkInstrumentationDefaultState" // 9.7+ // https://github.com/graphql-java/graphql-java/commit/821241de8ee055d6d254a9d95ef5143f9e540826 // "checkInstrumentation" // <9.7 // https://github.com/graphql-java/graphql-java/commit/78a6e4eda1c13f47573adb879ae781cce794e96a )) .and(returns(named( "graphql.execution.instrumentation.Instrumentation" ))), this .getClass().getName() + "$AddInstrumentationAdvice" ); } checkInstrumentationDefaultState というのは GraphQL Java に 実装されているメソッド で、GraphQL サーバー機能のセットアップ時に呼び出されるものです。 Advice を適用することで、上記のメソッドの呼び出し前後に処理を追加することが出来ます。 適用する Advice は以下のようになっており、GraphQL Java で作成された instrumentation を dd-java-agent 側で実装している GraphQLInstrumentation でラップして返すようになっています。 @SuppressWarnings ( "unused" ) public static class AddInstrumentationAdvice { @Advice.OnMethodExit (suppress = Throwable. class ) public static void onExit( @Advice.Return (readOnly = false ) Instrumentation instrumentation) { instrumentation = GraphQLInstrumentation.install(instrumentation); } public static void muzzleCheck() { // Class introduced in 15.0 ValueUnboxer value = ValueUnboxer.DEFAULT; } } 突然「GraphQL Java で作成された instrumentation」というのが登場していますが、GraphQL Java 自身も計装のための仕組みを備えており、起動時に instrumentation のためのセットアップがされるようになっています。 https://www.graphql-java.com/documentation/instrumentation/ dd-java-agent は「GraphQL Java で作成された instrumentation」をラップすることで Datadog 連携用の計装を追加している形になります。 GraphQLInstrumentation の実装 GraphQL Java の Instrumentation のラッパークラスの実装は こちら 。 GraphQL クエリの情報を収集する上で重要なのは以下の DataFetcher に関する箇所です。 @Override public DataFetcher<?> instrumentDataFetcher( final DataFetcher<?> dataFetcher, InstrumentationFieldFetchParameters parameters) { State state = parameters.getInstrumentationState(); final AgentSpan requestSpan = state.getRequestSpan(); return new InstrumentedDataFetcher(dataFetcher, parameters, requestSpan); } オリジナルの DataFetcher を dd-java-agent の InstrumentedDataFetcher でラップしています。 そして InstrumentedDataFetcher の実装は こちら 。 GraphQL クエリを処理する際に呼び出される DataFetcher#get に注目してみると、 public Object get(DataFetchingEnvironment environment) throws Exception { if (parameters.isTrivialDataFetcher()) { try (AgentScope scope = activateSpan( this .requestSpan)) { return dataFetcher.get(environment); } } else { final AgentSpan fieldSpan = startSpan( "graphql.field" , this .requestSpan.context()); // ...省略 dataValue = dataFetcher.get(environment); // ...省略 fieldSpan.finish(); // ...省略 } startSpan と finish が実行されることが読み取れます。 このように GraphQL クエリに対する処理を実行する前後に処理を追加することで、情報を収集していることが分かりました。 (ちなみに上記の箇所以外では、GraphQL クエリの parse や validation に対する情報が収集されていました) まとめ dd-java-agent や OpenTelemetry Instrumentation for Java は javaagent を利用することで一般的なライブラリやフレームワークに対する自動 instrumentation を実施 GraphQL Java に対する instrumentation は GraphQL Java 側に実装されている checkInstrumentationDefaultState メソッドに Advice を適用して実装を差し替えることで実現 java.lang 系の instrumentation を覗いてみたところ、脆弱性検出のためのコードを含んでいました。(例: java.lang.Math.random の呼び出しの監視 ) ↩
この記事は株式会社エス・エム・エス Advent Calendar 2023の13日目の記事です。 qiita.com はじめに 介護事業者向け経営支援サービス「カイポケ」のQAを担当している中村です。2021年10月に入社して早2年、現在ではQA組織の運営や横断的に複数QAチームに関わりつつ、チームのサポートや改善活動の推進など様々なことを担当させてもらっています。 今回の記事では改善活動で実施した施策の一つである、『E2Eテスト自動化の導入』をテーマにどんなテストを自動化しているか?どんな運用をしているか?など、現状を整理する形でお話ししていきたいと思います。ここでお話しするのはあくまでQAエンジニアの取り組みの事例で、開発エンジニアが実施しているUT(ユニットテスト)などの自動テストは触れませんのでご了承ください。 テスト自動化のお話し 1. どんなツールを使っているのか? 弊社では MagicPod というノーコードのテスト自動化ツールを使用しています。ツール選定の主な理由は以下の通りで、約2年ほど使い続けています。 プログラミングスキルが不要で開発未経験でも導入が容易 テストの実行回数に制限が無く費用を気にせず繰り返しのテストが可能 ローカルPC上でテスト実行が出来るのでプロキシサーバーを介してWEBアクセスが可能 SaaSサービスなので環境構築、保守の手間が不要 2. どんなテストを自動化しているのか? 担当している「カイポケ」では、主にWEBとネイティブアプリ(iPadOS)にサービスを展開しています。現状はWEBを対象にE2Eテストの自動化を進めていて、メンテナンスコストが掛からないように機能や画面に変更が入りにくい部分のリグレッションテスト(機能の追加や改修が入った際、既存機能に問題が起きていないかを確認するテスト)を対象としています。全機能を網羅するとテストケースが膨大になるのでハッピーパスなどの基本機能のテストに絞っていて、バグを見つけると言うよりはシステムが問題なく動作することの確認を目的としています。 3. どんな工夫をしたのか? 過去の経験から実装/メンテナンスコストの増加、属人化、テストの安定性といったところの課題を感じていたので、以下の取り組みをすることでよりスムーズに導入出来るように進めていきました。 テスト実装/メンテナンスコストの削減 MagicPodが提供している以下の機能を活用して実現しています。 共有ステップ(共通化) 複数のテストで使う処理は基本的に共通化 参考: 共有ステップの活用 変数 テストケースやテスト環境によって値が変わるデータやロケーターは変数を使用 参考: 変数の活用 データ駆動テスト 計算結果を確認するようなテストでは、同じテストケースでデータパターン(入力値や期待値)を変えて繰り返し実行をしている 参考: データパターン(データ駆動テスト)の活用 属人化対策 実装者によってテストの書き方が大きく変わらないことや導入がスムーズに行えることを目的とした、実装方針や最低限のルールを記載した手順書を用意しました。以下は手順書の記載例となります。 共通化、変数の使いどころ テストの組み込み方法 コメントの使い方 命名規則(テストケース、共有ステップ、ロケーター) ロケーターの指定方法 テスト実行の安定化 テストの独立性 基本的に他のテストの影響を受けてテストが失敗することを防止するために、テストケース同士の依存関係は無くして、各テストケースが独立して動くように作成しています。また、テストを再実行した際にクリーンな状態でテストが行えるように後処理(テスト中に登録したデータの削除など)を実施しています。 リトライ 不具合ではなくタイミングや不確定要素によるテストの失敗は自動テストのあるあるなのですが、都度テストを再実行するのではなくMagicPodが提供しているリトライ機能を使って自動で再実行する仕組みを取り入れています。途中でテストが失敗した場合に元の状態からテストが出来るように初期化(テスト中に登録したデータの削除など)も実施しています。 実行環境を仮想環境に移行 主にローカルPC上でテスト実行をしているのですが、ブラウザの操作をツールに奪われてしまうので作業が中断してしまう、リモートワーク主体の中でも安定したネットワーク接続が必要(瞬断でもテストが止まってしまう恐れあり)といった課題があり、それに対応するためにテスト実行環境を仮想環境に移行し安定して動作するようにしました。 4. どんな運用をしているのか? 現状はシステムに改修が入った場合やミドルウェアのバージョンアップが入った場合などに自動テストを実行するようになってきて、活用する機会がかなり増えています。簡易的な動作確認であっても、今までは時間をかけて手動で実施していた or 時間の都合により割愛せざるを得なかったのですが、素早く人の手を介さずに毎回テスト出来るようになったことで、より品質に自信を持って高速リリースが出来る状態となったのは大きな利点だと考えています。 5. 現状の課題は? 上述したとおり導入は進められているのですが、課題もまだ残っていて現在進行形で進めている点や今後実施予定としている点をいくつか紹介していきます。 他チームへの拡張 現状は特定のチームでのみ導入が進んでいる状況です。人的リソースやスキル的な課題もあって十分に導入が進められていないのですが、リグレッションテストの使用頻度はどのチームでも高いので少しずつ範囲を広げていきたいという思いがあります。 定期実行の導入 定期実行自体はMagicPodの機能として提供されているのですが、「クラウド」実行のみ使用が可能となっています。前述した通り、弊社は「ローカルPC」での実行をメインとしているので、定期実行を実現するには自前で仕組みを作る必要があるのですが、まだ手を掛けられていないという状況です。 テストの高速化 テストケースが増えたり長くなると、相対的にテストの実行時間が増えてくるといった課題が出てきています。テストケースの見直しや並列実行の仕組み化などやれることがありそうなのですが、こちらもまだ手を掛けられていません。 さいごに 前述の課題対策に加え、開発チームとの協業/分担なども考慮したテスト自動化の最適化も必要になりますし、並行して始まっているリニューアルプロジェクトへの本格導入とまだまだ先は長いです。テスト自動化に関わる人手も今以上に必要になってくることを想定していますので、一緒に働く仲間は絶賛募集中となっています! 最近QA組織の行動指針なるものを構築したのですが、テスト自動化もその中の取り組みの一つとなっています。そちらのブログも合わせて確認していただけると、QA組織の目指しているものがより見えてくるのではないかと思います。 tech.bm-sms.co.jp 少しでも興味を持たれた方がいたらカジュアル面談や選考へのご応募をよろしくお願いいたします。 エス・エム・エス-エンジニア採用情報 ソフトウェアエンジニア カジュアル面談(PM/EM/SRE/QAも歓迎)
この記事は 「株式会社エス・エム・エス Advent Calendar 2023」 の12日目の記事です。 こんにちは、Analytics&Innovation推進部(以下、A&I推進部)の小貝( @oddgai )です。 M-1グランプリの決勝が近づいてきて、今年ももう終わりか〜としみじみしています。 今年は夫婦で真空ジェシカ、令和ロマン、ヤーレンズ、敗者復活でななまがりを応援しています。がんばれ! さて、社内のデータ活用チームであるA&I推進部にデータサイエンティストとして新卒入社して4年目になるのですが、今年の4月から 「カイポケ」のフルリニューアルプロジェクト のエンジニアチームに社内留学してアプリケーション開発も行っています。12月時点だとデータサイエンティスト1割、エンジニア9割くらいの割合で働いています。 この記事では、今年を振り返って なんで/どうやって社内留学したの? 開始から今までにやってきたこと やってみてどう? あたりをまとめようと思います。 なんで/どうやって社内留学したの? 社内留学した理由を一言でまとめると、 今後のキャリアや社内での役割を見据えて、ソフトウェア開発の基礎的な経験を積んでおきたかったから です。これだけ書くと立派に見えますが、もう少し心の内をさらけ出して書くと下のようになります。 研修などでソフトウェア開発の体系的な知識を付けないまま新卒4年目まで来てしまい、 「同世代のデータサイエンティストが当たり前に知っているであろうことを知らない気がする」という焦り があった データサイエンティストとしてエンジニアとやり取りすることも多いが、あまり勝手がわかっていなかった 数理最適化や機械学習などのモデルは最終的に何らかのシステムに組み込まれることも多いので、ソフトウェア開発の知識や経験があったほうがいい 大きな環境の変化がないまま4年目になり若干だれてきた感があったので、何かしらの外的変化がほしかった このようなもやもやがあったので、3年目の終わりの考課面談で上長に相談してみました。周りに社内留学をした人がいなかったのもあり、このときは留学という発想はなく「何かしらの研修を受けさせてもらえたらいいな」くらいの気持ちでした。 そこからあれよあれよという間に話が進み、気づいたらエンジニアチームにいました。裏ではいろんな人が動いてくれていたのだと思いますが、私目線だと下のようなスケジュールになっていて、このときは正直このスピード感に心が追いついていませんでした。 2023/3/8: 考課面談で「開発経験が積みたい」と相談する 2023/3/24: 技術責任者の田辺さん( @sunaot )と面談して社内留学ができる説を知る このときは「やるにしても半年後くらいでしょ」と思っていた 2023/4/24: 受け入れ先チームの空中さん( @soranakk )達と面談する ここで「アッこれすぐの話なのか」と気づく 2023/4/28(その4日後!): チームのモブプログラミングに参加して、以降ほぼフルコミット 開始から今までの振り返り こんな感じでいきなり始まった社内留学ですが、現時点で開始から7ヶ月くらいになるので、今までをざっくり振り返ってみます。 開始〜1ヶ月目:プロジェクトのことを知る期 最初にプロジェクトやチームに関わるいろんなドキュメントをもらったので、そのインプットから始めました。カイポケがリニューアルするのは知っていたのですが、その背景や具体的にやっていることまでは把握していなかったので、そこを埋めるようにドキュメントを消化していきました。 介護業界に関わるドメイン知識などはすでにあって、それに関するつらさがほぼ無かったのは社内留学のいいところだなと感じています。 ちなみに当時の私はこんな資料を残しています(A&I推進部内での報告資料です)。右下のE資格というのは日本ディープラーニング協会が実施している資格試験のことで「開発の勉強もしたいけど資格対策もしないと〜〜〜」と大変な状況でした。がんばれ! 2〜3ヶ月目:バックエンドがんばる期 プロジェクトやチームの動きがある程度わかったところで、実際の開発タスクに手を付け始めます。 ちょうどその頃に着手予定になっていたバックエンドAPI実装をやったのですが、KotlinやSpring Bootを触ったことがなかったので、モブプログラミングで大いに助けてもらいながらなんとか実装しました。 モブプロはオンボーディング関係なくほぼ毎日やっているのですが、これが経験の浅い私にとっては本当にありがたくて、開発の勉強になるだけでなく「昨日〇〇がおいしかった」などの雑談も挟まるため チームの一員になっている感 があり、何もわからん状態だった私は精神的に救われました。やはり雑談は大事。 このAPI実装が終わった後に、チーム全体で別チームのバックエンド開発を手伝うことがあったのですが、そこまで難しくないタスクだったこともあり基本的には独力で進めることができて「なんかイケてるぞ」という自信に繋がりました。 また、この時期にはデータサイエンティストとして、求人のレコメンドAPI開発のプロジェクト管理もしていました。その際、エンジニアチームに依頼してAPIをサービスに組み込んでもらうタイミングがあったのですが、前よりもエンジニアの気持ちがわかるようになっていたからかスムーズに依頼ができて「 データサイエンティストとしてのスキルアップにも繋がってるぞ! 」と嬉しくなりました。 ちなみに当時の気持ちはこんな感じだったようです。えらいぞ!がんばれ! 4〜6ヶ月目:フロントエンドも触ってみよう期 バックエンドがチョットワカルようになってきたので、フロントエンドにも手を出し始めます。 最初は、当時タスクとして挙がっていた氏名入力フォームなどでの姓名分離(バックエンドは対応済みで、画面側の対応)をやりました。 ここでStorybookやChromaticに初めて触れたのですが、「画面がチェックできる!!すごい!!」と感動しました。成果物として実際に動く画面が見られるのは楽しいです。 次に手を出したタスクが当時の自分としてはやや難しく、というのも 最初の仕様ではそこまで難しいタスクではなかった 途中から仕様変更があり、チーム内で触ったことがないコンポーネントを扱うことになった 🤯🤯🤯 という変貌を遂げたもので、フロントエンドチームにも助けてもらいながらなんとか終えることができました。今振り返ると、デザイナーや別チームのエンジニアとやり取りしながら開発する経験ができたのでとても良かったです。 7ヶ月目〜現在:どんどんタスクを拾っていこう期 バックエンド、フロントエンドともに何となく進め方がわかってきたので、引き続き助けてもらいながらもどんどんタスクを拾っています。 積まれているタスクをやるだけでなく「ここの画面ちょっとおかしいですね→後で直しておきます」のような動きもできるようになり、「 俺は!!エンジニアとして働いているぞ!! 」という実感があって楽しいです。 一方で、個々の開発タスクで得た知識や経験を有機的に結びつけられていない感覚もあるので、改めて体系的に基礎を学びたいです。 まとめると今の気持ちはこんな感じです。いいぞ! やってみてどう? 最初は「開発のことなんもわからん」「チームの雰囲気に慣れない」などで大変でしたが、振り返ると本当に良い経験をさせてもらっているなと思います。 具体的に良かったことは挙げるときりがないのですが、ぱっと思いつくだけでこのくらいあります。 経験が浅いところからのスタートというのもあって「先週できなかったことが今週はできるようになっている」が続いて楽しい データサイエンティストとしてのスキルアップにも繋がっている 社内でカジュアルにコミュニケーションできる人が増えて嬉しい モブプロ や 社内版potatotips などの文化がとてもよい エンジニアとの距離が縮まりテックブログへの投稿が増えた このアドベントカレンダーもそうだし、去年なら 「学会に出るから発表資料を公開しよう!」 という発想にはならなかった気がする 外からは見えにくいエンジニアの大変さがわかって、もっとリスペクトが湧いた いつまで社内留学を続けるのか具体的なスケジュールは未定ですが、もっとエンジニアとしてのスキルを伸ばしたいのと、このプロジェクトにもう少し関わっていたいので、もう少し続ける予定です。 おわりに 改めて振り返ると、慌ただしかったですがとても良い刺激を受けた1年でした。 最後になりますが、社内留学のために動いてくれた方々や、日々助けてもらっているチーム内外のメンバーには感謝してもしきれません。本当にありがとうございます! 弊社では、データサイエンティストやエンジニアの採用を積極的に行っています。興味をもっていただけた方はぜひカジュアル面談にお越しください! データサイエンティスト(AnalyticsTranslator) / 株式会社エス・エム・エス ソフトウェアエンジニア カジュアル面談(PM/EM/SRE/QAも歓迎) / 株式会社エス・エム・エス
はじめに こんにちは。エス・エム・エスのプロダクトデザイングループ マネージャーの酒井 ( @_atsushisakai ) です。 エス・エム・エスは、9月30日〜10月1日 に行われた Designship 2023 にゴールドスポンサーとして協賛をさせていただきました。この記事では、 Designship 2023 におけるエス・エム・エスとしての活動の振り返りと、メンバーによる参加レポートとなっております。 はじめてのデザインカンファレンス協賛 エス・エム・エスのデザイン組織としてはこのような大型カンファレンスへの協賛を行うのは初めてでした。今回は協賛にあたって、会場で流してもらえるCM動画やブースデザイン・配布するチラシデザインなど数々の制作も行いました。また、スポンサーセッションへの登壇なども行いましたので、それらを一挙にご紹介いたします。 CM動画「デザインの力で社会課題に挑む」 今回は会場内で流してもらえる15秒という短い時間の枠の中でしたが、多くのメンバーに参加してもらいながら、たくさんの想いを詰め込み、CM動画を完成させました。組織の中にいるメンバーとして見た時にも、ストレートでメッセージ性のある動画に仕上がっていると思います。会場内で流してもらうだけではもったいないので今後色々なところで利用していくことも想定しつつ、エンジニアやPOにも協力を依頼しながら制作しました。ぜひ、色々な方に見ていただきたいです。 スポンサーセッション、パネルディスカッション登壇 会期中には弊社デザイナーの登壇もありました。 Day 1 にはプロダクトデザイナーの戒能孝祐さんがスポンサーセッションへ、 Day 2 にはは同じくプロダクトデザイナーの蔡長宏さんがパネルディスカッションへの登壇を行いました。 戒能孝祐「介護事業にデザインでどう向き合うか」 戒能孝祐さんは2023年4月にエス・エム・エスに入社しました。エス・エム・エスのプロダクトデザイナーとしてのキャリアを選んだ背景や、入社後にどのような難題と向き合っているのか、また、現時点でプロダクトデザイナーである自分自身が組織の中でどのような役割認識を持っているかといったストーリーが語られており、今後のデザイナーとしてのキャリア作りのひとつのロールモデルとして興味を持っていただけたのではと思います。資料を見ていただくだけでも参考になる部分は多いと思いますので、ぜひご一読ください。 蔡長宏「デザインリサーチの重要性」 パネルディスカッションには、蔡長宏さんが参加し、エス・エム・エスにおけるデザインリサーチの重要性や知見を共有しながら、他社のデザイナーの皆さんとディスカッションをしました。リサーチの現場でどのような観点でユーザーを観察するか、観察して得られたインサイトをどのような形でプロダクトチームに持ち帰るかなど、各社のリアルな声を聞くことができ、とても興味深い内容でした。今回、長宏さんは、日本語での登壇が初めて(!)ということで大変緊張していたと言っていましたが、落ち着いてわかりやすく、丁寧に、参加者に向けて誠実に知見を共有してくれました。 ブースでのサービス紹介とアンケート企画 エス・エム・エスという会社のこと、デザイナーが扱っている介護事業者向け経営支援サービスの「カイポケ」のことについて、来場した皆様により深く知っていただくために、今回はブース出展も行いました。ブースでは社会問題に向き合うきっかけとして、簡単なアンケート企画も実施しました。 アンケート企画の集計結果 「 どんな未来を過ごしたい? 」という問いに対して、以下のような4種類のカードを用意して、ブースに来ていただいた皆様に選んでもらい、パネルに貼り付けてもらう形で回答していただきました。このアンケートは、高齢社会で暮らす自分自身が将来どのような事を大切に感じながら暮らしたいか、ということを想像してもらいながら「介護」という世界にほんの少しだけでも触れていただくためのきっかけづくりとして実施しました。じっくり考えて回答してもらう方も多かったり、この「問い」と「カード形式での回答」を社内でも参考にしたいということで、パネルの写真を撮って帰ってくださる方もいたりなどしてとても嬉しかったです。 最終的にはこのような結果となり、パネルからはみ出してしまうぐらいの想像以上に多くの回答をいただくことができました。 集計結果としては、以下のようになりました。 合計回答数: 191件 「健康でさいごまで自立して」74件 「人との繋がりを大切に」70件 「大切な家族とさいごまで一緒に」40件 「慣れ親しんだ街で安心して」 7件 どの回答が正解というわけではないですし、豊かな暮らしを続けるためには全てが必要な要素かもしれません。とはいえ、特に「健康と自立した暮らし」「人との繋がり」を大事にしたいと感じる方が多かったようです。これを実現できる社会を作っていくために我々は様々な問題を解決し、乗り越えていかなければなりません。その課題解決のプロセスにおいて、「デザイン」はとても重要な役割・技術であると我々は考えています。 アンケートに回答いただいたみなさまには、今回のために特別に製作したノベルティ「カイポチくん おくすりケース」をお渡しさせていただきました。こちらも「かわいい!」とお渡しした方々に喜んでいただくことができて、デザイナーみんなで「作って良かった!」と盛り上がりました。 弊社デザイナーによるセッションの感想 さて、最後にカンファレンスに参加し、セッションを聴講したデザイナーの印象に残ったセッションとその感想をお届けします。 大坪 旅人 (クリエイティブデザイン) の感想 印象に残ったセッション: 望月 美憂さん「デザインプログラムマネージャーになって気づいた「これもデザイン」」 セッションの感想 デザインプログラムマネージャーという職種は自社にはないものの、現職でも役立つ考え方が多いセッションでした。 特に、 Design People という、デザインをデザイナーだけに留めず Notion や Figma を通して組織全体で普及させていく考え方が印象的です。 自分はマネージャーではなく、制作業務がメインのデザイナーですが、デザイナーと各部署でのコミュニケーションやドキュメント整備など、日々の取り組みから取り入れられる実践的な話しが聞けました。 組織全体で Design People としてふるまうために、まずはデザイナーがデザイナーという職種に固執しすぎることなく、組織間のコミュニケーションなどからデザインの考え方を取り入れていきたいと思います。 重留奈津美 (プロダクトデザイン) の感想 印象に残ったセッション: 舘山佳奈さん「存在しないものをデザインする・AIをデザインするという事」 ※引用元: https://design-ship.jp/2023/contents/session セッション終盤で語られていた未知のものに挑戦するマインドセットについて、「挑戦する」「前例はつくればいい」「プロセスを楽しむ」の三つを挙げられていましたが、どれも共感するものがありました。AI開発とは一見まったく違うように見えますが、カイポケリニューアルプロジェクトも不確実性の高さと合わせて非常に長期的なプロジェクトであることからくる、不安になるタイミングが多い点・不確かだからこそデザイナーが力を発揮すべきという点など、共通点は多く感じました。"挑戦"と最後に舘山さんが贈ってくれた"楽しむ"という言葉を忘れずに進みたいと思います。 戒能孝祐 (プロダクトデザイン) 印象に残ったセッション: 株式会社ビットキー デザイナー 中沢 大さん「PKのようなレビューをやめた」 レビューをしてくれるメンバーは本来仲間なはずなのに、自分のデザイン(ゴール)を突破しようとする敵のように扱ってしまっていませんか?という問いかけ。PKでなく、パスを繋いで一緒にゴールを狙いにいくようなレビューが理想。聞いたタイミングで、ちょうどそんなレビューをしちゃったかも、、と思って今回いちばん刺さる内容でした。インハウスのデザイナーだからこそ、チームの仲間を信頼していくことは大切にしたいと思えるスピーカーセッションでした。 さいごに 今回、協賛という形で Designship 2023 に関わることができて、デザイナーコミュニティの熱量の高さ、デザイナーが抱えている解決すべき課題の深さと幅広さを改めて実感することができました。また、エス・エム・エスのデザイナー目線では、部署の垣根を越えてたくさんの制作物を共同で作り上げたことで、チームとしての帰属意識・目的意識を統一することができたりなど社内向けの観点としても、とても良い経験となりました。 今後も、エス・エム・エスのデザイン組織として、もっともっとコミュニティに知見を還元したり、他社のデザイナーの皆さんとも繋がりを積極的に作っていきたいと考えています。 さいごに、ぜひ、エス・エム・エスのデザイン組織にご興味を持っていただけたのであれば、ぜひ採用情報もご覧いただけると嬉しいです。 r-kaipoke.bm-sms.co.jp
この記事は 株式会社エス・エム・エス Advent Calendar 2023 の11日目の記事です。 無いに越した事はありませんが、サービスを長い間運用しているとどうしてもシステム障害対応をやらなければいけないタイミングがあります。この記事では、小規模なアラート対応から数日間に渡るチーム横断での大規模障害までいくつのシステム障害対応に関わる中で実際に私が行ってきた事を 11 個紹介してみようと思います。 前置きとして、現在私が所属するチームはほぼ100%フルリモートで開発を行っており、それを前提とした内容になっています。 1. 専用のコミュニケーションスペースを作る 2. 役割分担をする 3. 積極的に音声通話でやりとりする 4. 情報整理用のダッシュボードを作る 5. 専用のカンバンを作る 6. 情報同期のための定時ミーティングを設ける 7. 通常業務を進めるメンバーを残す 8. メトリクスのスナップショットを残しておく 9. 異なるメトリクスを同じ時系列で並べる 10. 他のチームにも相談してみる 11. 意識して休憩を取る 最後に 関連資料 1. 専用のコミュニケーションスペースを作る まず、障害対応モードに入ったほうが良いと判断したタイミングで誰でも良いので専用の Slack チャンネルを作ります。これにより障害対応の情報を一つのチャンネルに集約して、普段チームが利用しているチャンネル上で障害対応の情報がノイズとならない様にします。関連する情報へのリンクは slack チャンネルの関連ページや canvas に記載しておきチャンネルから辿れる様にしておくと便利です。 その後、チャンネルを作ったらすぐにチャンネル上で huddle を立ち上げて関係者を呼び寄せ、障害対応の情報収集や役割分担を行います。 2. 役割分担をする 意思決定を迅速に行うために、インシデントコマンダーを頂上とした階層構造の組織体制を作ります。 指揮官(インシデントコマンダー) -- 全体の指揮を取り、他の役割を動かすための意思決定を行う 外部連絡役 -- カスタマーサポートやリスクマネジメントの部署とやりとりをし、チーム外とのコミュニケーション窓口となってもらう。普段からそういった部署とやりとりをしてもらっているメンバーに担当してもらう場合が多い。 観測・記録役 -- 原因調査・復旧担当や外部連絡役から入ってくる情報をまとめて、皆に伝えやすい形にする。インシデントコマンダーである自身が兼任する場合も多い。 原因調査・復旧担当 -- サーバーのログやメトリクスの調査を行い原因調査を行う。ほとんどの場合技術者が担当する。 場合によってはこれら以外にも現象の再現を試してもらう役割を作るなど臨機応変に対応します。いずれの役割を決める際も、コミュニケーションが混線してしまわない様に役割に対してまとめ役を必ず1名任命して、基本的にインシデントコマンダーはそのまとめ役とコミュニケーションを行う様にします。 なお、私の所属するチームはスクラムチームとして活動しているため通常時はトップダウンで意思決定を行う事はほぼありませんが、障害対応の際は例外的にこの様な体制に切り替えています。 3. 積極的に音声通話でやりとりする 障害対応では不確定な判断材料でリリース内容のロールバック、サービス停止、サーバースペック増強等の難しい判断を迅速に行う必要があります。このためコミュニケーション速度が速く、微妙なニュアンスを把握しやすい音声通話でのやりとりを積極的に使って作業を行います。特に対応初期はメンバーが揃わず情報収集もしづらいため、しばらく huddle を立ち上げっぱなしにしておいて状況の変化があった際にすぐに報告したり、何かを確認する際に声をかけやすい状況を作ります。 注意点としては、あまり多くの参加者が障害対応の本部機能を持った音声通話に入ってしまうと本部機能のノイズとなってしまう事があるため、役割分担が済み原因調査が動き始めたタイミングでそれぞれの役割ごとに音声通話を分けてもらう様気をつけています。 4. 情報整理用のダッシュボードを作る 障害対応時の情報整理は Notion 等のドキュメント管理ツールより miro の様なオンラインホワイトボードをダッシュボードとして使う様にしています。 ドキュメント管理ツールはシーケンシャルに構造化された情報を扱うのには向いていますが、複雑な関連性を表す表現力はありません。 オンラインホワイトボードツールであれば位置関係が離れている情報もドラッグアンドドロップですぐに移動できますし、何より縦横の二次元で情報を表現できます。更に位置関係を変えずに線を引いたり要素を囲ったりしてあげることで柔軟に情報の関連性や構造を表す事も可能です。複雑な判断要素が絡む障害対応ではこういった点が情報整理にとても役に立ちます。 5. 専用のカンバンを作る 状況が混乱していると記憶や認識のずれが発生しやすくタスク状態があやふやになる場合が多いです。これを避けるために障害対応専用のカンバンを作ります。私は miro の カンバン 機能を使い、標準のカラムに Backlog というカラムを追加して Backlog (検討中のもの) To do (実施が決ったもの) In Progress (対応中) Done (完了) というカラムがある状態にしています。今後進めるタスクの提案はいったん Backlog に入れて、対応する事が決まったものは To do へ、実際に実施中のものは In Progress へ移動して、状況が変わったら Done へ移動したり Backlog に戻したりといった運用です。 miro のカンバンは担当者を設定したり期日を決めたりすることも可能ですし、ホワイトボード上の他の情報から矢印を引っ張って関連付けを行う事ができるため GitHub Projects や Jira 等のカンバン専用のツールよりも柔軟な使い方ができます。障害対応では、この様にラフに使えるタスク管理方法のほうが情報を整理しやすいです。 6. 情報同期のための定時ミーティングを設ける 状況に応じてだいたい1〜2時間ごとに情報同期のための定時ミーティングを設けます。このミーティングでは 現在の状況に合わせてカンバンのアップデート 新たに発見した情報の共有 次に実施・中止するタスクの選定と担当決め を行っています。このミーティングは不確定要素の多い状況への適応とその対応を行うためのリズムを作ることを目的として、スクラムのデイリースクラムとプランニングをとても短い間隔で行うイメージでやっています。 7. 通常業務を進めるメンバーを残す 障害が発生すると不安から「全員で障害対応を行おう!」という気持ちになってしまう事があります。しかし、障害の内容によってはその原因調査を行えるメンバーが限られていたり、障害対応以上に重要な通常業務が存在する場合もあります。必要以上に障害対応への人員投下をするのでは無く、障害対応に入ってもらう必要があるメンバーを明確にしたうえで「〇〇さんは通常業務をお願いします」と、障害対応に入らなくて良いメンバーが明確になる様にしています。 8. メトリクスのスナップショットを残しておく メトリクスも種類によって保存期間や時間経過で情報の粒度が粗くなってしまい、障害発生当時のメトリクスが後から再現できなくなってしまう事があります。これを避けるために、気がついたタイミングで必ずメトリクスのスナップショットをスクリーンショットで残し miro に貼り付けておく様にしています。この際グラフがなるべく細かい単位で描画される様にしておくのもポイントです。 9. 異なるメトリクスを同じ時系列で並べる 障害発生時の状況把握を行う際はサーバー負荷やエラーレート、お問い合わせ発生日時等といった様々な情報の関係性を把握する必要があります。これを行うには同一時系列上に並列で異なるプラットフォームで取得したメトリクスを並べるのが効果的です。 ここで活用できるのが 8 で残しておいたスクリーンショットです。miro 上でx軸の時間を他のスクリーンショットのx軸の位置と合わせることで AWS 上のメトリクスや Datadog , Google Analytics といったプラットフォームの垣根を超えて同じタイミングで同時に変化が起こっているという状況が把握しやすくなります。miro であればグラフ上の気になる部分に注釈を付けたりする事も簡単にできますし、複数のスクリーンショットを繋げる事でブラウザ上では描画が難しい、長時間に渡るグラフを表現する事も可能です。 10. 他のチームにも相談してみる 障害対応にあたっているチームで原因や対策方法が見つからず解決が難しいと感じた場合、他のチームにも何か気がついた点が無いか相談してみます。複数のサブシステムが一つの共有リソースを使っている様なサービスの場合、特定のサブシステムでのみ発生していると考えられていた問題が実は別のサブシステムの影響によって発生していたり、共有リソースの問題がたまたまそのサブシステムに影響を与えていたという事もあり得ますし、他のチームメンバーが持っている専門知識によって意外な解決策が見つかる可能性もあります。 緊急事態なので、頼れる物は貪欲に頼るのが吉です。 11. 意識して休憩を取る 障害対応は場合によっては深夜作業や休日作業が発生してしまい体力的にハードなものです。この状態が続いてしまうと判断力が低下し、通常業務では行わない作業をやっている事も相まって不適切な情報を共有してしまったり、オペレーションミスでデータを削除してしまったりといった二次災害 1 を招いてしまう事があります。これを避けるために、意識して休憩を入れる様にします。 打ち合わせや議論が長くなる様であれば1時間ごとに小休憩を挟み、できるだけ昼休憩は通常と同じ様に設け、日が変わる前に一旦その日の対応を終え翌日再開できる様な動きができると理想です。当然それが難しい状況もあるのですが、その場合はシフトを組むなどして負荷が集中してしまわない様に配慮します。 最後に この記事を書くために当時の slack チャンネルを見ていると大変だった記憶が蘇ってきました。システム開発に関わる皆さんが、年末年始は何も起きず無事な年越しができる事を祈っています。 最後に、私が障害対応をするにあたって参考にしている資料を記載しておきます。 (筆者: プロダクト開発部桐生) 関連資料 今日からできる。初めての障害対応ガイド | DevelopersIO (dev.classmethod.jp) インシデント指揮官トレーニングの手引き | Yakst (yakst.com) Google - Site Reliability Engineering (sre.google) 重大事故の時にどうするか?|miyasaka (note.com) -- ヤフー株式会社(現LINEヤフー株式会社)の元社長宮坂さんによる記事。 (PDF) National Incident Management System - Incident Command System (ICS) | FEMA.gov (www.fema.gov) -- アメリカ合衆国連邦緊急事態管理庁の資料。 Google SRE の資料中でもこのシステムが参照されており、インシデントコマンダーという役割を理解する際に Incident Command System (ICS) の章を翻訳しながら読みました。 疲労が原因によるものでは無いですが、ちょうど最近クラスメソッドさんでもクライアントのインシデント対応にあたって実施した作業でオペレーションミスによる障害が発生していました。 2023年12月5日に発生した複数AWSアカウントが操作不能となった障害について | クラスメソッド株式会社 (classmethod.jp) ↩
はじめに この記事は 株式会社エス・エム・エス Advent Calendar 2023 の 10 日目の記事です。 カイポケリニューアルプロジェクトでエンジニアリングマネージャーをしている @hotpepsi です。 フロントエンドのチームが本格的に立ち上がってから一年ほど経過しました。現在では二つのフロントエンドチームが日々活発に開発しており、多くの時間は、アプリケーションコードを書いたり、より良い仕様を議論したりすることに費やしています。並行して、コンポーネント共通で発生する問題を解消したり、開発者体験や生産性を向上させる取り組みも数多く行ってきました。 今回は一年分のまとめとして、アプリケーション固有でない様々な取り組みについて紹介したいと思います。 こんな感じのスクリプト で一年分のフロントエンド共通の pull request の title と description を markdown で取得して、その中から 100 個をピックアップしました。カテゴリごとにおおよそ時系列に並んでいます。両方のカテゴリにまたがるものは関連性の高そうな方に分類しました。 利用しているフレームワークやコンポーネント 前提として、カイポケリニューアルプロジェクトのフロントエンドチームでは、以下のフレームワークやコンポーネントを利用しています。この構成になった経緯は「 大規模 SaaS 「カイポケ」の未来を支えるフロントエンドの技術選定 」にありますので、ぜひご一読ください。 言語: TypeScript UI framework: Next.js , Chakra UI linting: ESlint GraphQL client: Apollo Client state management: Recoil form: React Hook Form schema validator: Zod component catalog: Storybook testing framework: Jest testing library: Testing Library visual regression testing: Chromatic やったこと 共通ガイドラインやファイル構成 コードレビューガイドラインを追加 はじめに、pull request のテンプレートや、大まかなレビュー方針を作成。 コーディングガイドラインを esa から移設 開発者のドキュメントは esa に書いているが、コーディングガイドラインは GitHub にあるほうがレビューや議論がしやすいので移設した。 テスト実装に関するガイドラインを追加 なぜテストを書くのかや、Storybook の活用方針などを記述。 モノレポに移行 プロジェクトチーム全体で議論した結果、モノレポに移行した。サービス毎の GitHub Actions の調整などは必要だったが、GraphQL のスキーマ管理などがしやすくなった。 Props に type を使うことにした Props に interface と type が混在していた。たいていは type で十分であり、意図しない拡張も防げるので、 type を使うことにした。そのあと、Props 以外でもなるべく type を使っていくことにした。 Node.js のバージョンを固定する CI や開発者の Node.js のバージョンを揃えることにした。 package.json での記述など、複数の手段を検討したが、ツールの選択肢などを考慮して .node-version で固定することにした。 ファイルコロケーション テストを tests/ 、ストーリーを stories/ に置いたりしていたが、関連するファイルが同じディレクトリにあるほうが見通しがよくなるので、コロケーションを採用した。 named export への移行 default export を行っているコードが少し存在したが、 なぜ default export を使うべきではないのか? を参考にして、named export を利用することにした。既存のコードを修正して ESLint の import/no-default-export も追加した。 コードレビューガイドラインにコメント prefix を追記 question: や suggestion: や nits: など、コードレビューのコメント時に prefix をつけて意図を明確にすることを推奨することにした。 ポータルドキュメントを GitHub に設置 様々な場所にストック情報が増えてきたので、フロントエンドチームのミッション・ビジョン・チーム構成などへのリンクをポータルドキュメントとして一箇所にまとめた。 テストガイドラインに、推奨するテストの書き方を追加 Common mistakes with React Testing Library で紹介されているようなベストプラクティスを導入していて、ガイドラインにも反映した。 zod の import 方法の統一 import * as z from 'zod'; と import { z } from 'zod'; が混在していて、 公式ドキュメント などを参考に、後者に揃えた。 ファイル名の規則の lint ルール化 コンポーネントの名前やファイル名は PascalCase、ディレクトリ名を lowerCamelCase にしており、それを lint ルール化した。 eslint-config-airbnb-base を参考に lint 設定を見直し ソースコードの src ディレクトリへの移動 ソースコードが src/ 以下にあるほうが grep や lint に便利なので、移動した。 PropsWithChildren 利用の lint 化 子要素を受け取るコンポーネントは PropsWithChildren の利用を推奨している。 no-restricted-syntax の selector を使ったカスタムルールにより、 ReactNode の children を検出してエラーにするようにした。 Design System Chakra UIでDesign Systemを構築 アプリケーションコードからChakra UIのimportを禁止する 基本的な部品を全てデザインシステム上に構築できたので、アプリケーションから直接importしないようにした。 import/no-restricted-paths により検出。 Design SystemのStorybookの分離 Design SystemのStorybookをアプリケーションから分離した。 Storybook と Chromatic StorybookでHMRを有効化 GitHub Actions で Chromatic を実行する Chromaticによりvisual regression testを行うようにした。 Fakerの結果を固定する モックデータをFakerで生成しており、毎回異なるとChromaticの差分として検出されてしまうので、seed値を与えてデータを固定するようにした。(なおその後Fakerを利用するテストを削除したため使わなくなった) Chromatic導入に伴うレビューガイドラインの更新 pull requestレビュー時に、見た目の差分がある場合には確認して承認する必要があるので、ガイドラインを整備した。 mainブランチマージ後にStorybook をビルドする featureブランチだけでなく、 main ブランチにマージされたときにもChromaticでビルドするようにした。 main ブランチのStorybookはURLが固定されているので、他のチームに共有するときに使用している。 Chromaticで意図しない差分が出るStoryをUI Testの対象から除外する ポップアップなどのアニメーションを使用しているStoryで、変更がなくても差分として検出されてしまうケースがあり、 delay オプションでも解決できなかったので、 disableSnapshot オプションで除外した。 除外対象の一部修正 レンダリング終了より早くクリックしてしまっていたケースがあったのを修正。 Chromaticの TurboSnap を有効化し、スナップショットの数を減らした Chromaticの差分が生じたときにコメントする Chromaticで差分が検出されたとき、見逃してマージしてしまうことがあるので、差分が発生したというコメントをpull requestに追加するようにした。 create-or-update-comment を使用した。 フォントのプリロードについて調査 Chromaticの結果が不安定なコンポーネントがあり、 公式ドキュメント に従ってフォントのプリロードを試したが、改善しなかったため導入しなかった。 Storybook 7 へのアップデートとマイグレーション Chakra UIが対応したため、Storybook 7にアップデートした。これだけで1記事にできるくらいの更新があった。 CSF もバージョン3にした。 日付に依存したStoryの現在時刻を固定する 現在月を表示する画面で、月が変わるごとに差分が発生していたので、 mockdate により日付を固定した。 ChromaticでModalやPopoverのスナップショットを修正する play関数やアニメーションにより描画領域が変化する要素のスナップショットを安定して取得するために、画面サイズを指定した。 pull requestのマージにChromaticの結果の承認を必須にする Chromaticの差分があるとき、承認せずにマージしてしまうと、baselineが更新されないため他のpull requestでも差分として表示してしまう。そのため、差分があったらpull requestの必須のアクションの状態をpendingにして、承認するまでマージできないようにした。 Chromaticの結果のリンク先をChromaticの対象ビルドにする Chromaticの結果(UI Tests)がアプリのトップページにリンクしていて不便だった。pull requestのイベントの github.event.target_url にビルド毎のURLが入っているので、それに書き換えた。 main ブランチでの実行では autoAcceptChanges を有効にする Chromaticの結果の承認を必須にできたので、 autoAcceptChanges を設定して、baselineを更新するようにした。 PR時の reactDocgen の無効化 Chromaticを高速化するため、pull request作成時にStorybookの reactDocgen を無効化した。 各ページにStoryを書くことにした コンポーネントだけでなく、ページのStoryも書くことにした。Storyやテストも同じ場所におけるように、ビルド対象であるページのファイル名のsuffixを .page.tsx とした。 テスト JestやStorybookでGraphQLのクエリをテストするためMSWを導入 MSWのレスポンスに型制約を与える @graphql-codegen/typescript-msw を導入した。 mockの姓名を 名姓 から 姓名 にする fakerが生成する fullName が 名 姓 の順だが、逆にした。 Jestのタイムゾーンを東京に固定 console.error が出ているテストがあれば CI を失敗させる CI でtestとbuildを並列で実行する テスト実行時間の可視化 10秒以上かかっているテストを洗い出し、分割するかどうか検討した。 CIのJestのテストを高速化する --shard と --maxWorkers を与えて並列実行するようにした。 CI にキャッシュを設定して実行時間を速くする main ブランチにpushしてビルドするとき、キャッシュを保存するようにした。 Jestでwrapperを書かなくて済むようにする custom renderを定義し、 ApolloProvider や RecoilRoot など、共通で必要なwrapperをいちいち書かなくて済むようにした。 Jestを3回リトライするようにした テスト実行時間のばらつきがあり、タイムアウトして落ちるテストがあるので、リトライするようにした。 ローカル開発ではJestをリトライしないようにした fireEvent よりも userEvent の利用を優先する userEvent のほうが実際のユーザーの操作に近いため、推奨することにした。lintルールも追加した。 テストの実行時間が長くなる場合は fireEvent の利用を許可する旨をドキュメントに追加 テストのshardingの改善 テストの実行時間のばらつきがあるため、前回の実行時間を考慮するTestSequencerを実装し、shardingを改善した。 testing library v14対応 jest.useFakeTimersを使うと userEvent が終わらない問題の対処などを行った。 Larger Runnersの導入 テストの高速化のためLarger Runnersを導入した。Jestの maxWorkers は CPUコア数 - 1 にした。 mainブランチではテストを1shardで実行する CIのキャッシュの効率化のため、 main ブランチではテストを1shardで実行するようにした。 JestのエラーをSentryに送る Jestで失敗したテストを、テスト用のSentryプロジェクトに報告するようにした。 テストの日付を固定する 現在時刻から年齢を計算して表示する画面があり、 useFakeTimers により日付を固定した。 main ブランチのCIが失敗したらSlackに通知する 大量の文字入力のテストをclick/pasteに変更した 大量の文字入力をチェックする際に、 user.type ではテストに時間がかかるため、大量の文字を扱う場合は user.paste を利用するようにした。 lintとデプロイ失敗時にもSlackに通知する 共通コンポーネント 編集中にブラウザの戻るボタンをクリックした確認ダイアログを表示する ブラウザバックを監視するカスタムフックを実装した。 カレンダー編集UIのパフォーマンスチューニング データ量が多い複雑な編集画面のパフォーマンスを改善するため、オリジナルの仮想スクロールを実装した。 Kaipochiコンポーネントを追加 カイポケのマスコットキャラクターであるカイポチくんを追加した。なおカイポチくんの身長は133.4cm、体重はイチゴ3個分である。 ゼロ埋めの内部処理を標準組み込みメソッドに置換 標準メソッドに String.prototype.padStart があったのでゼロ埋めのメソッドを置き換えた。 電話番号の表示にハイフンを付ける libphonenumber-js を導入して、電話番号の表示にハイフンを付けた。バンドルサイズを軽くするため、 Customizing metadata の方法で日本のmetadataだけ使うようにした。 Feature Flagの導入 開発中の機能を限定された範囲で有効にするため、Feature Flagを導入した。 デバッグ用に日付を固定する 日付や時刻によって挙動が異なるページがあるため、デバッグ用のデータをlocalStorageに保存して、特定日時にできる機能を実装した。 Storybook用のFeature Flag判定を追加 Storybookのみで有効になるコンポーネントが実装できるようになった。 Next.js Dynamic Routing で 403 になった際のフォールバックを追加 SPAかつCloudFrontの環境で、Dynamic Routingを使ったページでリロードすると、プレースホルダ置換後のURLをアクセスしようとして403となっていた。CloudFront内で403を404にリダイレクトし、アプリケーションの404のハンドラ内で、routerで元のページに戻すようにした。 Dynamic Routingで存在しないページをリロードしたときに404にする 存在するページのみでリダイレクトしたいので、ビルド時にページの一覧を生成して、マッチしたページがあるときだけ遷移するようにした。 アプリヘッダの再レンダリングを抑える アプリのレイアウトをページコンポーネントの .getLayout に移し、再レンダリングを抑えるようにした。 フォーム 全角の英数字入力を許容する フォームのバリデーションのタイミング変更 onChangeでバリデーションを行うと、入力してすぐにエラーとなり体験が悪かったので、バリデーションのタイミングをonTouchedに変更した。 入力した文字の前後の空白・タブをtrimする GraphQL Apollo Server でモック用の GraphQL サーバーを起動 refetchQueriesに関するガイドラインを追記 リスト系のデータの再描画では refetchQueries を発行する必要があり、いくつかの注意点をガイドラインに追記した。 特定コンポーネントのGraphQLのqueryにprefixをつける GraphQLのクエリ名が衝突しないよう、prefixをつけることにした。 @graphql-eslint/naming-convention により判定。 near-operation-file-preset 設定 .graphql ファイルをコンポーネントと同じディレクトリに生成するために @graphql-codegen/near-operation-file-preset を導入した。 フロントエンドでのsupergraph生成をやめ、バックエンドのファイルを参照するように修正 GraphQLのsupergraphの生成方法を試行錯誤した結果、最終的にバックエンドで合成するようにした。フロントエンド側ではCIのタスクでコピーして、変更点を確認したり壊れていないかどうかを検証するようにした。 複数のmutationを呼んだ時も確実にrefetchするようにする @deprecated の扱いを warn にする APIに @deprecated をつけるタイミングをフロントエンド側で決められず、 error だとCIが失敗するので、 @graphql-eslint/no-deprecated のルールを warn に変更した。 GraphQL 利用側の推奨ルールを導入 @graphql-eslint/operations-recommended を導入した。 Renovate Renovateの導入 パッケージのアップデートのため Renovate をGitHubに導入した。 Next.js を Renovate から除外する Next.jsのバージョンアップは慎重に行いたいので、Renovateからは除外した。 Renovateが作成したpull requestではChromaticを実行しないようにする ライブラリのアップデートでは見た目が変わらなかったり、頻繁にrebaseされたりするため、botが作成したpull requestでは自動実行しないようにした。 ChromaticのCIを手動で回せるようにした 見た目を確認したいこともあるので、手動でも起動できるようにした。 特定のライブラリのアップデートでChromaticを実行する Renovateが作ったpull requestはChromaticを実行しないようにしたが、Storybookなど見た目に関わるライブラリのアップデートではChromaticを実行するようにした。 手作業で閉じたRenovateのpull requestが再度作られないようにする Renovateが chore(deps): をつけたりつけなかったりして閉じたものを再度作るケースがあったので、 semanticCommits を enabled にして常に付与されるようにした。 GitHub actions デプロイ通知を良い感じにする デプロイ成功時のアイコンを機嫌の良いカイポチくんに、失敗時にはしょんぼりしたカイポチくんにした。 pull requestを作るbotは自前のトークンを使う GITHUB_TOKEN でpull requestを作成するとCIなどのワークフローが起動しないため、自前のトークンに置き換えた。 ドキュメントだけ更新したときにコード系のactionsを起動しないようにする dev環境へのデプロイを直列にする main ブランチにマージするとdev環境にデプロイするようになっていて、近いタイミングでマージするとリソースが壊れることがあったため、直列にした。 その他 pre-commit フックに時間がかかるので pre-push でチェックする Huskyのpre-commitを導入していたが、小さい単位でコミットしようとすると地味にlint待ちが発生していた。基本的にVSCodeで整形&lintされているので、pre-pushに変更した。 git pull時に package-lock.json に差分があれば npm install する Huskyのpost-mergeで実装。 フロントエンドのhooksを希望者のみで発動するようにする モノレポで開発しており、必要な開発者だけhuskyのhooksを動作させたかったが、 npm install を実行したバックエンドの開発者でも発動してしまっていた。 .env.local ファイルに特別な記述をしたときだけ発動するようにして解決した。 Hygen 導入 循環参照の調査と修正 eslint-plugin-import の no-cycle で検出した。ルールを追加するとlintの時間が大幅に増加し開発効率が著しく下がるため、発見のみに使用した。 pre-push の処理を並列化 https://github.com/open-cli-tools/concurrently を導入してpre-push の処理を並列化した。 バージョン番号の生成スクリプトを作成 commit hashなどをJSONファイルとして公開し、どのバージョンがデプロイされているのか取得できるようにした。 ローカルデータ追加用のE2Eテストの設定追加 Playwrightを導入して、ローカル開発環境でユーザー登録から初期データ投入までできるようにした。 おわりに フロントエンドの技術は年々進化して複雑化しており、モダンな開発を普通に実践しようとすると、多岐にわたる取り組みが必要になることが確認できました。今後も、中長期のプロダクトを想像しつつ、より良い技術や手法をバランス良く取り込んでいきたいと思っています。 なおエス・エム・エスでは、フロントエンドだけでなく、様々なポジションで開発メンバーを募集しています。興味を持った方は、ぜひお気軽にお声がけください。
この記事は株式会社エス・エム・エス Advent Calendar 2023の9日目の記事です。 qiita.com はじめに 株式会社エス・エム・エスでエンジニアリングマネージャーをしている @emfurupon777 です。今回は両利きの経営という考え方をエンジニア組織に適用していくにはー?を考えてみる。ということで、概要の紹介と弊社の今年の取り組みをあてはめてみようと思います。 ※記載内容に誤りなどがある場合は筆者のX(旧Twitter)宛に連絡をいただけると幸いです。 参照書籍 エンジニアにとっては馴染みが薄い書籍かもしれないのですが、こちらです。 str.toyokeizai.net 原文は "Lead and Disrupt: How to Solve the Innovator's Dilemma" で受ける印象が学術っぽいですが、日本語では表紙に『「二兎を追う」戦略が未来を切り拓く』と書いてある本です。どうでもいいことですが、一石二鳥が座右の銘の私にとっては、日本語のほうがちょっとテンションが上がる好きな表現です。 両利きの経営 企業が両利きであるということはどういうことなのでしょうか。 企業活動における両利きは、主に「探索(exploration)」と「深化(exploitation)」という活動が、バランスよく高い次元で取れていることを指す。 ざっとまとめてしまうと、探索とは既存の枠を超えて破壊的イノベーションを生む活動で、リーダーシップ課題ととらえることができる。一方で、深化とは主に既存事業において品質や性能、効率性などを向上させることによる漸進的イノベーションを生む活動で、マネージメント課題としてとらえることができる・・・のような定義と理解しました。 両者では行動原理やKPIが異なるということですね。確かにこれを一人、一組織が同時に実行に移すことは難しそうです。みなさんの所属している組織では、今両利きの経営が意識的に行われている状態でしょうか? そもそも変化が速いなかで、両利きの経営が求められている企業は多い気がしますし、エンジニアとしてはキャリアの中で、0->1, 1->10, 10->100といったフェーズの違いを意識していることも多く、探索と深化の両方を経験してきた/経験しようとしていることが多いのではないでしょうか?(採用活動の中でも、最近は「今回はこの経験が得られる環境を探してます」と明言される方が多い印象です) また、本書のなかでリーダーも失敗を認めるといったことも挙げられているのですが、アジャイルを志向しているプロダクト開発のコンテキストでは当然だと思うので親和性も高そうです。 なんだかエンジニアにとっても、組織のあり方を定義していくのに良さそうな考え方ですね。スゴイ、やろう、すぐやろう、今やろう。・・・では実践していくのに何が重要なのでしょうか? 浸透させるのは価値観ではなく行動 両利きの経営をしていくためには探索と深化をつなぐカルチャーが大事だと説かれています。そして、組織が価値観(VALUES)を持つことは良いが、コントロールしていくためにはその価値観に基づいて期待される行動(NORMS)を明確にせよと言います。 例えば、様々な国がカルチャーを持っていることは誰もが認めているが、国の文化は価値観ではなく、予想される行動でしょ?組織として浸透させられるのは行動だよね、ということのようです。 具体例として挙げられていたマイクロソフトの変革では10のこと全てを行う必要があった、とまとめられています。これは非常に参考になる事例だなと思います。 news.microsoft.com しかし、マイクロソフトのサイズでこれら全てを実行するというのは、かなり難易度が高そうですね・・・ エス・エム・エスでの取り組み さて、弊社の取り組みについてです。 弊社では今年、まずテックブログにおいてカルチャーを言語化してみました。 tech.bm-sms.co.jp とはいえこれだけでは浸透は期待できません。様々なところでMVV(Mission Vision Value)は言語化する取り組みをしているものの、その浸透に四苦八苦・・・というのを多く目にし、私自身も経験してきました。 そこで、価値観を体現する行動をとっている社員をピックアップして紹介し、さらに最近技術責任者の田辺からは学習することへの投資の観点で推奨する行動の一部について発信してもらいました。 tech.bm-sms.co.jp これらはもちろん社内の取り組みとして実践していくことも可能ではあったのですが、両利きの経営において例示されたマイクロソフトにおいて、参考になるコンテンツがオープンでリーチしやすい状況にあったことがやはり良い体験でした。そのため、弊社も外部にもオープンなテックブログという場での発信によって、弊社について知っていただくとともに、あわせて社内への浸透もはかっている面があります。 今後について 弊社は創業から新規事業の開発とその継続的成長が重なって発展してきている会社です。そのため、我々エンジニアリング組織がマーケットに向けて働くにあたって、常に変化をしながら両利きの経営を実践していくケイパビリティが必要だと私は考えています。そのために我々のカルチャーをより強くしていきたいです。 先日、『両利きの経営』著者オライリー教授の講演(JBPress社 第19回 DXフォーラム)をきいていたところ、強いカルチャーを持つ企業がとっている手段として下記のような5つが挙げられていました。 5 Levers for Managing Culture (the LEASH Model) Leader Actions Employee Involvement Aligned Rewards Stories, Symbols and Signals HR Alignment どれも掘り下げていくと取り組みがいのあるテーマですが、私も(失敗しながらも)継続的に挑み続けたいと思います。そして、これらについて社内の取り組みだけでは視野が狭くなりそうなので、同じようなことを考えているエンジニアリング組織の方はぜひ情報交換してみたいです。 おまけ 知っていることと行うことは同義ではないとして、F・スコット・フィッツジェラルド氏の言葉として下記の紹介されていました。 「頭の中で相反する二つの考えを同時に持ち、なおかつ、その機能を維持することができるかどうかが、第一級の知性を占う試金石となる」 第一級の知性であるかどうかは別にして、これを行っていますよ、と自信をもって言える組織でいられるといいなーと素朴に思いました。 そして、弊社に興味を持っていただけた方は、ぜひこちらのページものぞいてみてください!
この記事は、「株式会社エス・エム・エス Advent Calendar 2023」7日目の記事です。 qiita.com Webサービスが長期間運営されると、成長に伴い複雑なプロダクトコードが蓄積されます。このような長寿サービスは多くの人が関わってきたということでもあり、様々な思いや依頼のもとにプロダクトコードが少しずつ変わってきています。そんな長いサービスに対して手を加えるとき、関わってきたすべての人たちがコミュニケーションできる範囲内にいるとは限りません。そのため、いまあるプロダクトコードから当時の意図を汲み取り、手を加えるという場面は多く存在すると思います。 これらの場面に直面する話は多くあれど、実際にどのように読み進めていくかというのはあまり多くは語られていないと思っています。そこで今回は「過去携わった人が近くにおらず、GitHub上でバージョン管理されたコードを読み解きながら改修をする」というようなシチュエーションを想定して探り方と直し方のアプローチ例をご紹介できればと思います。 どのようにアプローチするか 今回は、以下のような改修の依頼を題材に、大きく3つのステップに分けて取り組み方の例をご紹介していきます。 『TOPページのリストアイテムの並べ順を更新日時が「更新日:2022-11-20」の形式になっているので、その値をもとに日付の降順に並べ替えてほしい』 1.変更箇所にあたりをつける まずは改修する機能とソースコードの位置に関してあたりをつけます。これは改修依頼の内容によってアプローチは変わりますが、一番直感的な追い方は「改修箇所のユニークな部分から特定する」というやり方がよいと思います。 たとえば今回ののような改修の話であれば、"更新日:"という文字列を手がかりに探すということができます。もちろん扱っているフレームワークの構造などから「TOPページ」というところを手がかりに探すこともできるので、自身の持ち合わせている知識や利用しているフレームワークの特性を活かしてで特定していくのがよいと思います。 変更する場所がわかったら次は歴史を追っていく作業です。 2.GitHubのblameとhistoryの機能を利用して「何故行われたのか」を追う ソースコードを改修するときに「なぜ今の形になっているのか」というのを確認する作業が必要な場合が多いです。その時に役に立つのがblameです。blameは直訳すると「非難」という意味なので物騒な言葉ではあるのですが、GitHubでソースコードを探すときには大変有効に利用できます。 GitHubのblameの機能を利用すると、行単位に「いつ」「誰が」「どのコミットで」変更してくれたのかを可視化してくれます。 この機能を使うことにより、目星をつけた改修箇所のコミットを確認できるので差分を確認することができます。また、コミットがわかるので、コミットに紐づくPullRequestも確認することができます。PullRequestを見ることができればdescriptionを読むことができるので、そこから新しい情報を入手することができます。文章そのものも有益な情報ですが、JIRAやbacklogなどの別サイトで管理されている依頼情報を追うこともできたりするので、当時の背景理解を助けてくれます。 またhistoryの機能を使うとそのファイルが過去に行われてきた変更を確認することができます。commitによってはrevertしているなどで直前のコミットだけでは変更の真意まで読み解けないときがあるので、そのようなときにhistoryを使って過去のコミットを順を追っていくことで得られる知見もあります。 この過去の内容を追うときに念頭においたほうがいいのは「該当箇所にどんな変更があり、何故その変更が行われたか」です。例えば最初に挙げたリストアイテムの表示順を並べ替えたいという話であれば、何故最初に昇順で実装されていたのか、その後変更がされた形跡があるかというのは一度調べておくといいかと思います。これを調べることにより現在の担当者が知らなかった背景が見つかったりする場合もありますし、逆に当時何も考えて作られていないことがわかれば修正してしまってもなんの問題もないという裏付け材料になるので、調べておくことのメリットは大きいです。 3.前後比較ができる状態で改修をかける 変更箇所がわかり、修正する内容に関しても憂いがないことがわかったらあとは直すだけです。ただ直す際に気をつけなければいけないのは「関係ないところを変更してしまわない」ということです。 例えば今回の改修依頼の例でいくと、並び順は降順になったが、リスト表示するアイテムがおかしくなってしまう、などの事象が起きてはいけないので、その点に関して修正前後で問題がないかというところを確認する作業が必要です。 修正する箇所にテストコードがあり、修正した箇所以外に変更が加わっていないかということが検証できるのが一番良いのですが、歴史の長いコードベースの場合はちゃんとテストコードが用意されていないこともあります。そのため、予め「修正前後を確認できる方法」を用意しておいたほうがいいと思います。 修正前後を確認できる方法というのは、テストコードを書き足すということでも実現できます。もともの改修前の箇所に関してテストコードを書き足し、その後改修とワンセットでテストコードも書き換えるというやりかたです。こうすることにより元の仕様の理解も深まり、また未来コミットログを見た人がどういう振る舞い変化を期待して直したかというのもわかりやすくなります。 ただ、テストコードが継ぎ足すのが構造上難しい箇所もあると思います。その場合は一般的にマニュアルテストと呼ばれているようなテストケースを文章で書き起こし、それを実施するというのも方法の一つだと思います。その場合はPullRequestのdescriptionに行ったテストケースに関する情報があれば、未来の人に何をしたかを残すこともできます。 ここで大事なのは「修正したい場所と修正する場所に近いところがちゃんと壊れていないかを確認する工程を踏む」ということを意識づけてやるところなので、テストコードでもマニュアルテストでも確認作業を踏む、踏んだ足跡を残せるとよいかと思います。 過去を探ることで、足場を固めて改修する 歴史のあるプロダクトコードはビジネスの成長に合わせて無理をしていることもあります。そのようなプロダクトコードに手を入れるときに当時の背景を理解するということは改修の手助けになることがあります。過去を知るチームメンバーに色々と話を聞けるとよいのですが、もしそのようなメンバーがいない場合、GitHubでソースコードを使うことで断片的にでも情報を探ることができます。 また断片的に得られた情報から改修を行う際は、テストコードなどで足場を固めて改修をしていくとバグを生み出す確率を減らすことができます。下記のPullRequestでは今回のアプローチで紹介していたような探りを入れ、そこに対し既存実装にあわせたテストコード(RSpec)を追加、そのRSpecを元に既存実装から改修実装に切り替え、最終的に影響が他に伝搬してないかを確かめつつ改修しています。かなり複雑な箇所の改修でしたが、大きな不具合を出すことなく改修ができました。 これらのアプローチを無意識にやっている方が多い部分もあるとは思いますが、もしこの記事で少しでも学びや再発見があれば幸いです。 こちらの文章は直近 入社エントリ を書いた高田の提供でお送りしました、明日のアドベントカレンダーもお楽しみに!
この記事は 株式会社エス・エム・エス Advent Calendar 2023 の6日目の記事です。 エス・エム・エス BPR推進部 カスタマーデータチームの橘と申します。 私は「ナース人材バンク」等のキャリア事業を中心に、社内のデータ活用の推進、データ基盤の開発運用を担当する、データエンジニアの役割を担っています。 今回は私の組織におけるデータエンジニアの役割を簡単にご紹介し、データ活用の推進のために進めている活動の1例として、データカタログの整備についてご紹介します! データエンジニアとは そもそもデータエンジニアとはどういう役割でしょうか? 一言でいうと、社内のデータ活用に携わるITエンジニアです。ビジネスの意思決定を決めるデータ活用の基盤として、データ分析基盤があります。そのデータ分析基盤はデータの収集、蓄積、加工、可視化、出力などの機能を持っています。また、データ分析基盤を活用するためのデータの整理、カタログ化、セキュリティの担保等も必要になってきます。これらの開発・運用に携わるのが私たちのチームにおけるデータエンジニアとなります。 私たちキャリア横断開発グループではGoogle Cloud を中心にデータ分析基盤を構築しております。以下の記事でもご紹介しておりますので、合わせてご覧ください。 キャリア事業におけるデータ活用 エス・エム・エスのキャリア事業のみに限定しても、「ナース人材バンク」や「カイゴジョブ」等の複数サービスを展開しており、非常にたくさんの種類のデータが、あちこちに存在します。 これらのデータを1つのデータストレージ、具体的にはGoogle Cloud のBigQuery に連携して、データを活用できるようにしています。 私たちは貯めたデータをもとに、マーケターからヒアリングした課題の解決に向けて、データの出力や可視化、分析を進めています。 とはいえ、単に条件を指定したデータの出力や単純な可視化等は、データエンジニアチームを介すことで実装完了までのリードタイムが生じたり、依頼内容と開発者の認識の祖語が発生したりする問題もあります。そのため、マーケター自らが収集したデータを探して、活用していくという、“データの民主化”に課題がありました。 キャリア事業というドメインのデータ分析基盤は、データメッシュという考え方における、“セルフサービス型データプラットフォーム”を目指してます。データエンジニアに依存せず、マーケター達が自律的にデータを取り扱えるようなデータ基盤を構築し、データカタログ、データマート、BIツール等の各ツールを活用して、データの分析を行う世界を目指しています。 今回はそのうちのデータカタログというプロダクトに焦点を当ててご紹介します。 データカタログの整備 前置きが長くなりましたが、データカタログについての話に入ります。 そもそもデータカタログとは何でしょうか?その名の通り、“データのカタログ”になります。データのメタデータ、ビジネス要件などをドキュメント化して、検索ができるカタログのことを指します。 私たちのデータ分析基盤では、目的に応じた大量のテーブルが存在し、各テーブルには大量の項目が存在しています。 セルフサービス型データプラットフォームは、こういった大量のデータを分析するにあたって、データを発見しやすく、アクセスしやすい環境でなくてはなりません。そのため、データ分析基盤の各データのメタデータをもとに、データカタログを作成する必要があります。 私達のデータ分析基盤(今回はGoogle Cloud のデータウェアハウス、BigQuery 内のデータに限定しています)におけるデータカタログの要件は以下としています。 分析を始めたい人がデータカタログにすぐにアクセスできる 各データセット、テーブル、項目の定義やビジネス要件が整理されている データカタログを検索できる メタデータの収集は自動化できる ビジネス要件を継続してメンテナンスできる これらの仕組みが一か所に集約され、データカタログを起点にデータへのアクセスが容易となっている 単純にメタデータの収集であれば、Google Cloud にも、 Data Catalog という製品があります。 しかし私たちは上記の要件を満たすために、Googleスプレッドシートで簡易的なものを作成して運用しています。 今回はそのGoogleスプレッドシートで作成したデータカタログついてご紹介します。 実際のデータカタログ こちらが実際のGoogleスプレッドシート上のデータカタログになります。 実際にデータ一覧をお見せすることはできないので、Cloud Loggingからエクスポートしている、App Engineのnginxのリクエストをテストデータとして表示しています。(テストデータのため、論理名や説明は省略してます) シートの構造は以下の通りです。 README データカタログの使い方を記載したシートです。 データセット一覧 分析用プロジェクト内の、BigQuery データセットの一覧や説明を記載したシートです。 テーブル一覧 分析用プロジェクト内の、BigQuery テーブル(Viewやテーブル関数なども含む)の一覧や説明を記載したシートです。 利用者は主にこのシートを参照します。テーブル一覧のみでは分析用途として事足りないので、Google Apps Scriptを用いて、上記キャプチャのように、選択中のセルのテーブルで、項目一覧シートの情報を検索し、結果をモーダルで表示する機能を用意しています。テーブルの情報、各項目の情報を一覧で見れたり、SQLやテーブルスキーマファイルの自動生成などといった機能も用意しています。 項目一覧 分析用プロジェクト内の、BigQuery テーブル全ての項目の一覧や説明を記載したシートです。 データカタログの更新方法 データカタログの更新方法は、 BigQuery のメタデータ取得による自動更新 データエンジニアによるビジネス要件の手動入力 の2パターンがあります。 これらのアーキテクチャを簡単にまとめますと以下のようになります。 BigQuery のメタデータ取得による自動更新 項目名、型、更新日時や件数などの情報はBigQuery のメタデータにあるため、SQLで取得することができます。 以下のようなSQLを実行し、自分たちのデータカタログの各シートに出力できる形に整形して、日次のバッチ処理でスプレッドシートに自動出力される仕組みです。 1.BigQuery データセット一覧を取得 SELECT * FROM INFORMATION_SCHEMA.SCHEMATA 2.取得したデータセット毎に、BigQuery テーブル一覧とメタデータを取得(それぞれのクエリで取得できる情報は異なります) SELECT * FROM [データセットID].INFORMATION_SCHEMA.TABLES SELECT * FROM [データセットID].__TABLES__ 3.取得したデータセット毎に、BigQuery の全テーブルの項目一覧と、メタデータを取得(それぞれのクエリで取得できる情報は異なります) SELECT * FROM [データセットID].INFORMATION_SCHEMA.COLUMNS SELECT * FROM [データセットID].INFORMATION_SCHEMA.COLUMN_FIELD_PATHS データエンジニアによるビジネス要件の手動入力 テーブルや各項目の説明(集計項目であれば集計ロジックなど)、更新頻度など、メタデータで取得できない情報については、テーブルを実装したデータエンジニアが手動で入力する必要があります。また、不足している情報があればスプレッドシートの編集権限を持つメンバーが更新できるので、入力インターフェースとして準備が簡単だったGoogleスプレッドシートを採用しています。 とはいえ、メタデータ取得は自動的にされているものの、ビジネス要件が入力されておらず、カタログとして情報が不足してしまうことも多々あります。そのため、定期的にデータカタログ上で情報が不足している箇所を検知して、Slackに通知し、データエンジニアに入力を促すなどしています。データを収集してテーブルとして公開するまでが仕事ではなく、実際に分析するユーザーがデータにアクセスしやすい環境づくりを心掛けています。 まとめ 以上、私たちのチームにおけるデータカタログについてご紹介しました。 実際に分析をするマーケターや、開発担当のメンバーからも、 「BigQueryのデータを見るときはまずこのデータカタログから見てます!」 「テーブルをリリースすると項目定義が自動で連携されるから便利!」 といった声が上がっています。 一方で、利用範囲が広がるにつれ、データのオーナー情報、集計ロジックを直接見れるGitHubのURLも載せてほしいなど、データカタログとして管理していきたいビジネス要件が増えてきて対応しきれない部分もあるのが課題としてあります。 社内のデータの活用を推進する立場として、こういったドキュメントの整備も怠ることなく進めて行きたいと考えております。 エス・エム・エスは新しいメンバーを募集しています。 特に私たちのチームでは、データ分析・データ活用の推進に関わるデータエンジニアを募集しています。 今回紹介したデータカタログは、データエンジニアの仕事のほんの一例のご紹介にすぎません。 弊社の事業に携わってみたい方、興味のある方は、ぜひこちらのページものぞいてみてください。 エス・エム・エス - エンジニア採用情報 データエンジニア(キャリア事業) / 株式会社エス・エム・エス
こんにちは。介護事業者向け経営支援サービス「カイポケ」でエンジニアリングマネージャーを担当している橋口( @gusagi )です。 今回は、少し前にカイポケの訪問看護チームで行った「システム障害対応訓練」について紹介します。 なお、システム障害対応訓練に関しては、今回の記事だけでなく裏側を中心に紹介する記事を掲載予定です。 今回の記事ではやったことを中心に紹介させてもらい、別の記事では準備期間・当日・ふりかえりの裏側でどんな動き・工夫があったのかを紹介する予定です。そちらもなるべく早く公開するつもりですので、ご期待いただけますと幸いです。 きっかけ 訪問看護チームでは、テックリードを中心とした体制で開発・運用を行っています。 この体制は現時点で機能していますが、ある時のふりかえりで「テックリードが不在の時に何らかの問題が起こったとしてもうまく連携して対応することができるか?」という指摘が上がりました。 テックリードが不在となった場合に心配なことは何かを具体的に挙げていったところ、票が一番多く集まったのがシステム障害が発生して対応を行う時でした。訪問看護チームではシステム障害対応のガイドラインも策定していたのですが、その中で対応時の指揮官(インシデントコマンダー *1 )を毎回担っているのがテックリードであったため、不在の時にチームが同じように動けるのかが不安要素として挙がったのです。 特に、以下の課題に関しては早い段階で手を打つ必要がありそうでした。 テックリード以外にインシデントコマンダーを担える人がいるかが分からない チームで行う対応がインシデントコマンダーの判断・指示に依存している QAチームとの連携がスムーズにできていない そこで「テックリードが不在の時のシステム障害対応」という課題に対する対応案として、表題にもあるシステム障害対応訓練を実施するという取り組みがスタートすることとなりました。 このシステム障害対応訓練において期待する効果は以下です。 短期・直接的な成果: 障害対応の解像度を上げる インシデントコマンダーを担える人間を増やす 中長期的な期待: 各人がシステム障害対応に主体的に関われるようなチームへの成長 やることが決まるまで システム障害対応訓練を行うということを決めて、そこからどんな内容にするかをチーム内で考えていく流れとなりました。 企画に名乗りを上げてくれた若手エンジニア2名を含めて打ち合わせをして、大枠として以下のことが決まりました。 お客さまからのお問い合わせをトリガーとして、問題の調査や解決を進める流れとする 実際にシステム障害を起こしたりはせず、チーム内でシミュレーションを行う形とする ただし、ログや各種メトリクスの調査は、ある程度まで実際にやってみる そのシーンで実行できるアクションは選択肢を提示しつつも、それ以外にも参加者が考えて何をするか決めて良い インシデント時のガイドラインに則って専用のSlackチャンネル作成なども行う チーム外に不要な混乱が起きないよう、事前の周知を徹底する他、当日のSlackチャンネル名などにもシステム障害対応訓練であることを明記する 上記を満たす方法を検討した結果、テーブルトークRPG(TRPG) *2 の形式を取るのが良さそうだという話になりました。 TRPGとは、ゲームマスター(GM)と呼ばれる進行役と、プレイヤー(PL)と呼ばれる参加者で協力して会話をベースとして物語を進行させていく遊びです。 実際には起きていないシステム障害に対するシミュレーションで、選択肢にない参加者の行動も柔軟に拾っていくことを考えた結果として、TRPGが良さそうだとなりました。 TRPGの形式が良いと判断した主な理由は以下です。 リモートワーク中心の状況で実際にシステム障害に対応する場合でも、複数人で会話をしながら対応を進めることが予想されるため、近しい状態で訓練することができる シミュレーションによる訓練となるため、進行役としてGMが存在する方が柔軟に対応できる 訓練だからこそ、少しは遊び心を入れて楽しみながら取り組めるようにしたい また、企画に名乗りを上げてくれたエンジニアがどちらもTRPGを知っていたこともスムーズに方針が決まった一因になったと思います。 当日までの準備について まずは発生したとするシステム障害の内容と大枠のシナリオを決めることとしました。 訪問看護チームは、介護事業者向け経営支援プラットフォーム「 カイポケ 」のうち訪問看護の領域を開発・運用しています。従って、カイポケのサービスにおいて特にお客さまへの影響が大きく緊急性の高いシステム障害が発生したと想定する方が望ましいと考えました。 そこで、発生したシステム障害の内容を決めた上で「一部のお客さまから『診療報酬明細書(レセプト)が出力できない』というお問い合わせが来た」という状況からシナリオが始まるようにしました。 なお、シナリオにはフラグによってエンディングが分岐する仕掛けを入れておき、GoodエンドからBadエンドまで何種類かのエンディングを用意しました。 また、TRPGを知らない・詳しくない参加者がいることが予想されたため、企画に参加しているエンジニアのうち片方の人にGM役を、もう片方の人には参加者として他の人のフォローに入ってもらうことをお願いすると共に、参加者の人にはシナリオを伏せた状態で準備を進めるようにしました。 合わせて「ハンドアウト」と呼ぶ事前資料を用意して、目的を意識して訓練に臨んでもらえるようにしました。 ハンドアウトではシステム障害対応訓練の目的や進め方の説明と合わせて、TRPGに不慣れな人向けのロールプレイの説明や会話をしながら進めることの必要性なども記載しました。また、トレーラーと呼ぶようなシナリオの予告ストーリーも載せておき、訓練ではあるもののゲームとして楽しめるような遊び心も盛り込ませてもらいました。 当日の実施レポート 当日は、まずは訓練会場として用意したZoomに集合してGMから改めて当日の流れを説明しました。 その後、実際のお問い合わせを模した形で内容をJIRAのチケットとして起票し、Slackで運用担当者への確認依頼をGMから伝えて、訓練開始となりました。 初めてのシステム障害対応訓練、かつTRPG風というアレンジが入っていたことで、訓練の途中にルールへの質問が入ったり、対応に関する相談が想定以上に盛り上がり時間が押してしまうというハプニングもありましたが、PdM・エンジニア・運用・QAといった日頃の役割を超えて意見の交換が行われており、概ね成功したと言えるのではないかと思います。 なお、最後は駆け足気味になっていましたが押さえるべき観点をしっかり押さえた対応を行えており、シナリオの結果として一番良いエンディングに到達することができていました。 訓練の最中にも「このペースで問い合わせが来ているの、相当ヤバい状況だね」「どう動いたら早く・確実にこの事象を解消できそう?」という会話が出ており、訓練を通して参加者がしっかりとシステム障害対応に取り組むことが出来ていたのではないかと思います。 振り返りについて 訓練結果を有効に活用するため、訓練直後に簡単なアンケートに協力してもらい、その内容を事前に共有した上でYWT形式でふりかえりを行いました。 アンケートの回答では、訓練を実施したことそのものに対する好意的な意見、訓練を通して得た気付き、訓練の進め方に関する改善の提案、今後の希望など多くの回答がありました。 また、アンケート結果を踏まえてのふりかえりでも、書き出しの時間をそこまで取ることが出来なかったにも関わらず、想像を大きく超える数の付箋が書き出されました。内容も、やったこと(Y)よりも、そこからわかったこと(W)や次に行うこと(T)の数が圧倒的に多く、この点からも、参加者にも楽しんでもらうと共に、システム障害対応訓練で気付きを得てもらうことが出来たのではないかと思います。 公開できない情報もあるためお見せすることができないのが残念なくらいでした。 あとがき ここまでで、訪問看護チームで行ったシステム障害対応訓練でやったことの紹介は終わりとなります。 ですが、冒頭にも書いたように、準備期間・当日・ふりかえりの裏側でどんな動き・工夫があったのかを紹介する別の記事も準備していますので、そちらもなるべく早く公開するつもりですので、ご期待いただけますと幸いです。 *1 : インシデントコマンダーについては Asanaの記事 や Atlassianの記事 が参考になります *2 : TRPGに興味のある人は 富士見書房さまによる紹介ページ や Wikipediaの記事 もご覧ください
この記事は、「株式会社エス・エム・エス Advent Calendar 2023」3日目の記事です。 qiita.com 介護事業者向け経営支援サービス「カイポケ」の開発をしている @koma_koma_d です。 私が所属しているチームは、介護事業所の業務のなかの一部の領域を扱う箇所の開発を担当しています。最近、このチームの置かれている状況に変化があり、それに伴って(他にも様々な変化が必要になっているのですが)ドキュメンテーションについての方針転換がありました。この方針転換は、私個人にとってもこれまでの働き方を一部改めるきっかけになるものでしたので、今回の記事では、その方針転換について紹介したいと思います。 これまでのチームの状況 私たちのチームが担当している領域のシステムは、大雑把にいうと、ユーザーが触るアプリケーション(サーバーサイドレンダリングをベースとする典型的なWebアプリケーション)と、その更に裏側で動作するバックエンドのアプリケーション(WEB API+非同期処理を担うワーカー)の2つの部分に分かれています *1 。 私たちのチームが担当する業務は、カイポケの他のコンポーネントで作られたデータを入力とするのですが、基本的にはこれらの2つのコンポーネントで完結します。したがって、カイポケの他のチームのメンバーは私たちのチームの担当する業務ドメインについての知識をほとんど持つ必要がなく、ユーザーから見える仕様もこれら2つのコンポーネント間のAPIの仕様もほぼ自由に変更することができました(もちろん仕様を変える際は対ユーザーのコミュニケーションは不可欠ですが)。この自由度を活かして、新しい機能を追加したり、そのために内部API仕様を変更したりを活発に行なってきました。 カイポケリニューアルプロジェクトの進行に伴う状況の変化 しかし、ここ数ヶ月の間で、状況が変わってきました(予定通りではあるのですが)。それは以前から動いているカイポケのリニューアルプロジェクトの進行に伴うものです。 careers.bm-sms.co.jp このリニューアルプロジェクトでは、既存システムとは別の新システムを開発しており、私たちのチームが担当する業務ドメインについても、別のチームが開発をしています。しかし、先述の2つのコンポーネントのうち、 後者のバックエンドのアプリケーションについては、既存システムと新システムとが共用します 。リニューアルプロジェクト側では、ユーザーが触るWebアプリケーション *2 だけを新規開発し、そのアプリケーションから私たちのチームのシステムのWeb APIを利用するわけです。 この状況の変化により、 これまで私たちのチームだけが知っていれば良かった知識の一部を、他チーム(リニューアル側の開発チーム)にも知ってもらう必要が出てきました。その中には、業務ドメインに関する知識と、内部APIの仕様の知識の両方が含まれます 。このことが、ドキュメンテーションの方針に変化を強いることになります。 これまでのドキュメンテーションの考え方 基本はチーム内向けのドキュメント 私のチームでは、ドキュメンテーションツールとして esa を主に利用しています。esaはMarkdownで書くことのできるツールで、個々の記事がバージョン管理されるほか、 フロー情報とストック情報を分ける機能 などがあります。esa以外には、ソースコードに近い情報はGitHubリポジトリ上のコメントやREADMEなどで記述しているほか、内部APIの仕様についてはOpenAPI Specification(コードから自動生成しています)から作成したドキュメント *3 があります。 このうち、内部APIの仕様についてはチーム外の人が見ることを意識していましたが、esaに書かれるドキュメントについては基本的にチーム内の人(未来の自分たちを含む)が読むことを想定して書いてきました。もちろん仕事をしている中で別のチーム(開発チーム以外を含む)に向けて情報共有をすることはありましたが、そのときに適切な情報が伝わればよいケースがほとんどで、メンテナンスされるようなドキュメントとして書いていなかったり、必要が生じたタイミングで書くという形で書いていたため網羅性の乏しいものになっていました。 読み手としてチーム内の人を想定する場合の考え方 読み手としてチーム内の人を想定する場合、ドキュメントを書く際に意識することは少なくて済みます。まず、チーム内の人であれば、コードを読むことで得られる情報など、既に関連する部分の知識を持っていることを前提としてドキュメントを書くことができます。コードを読んだ方が正確に・詳細に把握できる事項についてはドキュメントを書かないでおく選択を取ることもできます。 また、(新規参画したメンバーは別ですが)過去の経緯がある程度頭に入っていることも期待できるので、ある時点で書かれたフロー情報的なドキュメントを見たときにそれが書かれた文脈を想像してもらいやすいですし、必要に応じてgitの履歴やGitHubのPull Requestの履歴とも紐付けて読んでもらいやすくもあります。 このような背景から、ドキュメンテーションに対する考え方は、(チームとして明確に意識していたわけではありませんが) 「多少読みづらくてもよいので、とにかくたくさん情報を残しておく」 という方に寄っていたように思います。また、私個人の経験としても、チーム開発におけるドキュメンテーションの最初の壁は「共有されてもいい情報がドキュメンテーションツール上に書かれない」ことだと感じていたので、「書くハードルを下げる」「些細なことでもとにかく書いておく」ということを重んじてきました。個人で何か作業をしたときや調査をしたときも気軽にドキュメンテーションツールに書いておくことで、他のメンバーや将来の自分の参考になる情報をなるべく増やすという考え方ですね。現在のチームの前に所属していたチームでは、この考え方に基づいたプラクティスが上手くワークしていたこともありました。以下の記事で紹介している「転ばぬ先の杖」がそれです。 tech.bm-sms.co.jp 「書き手の書きやすさ重視」のアプローチ このアプローチは、「書き手の書きやすさ重視」のアプローチということもできます。もちろんドキュメンテーションはそもそも読み手のためのものなので、書き手の書きやすさを重視することも究極的には読み手のためではあるのですが、読み手にとっての利便性のうち、情報量を増やすことにフォーカスしており、「簡単に情報にアクセスできる」「わかりやすく情報がまとまっている」という部分は犠牲にしている側面があります。読み手は検索やリンク(esaにはバックリンクを表示する機能もあります)の機能を駆使してドキュメントを「漁る」ことで、必要な情報を得ることになります。 生じてきた課題 しかし、先述の状況の変化により、課題が出てきました。 チーム外向けのドキュメントだけでは足りない まず第一に、従来からチーム外向けを意図して書いていたドキュメントでは、全く情報が足りないということを本格的にリニューアル側の開発が始まってから痛感しました。これは見立てが甘かったと言ってしまえばそれに尽きるのですが、どう想定と違ったかを少し紹介したいと思います。事前のイメージは「Web APIのクライアントとなるリニューアル側の開発チームは、OpenAPI Specificationベースのドキュメントと、それを補足するようなドキュメントがあれば開発できるだろう」というものでした。しかし実際に開発が始まってみると、私が想定した以上に細かく、実装に近い仕様や業務ドメインに関する知識を質問されることが多かったのです。 内部APIのモジュールとしての性格 こうなってしまった理由を考えてみますと、私たちの開発している内部APIのモジュールとしての性質に思い至ります。私たちのチームで開発していた内部Web APIは、情報の隠蔽を志向しているというよりは、クライアントであるユーザー向けのWebアプリケーションで求められるユースケースを最大限実現できるようにすることの方を優先して作られていました。 もちろん、内部APIとして切り出す意味がある程度の複雑な機能をAPIの裏側に持っている(データベースやオブジェクトストレージ、KVS、非同期処理を実現するためのメッセージキューなども独自で持っています)のですが、非同期処理の過程のステータスの遷移などの情報はあまり隠蔽せず、APIで露出させることでクライアント側で画面に表示したり制御に利用したりできるようにしています。 『A Philosophy of Software Design』 における表現を使えば、「機能は多いが、インタフェースも多い(複雑な)」、DeepともShallowともいえないモジュールだということです。『A Philosophy of Software Design』については、以前個人ブログの方に書いた記事や、NTTコミュニケーションズ社のブログ記事も参考にしてください。 ky-yk-d.hatenablog.com engineers.ntt.com チーム外の人も、API仕様以上の知識に関心がある このようなモジュールとしての性質から、クライアントの開発者はこの内部APIを使って開発をする際に、かなり多くの知識にそもそもOpenAPI Specificationベースでドキュメント化されているAPI仕様の段階で触れることになります。その上で、そこに露出している知識を最大限に理解した上で実装をしようとすると、OpenAPI Specificationでは書ききれていない情報、ほぼ実装の詳細に関わるような内容や、背後にある詳細な業務知識までも知りたくなってしまうようでした(そもそも私たちのチームではそこも把握した上でユーザーの触るWebアプリケーションを実装しているわけです)。 チーム内向けとして書かれていたドキュメントをチーム外の人が読む チーム外に向けて書いていたドキュメントだけでは足りないとなると、他チームのメンバーとしては個別に私たちに質問するか、私たちがチーム内向けに書いたドキュメントを読むかして情報を得ようとします。私たちのチームとしてもリニューアルプロジェクト側の開発が滞りなく進むように支援することの優先順位は高く設定しているので、もちろん質問してもらっても大いに構わないのですが、すぐに応答できないこともありますし、双方にとって効率的でないこともしばしばです。したがって、やはりドキュメントで完結する部分を増やすことは重要になります。 チーム外の人にはチーム内向けのドキュメントは理解しづらい それでは、チーム内向けとして書かれていたドキュメントをチーム外の人が読もうとすると、どんな困りごとが出てくるのでしょうか。第一に、 ドキュメントを読むだけでは理解できない ということがあります。これは先述したような、チーム内であれば期待できる前提知識や、コードを読むことによって得ることのできる情報を、チーム外の人は持っていないからです。もちろん他チームであっても開発者ではあるので「コードを読んでください」と言えば読んでもらうことは可能なのですが、私たちのチームとリニューアルプロジェクト側のチームとでは技術スタックがやや異なっていることもあり、あまりここに頼りたくはありません。 チーム外の人にはドキュメントに書かれている情報の鮮度を判断しづらい また、チーム内向けのドキュメントではフロー情報としてある時点での情報を書いたものをそのまま残してあるものも多いのですが、チーム外の人は私たちのチームやそのシステムの過去の経緯までは知らないことが多いので、あるドキュメントを見たときにそれがup-to-dateなものかの判断が付きづらく、誤った(out-of-dateな)認識を持たせてしまう危険性があります。 チーム外の人は必要なドキュメントに辿り着きづらい 更に、そもそも 必要なドキュメントに辿り着けない という問題もあります。先述の通り、「書き手の書きやすさ重視」のアプローチでは、読み手の利便性のうち、「欲しい情報への辿り着きやすさ」は犠牲になっており、検索やリンクを駆使してもらう必要があります。 チーム内であれば自分たちがどういう言葉を使っているかが分かりますし、何かを調べようと思ったときにどのようなキーワードで検索したら見つかりそうかの候補もすぐに思いつきます。「あの記事からリンクされていた気がする」というのも覚えているかもしれません。しかし、これはチーム外の人には期待すべくもないことです。もちろん最小限の語彙はOpenAPI SpecificationベースのAPi仕様という形で見えるようになっており、そこで接した用語について関心を持って調べ始めるわけなので、全く白地からというわけではありませんが、やはり「欲しい情報へ辿り着く能力」には差が出てしまいます。 ※ちなみに、将来的には現状の全文検索やリンクに加えてAIによる要約やチャット形式での検索が発展して、現在よりは必要な情報に辿り着きやすくなるのではないかと妄想しますが、その場合でもデータソースを書き捨ての文章のみで構成するのはなかなか厳しい気がします。 これからのドキュメンテーションの考え方 以上のような課題から、私たちのチームではドキュメンテーションの考え方を改めることにしました。具体的には以下のような方針を定めました。 チーム内向けとチーム外向けを分けない これまで、ドキュメントはデフォルトがチーム内向けで、例外的にチーム外向けを書くという形になっていましたが、この分け方自体をやめることにしました。チーム外の人でも読めるものに最初からしましょう、ということです。実際には、チーム内のメンバーしか読まないドキュメント(たとえば、運用上の手順書など)も出てくると思いますが、その場合でも暗黙の前提知識を要求するような形では書かないということを原則としようとしています。 ドキュメントを小分けにせず、なるべく大きなまとまりにする これまでは「場所に悩んだりして書かないよりは、とにかく書いておくことを優先する」という方針で、仕事をしている過程で小さなドキュメントをたくさん書いてきました。しかし、このアプローチでは、一度書かれたあとに更新されないドキュメントが増えがちです。更新されないドキュメントが存在することは、読み手、特に過去の経緯まで把握していないチーム外の読み手にとっては大きなノイズとなります。 新しい方針では、なるべく大きなまとまりの文書をメンテナンス対象とし、加筆・修正していくことにしています。あるテーマについてはこの文書だけが信頼できる唯一の情報源(Single Source of Truth)であるという状態を作ることです。 こうしておくことで、まず第一に、欲しい情報に辿り着きやすくなります。また、これはチーム内で話をしている中でメンバーから言われて「なるほど!」となった点なのですが、 読まれる頻度の高いドキュメントは更新されるチャンスも多くなる ということもあります。ドキュメントが更新されるタイミングとしては、何か変更が入った際に「あのドキュメントも更新しなきゃなー」と更新されるのがベストですが、更新を忘れてしまうことは実際には多いです。しかし、日頃から繰り返し開くことの多いドキュメントであれば、「あ、ここ情報が古いじゃん」と気づく機会が増えます。もちろん、ドキュメントが大きくなればその中の一部の記述だけを目当てにしてそれを開くことも増えると思いますが、それでもその部分以外の記述も併せて目に触れることはある程度あり、更新のきっかけになると思います。 フロー情報を書いたものはドキュメントとして扱わない 上の内容とも関連しますが、フロー情報として書いたものをドキュメントとして扱わないようにしようと考えています。 これまではフロー情報を書いたものもドキュメントの一部として扱い、「読まれる」ことを期待していました。しかし、この考え方はともすると「本来ストック情報として書かれるべきものがフロー情報として書かれっぱなしになってしまう」という事態を招きやすいと感じます。「フロー情報を残しただけでドキュメントを書いたつもりになる」のをやめなければなりません。そのためには 「フロー情報を書いたものはドキュメントではない」 というくらいの意識が必要だと思います。有益な情報として残すべきだと考えたなら、その情報が書かれるべきドキュメントを探して、メンテナンスするものとして記述します(もちろん、もはや必要でないと判断した場合には「メンテナンス」の一部として削除することもあるでしょう)。 インデックスとなる記事からリンクだけで必要な情報に辿り着けるようにする。 これはドキュメントへの辿り着きやすさの改善のための方針です。これまではドキュメントを新しく作成するとき、「どのようなタイトルにするか・どのような文言を入れておくか」という検索でのアクセスのしやすさの観点と、「どのディレクトリ *4 に入れておこうか」という階層構造を使ったアクセスのしやすさの観点を意識することはありましたが、他の記事との関係でいうと、関連する記事同士をリンクで結びつけることによるネットワーク構造の作成くらいまでしか意識してきませんでした。 今回、新しく各グループ(ex. 仕様に関するドキュメント群)ごとにインデックス(ルート)となる記事を設定し、そこから明示的なリンクを辿ることで必要な情報を見つけられるようにしようということになりました。先述の通り、検索頼みにするのはチーム外の人にとっては利便性が特に低いですし、「検索や階層構造で見つけてくれる」というのに甘えると自分たちがその文書に辿り着くのも意識的にアクセスしたときに限られやすくなるため、書きっぱなしで更新されないドキュメントになりがちです。特定の記事からリンクだけで辿り着けるようにしておくことで、チーム外の人からアクセスしやすくなると同時に、更新されやすいようになることを狙っています。 終わりに 以上、私たちのチームにおけるドキュメンテーションの方針の転換について、その背景と併せてご紹介してきました。この方針で動き始めたのは最近なので、実際にどうなったか(うまくいっているのか・いないのか)はまだご紹介できる段階にありません。ドキュメントをメンテナンスしていくのはそもそも簡単ではなく、だからこそ従来の方針のような「書き手の書きやすさ」を重視するという方針にも意味がある(最初から読み手の利便性を100%満たすドキュメントを書けるのであれば苦労はしない)わけですから、今回立てた方針を適切に実行できるかどうかも不透明です。 しかし、社内向けとはいえチーム外にAPIを提供するチームとしては、ドキュメントをプロダクトの一部として捉え、コードと同じくらい大切にする必要があります。ソフトウェア自体に不具合がなくても、ドキュメントが不足していたり誤解を招くものであったりした場合、使い方を間違えることでシステム全体としては正しく動作しなくなってしまうこともあるわけです。「ドキュメントをプロダクトとして扱う」という考え方は 『エンジニアのためのドキュメントライティング』 でも語られています。 pub.jmam.co.jp また、私個人としては、これまで他の開発者にクライアントとして使ってもらうソフトウェアをメンテナンスする経験がほとんどなかったので、これまでに形成してきた自分自身のドキュメンテーションに対する考え方をアンラーンする必要を感じています。今回のチームとしての方針の転換をいいきっかけとして、プロダクトの一部としてのドキュメントに真剣に向き合っていきたいと考えています。 「株式会社エス・エム・エス Advent Calendar 2023」 、明日4日目は、 @soranakk の記事を予定しています! *1 : なぜこのような構成になっているかは割愛します。 *2 : 厳密には、リニューアルプロジェクトではフロントエンドとバックエンドがGraphQLのAPIで通信するアーキテクチャとなっているため「ユーザーが触るWebアプリケーション」はフロントエンドだけなのですが、ここでは簡略化のためバックエンドの部分も含めて「ユーザーが触るWebアプリケーション」と記載しています。 *3 : 当初は Swagger UI 、現在は Redoc を利用しています。 *4 : esaでは、ディレクトリ構造を作って記事を整理することができます。個々のディレクトリに相当する部分のことを「カテゴリ」と呼びます。
株式会社エス・エム・エス Advent Calendar 2023 エス・エム・エスで開発者をしている @koma_koma_d です。 今年もアドベントカレンダーの季節ですね、ということで、今年はエス・エム・エスでもアドベントカレンダーをやります! qiita.com 記事は、このブログ以外に、各メンバーの個人ブログ、Qiita、Zennなどの様々な媒体に投稿される予定です。公開された記事はXのアカウント @BM_SMS_tech で随時シェア予定ですので、ぜひアカウントをフォローしていただけると幸いです! 誰が何を書くのか 参加するメンバーは、 開発者 SRE エンジニアリングマネージャー QAエンジニア プロダクトマネージャー など、プロダクト開発に関わる多様な職種が集まっています。 内容についても、業務に関わることに限定せず、各メンバーの好きなテーマで書いてもらいます。エス・エム・エスのメンバーがどういう技術に興味を持っているのか、日頃どのようなことを考えながら仕事をしているのか、などを知っていただける機会になると嬉しいです! 初日である明日の執筆者は、フロントエンドエンジニアの setoh です!お楽しみに! setoh が過去に執筆・登場した記事 tech.bm-sms.co.jp tech.bm-sms.co.jp
はじめに エス・エム・エスのヘルスケア事業部所属のエンジニアの今村と申します。この会社に転職してきて気がつけば10年以上となります。 その間に、新規登録の処理を何度も何度も設計してきました。設計とは言うものの、入力用の画面を用意しPOSTしたらその値をサーバーサイドで検証してDBに登録するという大枠の流れは同じです。しかし最近になって、それで本当に良いのか? と再考する機会がありました。 今回は、その時に再考した内容を整理したいと思います。 再考することになった経緯 仕事では、webサービスの改善・運用の他、業務で使うkintoneのカスタマイズも担当しています。 ある日、kintoneアプリのカスタマイズ要望がありました。具体的には、画面内の項目Aに特定の値を入力して保存した場合、ダイアログを表示して「次に担当者がとるべきアクションを明示したい」というものです。 kintoneには固有のイベントハンドラがあり、データの保存が成功したことをトリガーにして処理を実行することができます。今回はこれを使えば簡単に実装できると思っていました。 前提として、今回の値は新規登録と更新のどちらのケースでも入力されうるものです。そして、kintoneの画面は、新規登録を行っても完了ページには遷移せず、その画面内の項目が全てdisabledになるのみです。もしそこで「編集ボタン」をクリックすると、disabledが解除され、各項目の値を変更したりできるのです。業務アプリケーションではkintoneに限らず、よくある仕様と言えるでしょう。 しかしこの仕様、合理的なように見えますが、ユースケース次第では厄介なことになります。 更新画面ではURLで対象レコードのIDを指し示している必要があるものの、新規登録画面入力時には、まだIDが払い出されていません。このためkintoneでは、登録完了のレスポンスをAPIから受け取ったあと、フロントエンド側でリダイレクトをかけて編集画面を表示していました。 その結果、新規登録時の送信成功イベントハンドラを使って表示したダイアログは、一瞬だけ表示されるのみで、すぐリダイレクトされることがわかりました。これではイチロー並みに動体視力が発達した人しかメッセージを読み取ることができません。 結局、新規登録時には処理成功のイベントハンドラでCookieを発行し、編集画面が表示されたタイミングでCookieの有無をチェックしてダイアログを表示し、その後にCookieを削除するという煩雑な処理が必要でした。 そこで、ふと思ったのです。「新規登録では、入力完了後にデータを保存し、IDを払い出すのが唯一の正解なのか?」と。 新規登録という名の更新 気になった私は、早速世の中のさまざまなwebサービスはどうなっているのか調査しました。結果、一部のサービスでは、新規登録を行うと入力開始前にIDが払い出されて、新規登録画面という名の更新画面を表示していることがわかりました。 メジャーなサービスでは、Google Workspace(Docs、Sheets)、note、Zenn.devがこのような設計になっています。これらのサービスでは、一度登録画面を表示した後に入力を行わず離脱すると、そのデータは一覧上には表示されません。しかしURLを直接入力すれば表示できます。数日経つと、URLを入力してもアクセスできなくなります。以降ではこの方式を便宜的に「登録編集共通方式」と呼ぶことにします。 登録編集共通方式のメリットとデメリット この処理方式、主にフロントエンド観点では、実装が楽になるというメリットばかりとなります。一方バックエンドは、フロントエンドの実装が楽になったしわ寄せとして、主にDB周りの設計に複雑さが生じます。以下詳しく整理してみます。 メリット フロントエンド側の考慮事項が減る 登録と編集を共通化してしまえば、新規登録を編集と同等の挙動に見せかけるための様々な工夫が不要になります。当然、実装もシンプルになると言えます。 多重POST問題から解放される IDが払い出されていない場合、同一の投稿がすでに送信されていないか判断する必要があります。フロント側でボタンをごく短時間不活性化すれば良いとの意見もありますが、ユーザーは数秒後に同じ内容を送信してくることもあり、バックエンド側での多重POST判定の処理が必要なケースもあります。 他方、IDを払い出す場合、内容如何によらず、POSTされたら素直に上書き保存すれば良いだけなので、先述のような考慮は不要になります。 デメリット テーブル設計が複雑になる この設計を実行に移すには、未入力の状態でも登録ができるように、多くのカラムでnullを許容する設計にするか、IDを払い出すための最小項目の親テーブルと実データを格納する子テーブルの関係で設計する必要があります。 チームの方針として、テーブルの項目に原則nullを使用しないことになっている場合は、自ずと後者の設計を選択することになるでしょう。 新規登録時点では親テーブルのレコードのみを登録してIDを払い出し、最初のデータ保存のタイミングで子テーブルのレコードを登録します。これはアプリケーションの都合にDB設計が従属する形となるため、受け入れられないこともあるでしょうし、受け入れられたとしても、テーブルの管理が従来より煩雑になるのは間違いありません。 ごみレコードが沢山できる/定期的に削除処理が必要になる 新規登録の画面を開く都度にレコードが作成されるため、結局その後保存されずに離脱されてしまうと、そのレコードは、ゴミとして蓄積していくことになります。 DBの性能とシステムの規模によっては、パフォーマンスの劣化を早めてしまうため、定期的な削除が必要で、その場合バッチ処理を別途作成することになるでしょう。 まとめ 以上の通り、 登録編集共通方式について、採用した場合の具体的なメリットとデメリットを整理しました。 繰り返しになりますが、登録編集共通方式ではフロントエンド周りの開発コストが削減できそうですが、バックエンド周りの開発コストは増える可能性がありそうです。 例えばフロントエンド周りの機能が今後複雑化していきそうな場合には、バックエンド側が開発コストを多く負い、フロントエンド側をシンプルに保てる登録編集共通方式のほうが長期的に優れた結果をもたらすでしょう。一方、従来の会員登録のような機能では登録編集共通方式の採用はデメリットが目立つ結果になりかねません。 このため、プロジェクト全体の方針やユースケースに応じて、既存の方式と登録編集共通方式を比較検討しながら、その時々でベターな選択をしていけると良いかなと思います。
技術責任者の @sunaot です。エス・エム・エスのプロダクト組織では、カンファレンス参加や専門書籍による学習などを強く推奨して、金銭的・時間的な支援も広く行なっています。 取組み自体はとくに最近の Web の会社では珍しいものではありません。ただ、位置付けや考え方を表明しているのはやや珍しいらしく、入社してきた人やカジュアル面談の場などで説明すると面白がってもらえることがあります。そこで、今回はその背景や考え方を説明してみます。便宜上ソフトウェアエンジニアを例に説明をしますが、基本的にはプロダクトマネージャーやデザイナーなど他の職種においても同じことが言えると考えています。 学習への投資は責任を果たしてもらうための必要経費 エス・エム・エスのプロダクト組織では、カンファレンス参加や書籍の購入といったものに会社のお金や業務時間が使えることを 福利厚生として位置付けていません 。では、報酬ではないのだとしたらどのような位置付けなのでしょう? 実は、これは十分なクオリティの仕事をする上で当然必要なもの、 責任を果たすための過程で必要なものの一部 として提供をしています。 元々、エンジニアを始め、プロダクト開発の仕事というのはタスクを終えることが仕事ではなく、一定の品質水準を満たすものを届けることが仕事の完了条件に含まれています。そして、その自律の求められ度合が高いのが特徴です。ソフトウェアは目に見えないのでぱっと見で品質の判断ができず、自律しないと手抜きができてしまいます。さらに、目の前でやる仕事が全て自分の知識の範囲に収まることは非常に少ない仕事であることも特徴です。エンジニアであれば、大体知らない技術要素であったり製品だったりが関わってきます。 そのため、成果物に対してプロフェッショナルな水準の仕事をするとなったときに「調べる・学習する」ということが仕事の当たり前の一部になってきます。そして、仕事のたびに全部を新しく調べるわけにはいかないとなると、自分の道具を磨くための学習をし続ける必要があります。 必要な品質を満たすために十分な調査・学習をしてほしい こうした見方をしているので、今のエス・エム・エスのプロダクト組織では学習をするということに対して積極的に支援をしています。それは仕事に必要だと知っているし、明らかに投資に対してリターンが大きいからです (全部を学習し終えた人を転職市場から探して採用してくるのはとても難しくコストもかかります)。 "知らないことを調べることも仕事の内で、自身でクオリティの判断ができないうちに仕事を期限だけに対して終わらせないでほしい。必要な品質に対して調べることをしてほしい" ということもよくメンバーに対して伝えています。これも同じ理由で、それがまともな品質のエンジニアリングの仕事に必要だからそう求めています。仕事の時間を使って経験のない技術の調査をしてよいと聞くと、一見その人の時間への優しさのように聞こえますが、実はそうではなく仕事のクオリティへの厳しさゆえの方針だったりします。 直接は目の前の仕事に関係しない勉強会を仕事の時間にやっていたり、カンファレンスへの参加を業務時間に入れているのも同じ理由で、けっきょくいつ学ぶかだけの問題で、そうして積み重ねた学習がなければ必要になったときに一から全部学ぶことになってコストが高いから積極的に奨励している、という背景になります。そういう仕事だから、ですね。 もちろん、そうした学び合う環境があるほうが働いていて楽しいとか、優秀な人と学習すると刺激になって働きがいがあるとか、学習を支援している環境のほうがわいわいしていて周りの人も学ぶ気持ちになるとか、色々副次的なメリットもあるとは思っているのですが、一番の理由は「そういう仕事で、必要だから」という考え方をしています。 まとめ この記事のまとめです。 エス・エム・エスのプロダクト組織ではカンファレンス参加や専門書籍・コンテンツによる学習を推奨し、広くその支援をしています。 これは個人の学習支援のためという以上に、そのときにマーケットやプロダクトが必要とする水準のクオリティの仕事を求めるという姿勢から来ています。それまでの経験で得た知識・スキルでできる範囲のクオリティの仕事をしていくのでなく、必要であれば都度学習しながら未知の課題にも取り組める人とチームでいるための方針なのです。