TECH PLAY

BASE株式会社

BASE株式会社 の技術ブログ

576

この記事は BASE アドベントカレンダー 2022 の20日目の記事です。 はじめに BASE BANKというチームで BASEカード というサービスの開発をしている大垣( @re_yuzuy )です。 本記事ではBASEカードで行ったキャッシュバックキャンペーンについて、システム的な設計という観点から書いていきます。 そもそもBASEカードとは何なのか BASEカードは BASE で作ったネットショップの売上を残高として全国のVisa加盟店(以下加盟店)で使うことができるプリペイドカードです。 BASEカードによって手数料をかけずに売上金を即時に使うことが可能になりました。 キャッシュバックキャンペーン BASEカードでは利用者増加を促進するためにキャッシュバックキャンペーンを実施してきました。 第1回目はリリース直後の去年(2021年)の9/28~12/26に行われました。 そして第2回目は今年(2022年)の12/1~12/26で記事投稿時現在も行われています。 カード決済の裏側 キャッシュバックキャンペーンの設計を説明するあたってそもそもカード決済がどのように処理されるのかも簡単に説明しなければなりません。 基本的な流れ 加盟店でBASEカードを使って決済を行う場合、まずVisaにリクエストが行き、その後提携会社を通じてBASEカードに通知が送られてきます。 最も基本的な形は 残高確認→決済成功→決済確定 という順で通知が送られてくるパターンです。 各通知の詳細についてはこの後説明します。 決済がキャンセルされると途中で 残高確認→決済成功→キャンセル 残高確認→決済成功→決済確定→キャンセル というようにキャンセルの通知が挟まったり、なんらかの理由によって途中で商品の値段が上がると以下のように増額の通知が挟まったりします。 残高確認→決済成功→増額→決済確定 残高確認→決済成功→決済確定→増額→決済確定 残高確認 先程BASEカードは売上を残高として使える プリペイドカード と説明しましたが、実際の使用感は デビットカード に近いです。 例えば1,000円の売上残高があったとして500円の商品を購入したい場合 というようにサイレントにチャージが行われています。 残高確認とはこの例で言うと提携会社からBASEカードに送られてくる「500円残高ある? 」というところで、残高を確認する他にショップがBANされているか、カードがロックされているかなどの確認をしています。 1秒以内という速度要件があり、この要件を実現するためにした取り組みも面白いのでこれに関しても別でブログを書きたいと思っていますが、キャッシュバックにはあまり関係していないのであまり気にしなくても大丈夫です。 決済成功 残高確認を経て提携会社の向こう側であれこれやった結果、無事決済が成功すると送られてきます。 決済確定 加盟店(ネットショップなど)側で売上が確定すると送られてきます。 毎日特定の時間に送られてきます。 ネットショップだと商品を発送したときなどに送られてくることが多いです。 なので基本的に 決済成功してから決済確定までは数日間のラグがあります 。 ここで決済の詳細なデータ(加盟店や為替の情報など)がBASEカード側に送られてきます。 例えばBASEのショップで買い物をしていただくと、残高確認や決済成功の段階では加盟店名はBASEですが決済確定ではBASE*HOGE SHOPのようになります。 これはBASEカードに限ったことではないので自分のクレジットカードの利用履歴などを見て確認してみても面白いかもしれません。 キャンセル 決済がキャンセルされると送られてきます。 必ずしも全ての金額がキャンセルされるというわけでもなく、複数の商品のうち1つを返品するなどされた場合にはその商品の金額分だけキャンセルされます。 増額 上記の説明そのまんまなので割愛します。 キャッシュバックキャンペーンの設計 2021年 前述した通りBASEカードリリース直後で、もちろん初めてのキャッシュバックキャンペーンです。 BASEカードのキャッシュバックを設計するにあたって参考にできる記事等があまりなく、かつメインで設計した私が設計初心者だったこともあり苦労した印象があります。 仕様 2021年のキャッシュバックキャンペーンはざっくりと以下のような仕様でした。 キャンペーン期間中に来た決済が確定されたら特定の割合をキャッシュバックする。 キャッシュバックされた決済がキャンセルされたらキャッシュバックもキャンセルする。 本人確認の有無でキャッシュバックの割合・キャンペーン全体での上限金額を変更する。 本人確認済み: 5%・5,000円 それ以外: 1%・2,000円 決済毎の上限金額は500円。 ご利用履歴詳細でキャッシュバックされた金額を確認することができる。 DB設計 キャッシュバックキャンペーンの要素を保存するテーブルとして以下の3つを定義しました。 payment_transaction_logsに関しては決済に関する通知が蓄積されているとだけ考えていただければ大丈夫です。 cashback_campaigns キャッシュバックキャンペーンそのものを表すテーブルとしてキャッシュバックキャンペーンに関わる全てのテーブルの親となっています。 このテーブルが持つ重要な情報はIDとキャンペーンの開始・終了時刻くらいで、他の情報は別のテーブルが保持しています。 cashback_yields キャッシュバックの還元率や上限金額を保存するテーブルです。 targetというカラムを作りそれによって還元対象を判別できるようにしています。 2021年の場合は本人確認済と未確認の識別子を定義し、それぞれ還元率と上限金額が異なるレコードを用意しました。 cashback_logs キャッシュバック・キャッシュバックキャンセルの情報を保存するテーブルです。 キャッシュバックに紐づく決済の識別子やキャッシュバックが行われたときの還元率の情報を保存しています。 アプリケーション設計 2021年のキャッシュバックキャンペーンではバッチを毎日定期実行し、そこでキャッシュバック処理に関する全てのことを実行するようにしました。 処理としては 前回の実行以降に確定した(キャンセルされた)決済を引っ張ってきて、キャッシュバック(キャンセル)対象かつキャッシュバック上限未到達であればユーザーの本人確認状況によって適切な還元率を適応してcashback_logsにレコードを保存し、ショップの売上残高にキャッシュバック(キャンセル)する。 と、シンプルです。 よかった点・反省点 よかった点は結構キャッシュバックキャンペーン開始までスケジュールギリギリで設計・実装していたものの根本的には長生きできそうな設計にできた点です。 例えばリアルカードでの決済にだけキャッシュバックしたいというキャンペーンが生まれてもcashback_yieldsに適当な識別子を追加して、それに紐づく判別の処理を実装し当てはまればキャッシュバックをする、という感じです。 逆に反省点は前述した通り急いで実装するために(ただの言い訳ですが)一般化があまりなされておらず、実質的には今回のキャッシュバック専用の実装が出来上がってしまった点です。 ですが1年越しに見てみても悪くない設計にはなったのかなと思っています。 2022年 さて今年のキャッシュバックキャンペーンですが、前回のキャンペーンとところどころ仕様や実行方法が異なっています。 さらに キャンペーン期間中にBASEカードで1回以上決済をする(500円以上)と抽選で10,000円がキャッシュバックされる という特定の決済に紐付かないキャッシュバックも新たに登場しました。 しかし、これについては設計的に面白みがあまりないのでこの記事では書かないことにします。 仕様 今年のキャンペーンでは新規ユーザー獲得のため、キャッシュバック対象ユーザーが「キャンペーン中にBASEカードで初めて決済をしたユーザー」に 変わっています。 更に以下のような仕様が追加されました。 予算を超えたらキャッシュバックキャンペーンを終了する。 ご利用履歴画面で決済がキャッシュバックされる予定か確認できる。 このキャッシュバックされる予定(以下キャッシュバック予定)という概念が厄介で苦労しました。 DB設計 仕様を満たすためにテーブルや識別子を追加しました。 cashback_campaign_balances 予算を表すテーブルでキャッシュバック(キャンセル)が行われるたびに更新しています。 cashback_campaigns 2021年のキャッシュバックキャンペーンでは実施されているか否かを判断するためのカラムが開始・終了時刻しかありませんでしたが、今回は予算が消化されたら期間内であっても終了するという仕様が追加されたのでキャンペーンの実施可否が判断できるようにカラムを追加しました。 アプリケーション設計 前述したとおり決済成功と決済確定にはラグが存在しており、キャッシュバック予定を確認できるという仕様は正確に言えば、決済成功段階でその決済がキャッシュバックされる予定の金額などを確認できる、ということです。 これは日次バッチだけでは実現することができず、 決済成功が来たらキャッシュバック予定を保存し、日次バッチでは予定情報を見てその分売上残高にキャッシュバックする。 というように全体的に設計を変更することになりました。 キャンセル・増額の処理 2021年のキャッシュバックではバッチで処理していましたが、キャッシュバック予定の関係等でキャンセル・増額の通知が来たときに処理することにしました。 キャッシュバックが予定段階のときにキャンセル・増額された場合にはキャッシュバック予定・キャッシュバック予定キャンセルを追加で保存し、バッチでは決済IDに紐づく全てのキャッシュバック予定・予定キャンセルを足した値をキャッシュバックするようにしました。 キャッシュバック済みの決済が増額・キャンセルされた場合にはバッチで残高操作をせず、その場で残高操作まで行うようにしました。 日次バッチでキャンセル・増額のキャッシュバック処理をしない理由として、バッチ自体の実装を単純にしたかったことに加え、決済確定が毎日決まった時間に通知されるのと対照的にキャンセル・増額は決まった時間に通知されないという問題がありました。 これによってバッチで処理するようにするとキャンセルからバッチ実行までの間に余分にキャッシュバック可能額が狭められてしまい、本来キャッシュバックされるべき決済がキャッシュバックされない可能性が生まれてしまいます。 よかった点・反省点 よかった点は設計に関してちゃんと文書化できた点です。 これはキャッシュバックに限ったことではなく、BASEカードでは大抵の事柄(決済や本人確認など)について技術ドキュメントが書かれていて、カード決済というドメインそのものの複雑性と決済や本人確認などの複数のベンダーが関わっているという複雑性に立ち向かうためにこれらのドキュメントをとても重宝しています(もちろん前回のキャッシュバック設計時にも書きました)。 今回に関して言えばキャッシュバック予定という概念が新しく登場しましたが、きちんと文書化することで開発メンバー全員が新たな設計や概念に対して共通の認識を持つことができました。 反省点は前回と同じく、今回の仕様専用のような設計・実装になってしまった点です。 キャンセル・増額の処理のユースケースが巨大化してしまうなど、今年のキャッシュバックキャンペーンでは戦術的な設計になってしまった部分が多々ありました。 今後改善していきたいこと 今後もキャッシュバックキャンペーンは行われていくと思われるため、決済の実装からはできるだけ切り離すなど、より戦略的な設計にしていきたいです。 おわりに BASEカードにはキャッシュバックに限らず面白い課題がたくさんありますし、手をあげれば設計やデータ分析などやってみたいことに取り組める環境です!(2021年のキャッシュバックの設計をした当時私は17歳かつインターン生でしたが、興味本位でやりたいと言ってみたらメンバーのサポートもありやることができました) 一緒に開発していただけるメンバーを鋭意募集中ですので、この記事を読んでみて少しでも興味をもっていただけましたらぜひカジュアル面談だけでもよろしくお願いします! open.talentio.com 明日は緒方さんと松田さんの記事です!お楽しみに!
アバター
この記事は BASE Advent Calendar 2022 の19日目の記事その2です。 こんにちは。BASE 株式会社 New Division BASE BANK Section にて、Engineering Program Managerをしている永野( @glassmonekey ) です。 私個人としては、今年のアドベントカレンダー2回目です。 前回は以下の記事で普段の仕事への取り組みざまを書いたのでそちらもよかったらご覧ください。 devblog.thebase.in 今回の記事の趣旨としては、私が主に担当しているYELL BANKというプロダクト開発で行った Python の改善ネタになります。 ちなみにYELL BANKについては同僚のyuniさんが熱く語ってくれたのでそちらもご覧ください。 devblog.thebase.in YELL BANKのプロダクトの裏側 YELL BANK では、過去の売上データを元に提供金額を算出し、 BASE加盟店さま の規模感に応じた資金調達体験を実現しています。 その際以下のフローで金額の提示を行います。 売上予測といった機械学習の内容を返却するAPIから金額算出のための情報を取得する 我々の事業状況に応じて 提供金額算出 API が提示する金額の計算を行う 計算した金額を BASE加盟店さま 向けの管理画面で提示する 資金提供APIを始めとして、我々の開発チームでは基本的に Go を扱うことが多いです。 しかし 提供金額算出 API に関しては、機械学習の仕組みも簡単に取り入れる選択肢がありえるだろうということで、 Python で書かれています。 実際に現在は異常検知のために、機械学習の仕組みが導入されていたりもしています。 ある日の課題 リリースして5年にもなるサービスなので、金額計算のロジックを始めとしたドメイン知識の複雑さも増える一方の状況でした。 とくに金銭を扱うコードなので、一歩間違えると事業上大きなリスクを背負うことにもなり、品質にも気をつける必要がありました。 そのため、金額計算のテストは厚めに書いていたものの、複雑なドメインロジックの認知負荷を下げることにはそこまで対処できていない状況でした。 特に型の整備は全然できておらず、 int , str といったプリミティブな型が基本的に使われるという状況でした。 特にYELL BANKにおいて、同じ金額という内容でも以下を区別しており、一言に int として扱うのは限界がありました。 * 提供金額 : 利用者に提供する金額 * 支払い総額 : 手数料を含めた金額 いわゆるLintの整備はある程度できていたものの、とりわけ mypy による型の静的解析の対応ができていませんでした。型の静的解析があれば早めに気づけたミスも、テストを実行してみて初めて気づくという状況が度々発生してしました。 全てのテストで数分レベルなので、致命的とまでは言わないですが開発者体験としてあまりいいものではありませんし、今後のテストの内容次第では開発のボトルネックになるのは目に見えていました。 段階的に型をつけていく そこで、全体的コード知識を整理すべく、以下を中心に型の追加・厳格化対応をしていきました。 dataclassの活用 NewTypeでプリミティブな型に意味付けをする mypyのstrict化の実施 それぞれ詳しく説明します。 dataclassの活用 ある程度のドメイン知識を表す表現に当初は TypedDict をメインで使っていましたが、単体だとメソッドをつけられず不便でした。 一方で class を使えばオブジェクトに振る舞いを持たすことは可能ですが、 testに失敗したときに以下のように差分が不明瞭といった課題感がありました。(スクリーンショットはPyCharmでテストを実行したものです) マジックメソッドの __eq__ や __repl__ を定義してなんとかやりくりしていましたが、クラスの構造に対する追従漏れが生じたりと、十全とは言えない状況でした。 そこで dataclass を積極的に活用するようにしました。 dataclass の詳細は PEP 557 で定義されているので一読するのをおすすめしますが、3.7から導入された機能になります。 3.6用のバックポート も存在しています 使い方はシンプルで、classに対して @dataclass のデコレータを使用するだけです。 frozen=Trueを使用すると生成されるオブジェクトのプロパティの再代入が禁止され、イミュータブルなオブジェクトに簡単にできるので大変便利です。 @ dataclass (frozen= True ) class Point : x: int y: int 上記のclassに対して、あえて失敗するテストコードを書いてみます。 def test_sample (self): assert Point( 1 , 1 ) == Point( 2 , 1 ) すると以下のように失敗したときの差分もわかりやすく表記してくれるので、開発効率は大幅に上がりました。 NewTypeでプリミティブな型に意味付けをする 前述した通り、YELL BANKでは様々な数値を扱うため全ての数値を int だけで表現することに限界があると述べました。 ではどのようにするといいのでしょうか? 前述した dataclass を使った表現も1つの方法としては考えられるでしょう。しかし、振る舞いをそこまで必要としない数値的な概念に対して全てに dataclass を定義することは過剰なように思えます。 そこで、考えた手としては NewType の活用でした。以下のように簡単コメントで説明を併記しておくことで、簡単なドメイン知識が集約されるようにもなりました。 FactoringAmount = NewType( 'FactoringAmount' , int ) # 債権の提供金額。 PurchaseCreditAmount = NewType( 'PurchaseCreditAmount' , int ) # 提供金額に手数料とたしたもの。 strict な mypyの導入 そもそも mypy とはPython用の静的型解析ツールです。 https://github.com/python/mypy 元々mypyそのものは導入されていましたが、まともに運用はしていない状況でした。 また、strictオプションを有効にした場合の変更差分が多い状況でした。 mypyのstrict化をしている間事業の更新を止めるわけにはいかないので、最初の方はstrictの設定をOFFにして、日々のスプリントの開発上で無理のない範囲でちょっとずつ対応していきました。 現在のmypyの設定情報は以下のような感じで現在運用しています。 ignore_missing_imports = True no_implicit_reexport = False strict = True 補足として no_implicit_reexport に関してはパッケージの引っ越し作業を行った影響で、明示的に残しています。(近いうちに削除予定です) ignore_missing_imports に関してはサードパーティのライブラリに型情報のファイル(拡張子が .pyi もの)が無いと、 `error: Skipping analyzing "{パッケージ名}": module is installed, but missing library stubs or py.typed marker というエラーが発生するので設定してます。本来は抑制は褒められた話ではないでしょうが、サードパーティのライブラリに個別に設定するのは現実的ではないでしょう。 対応してよかったこと 我々のチームでは外部libraryの更新に dependbot を利用しています。その対応時に問題があった際に、先にlintや型チェックで気付けたこともあり対応しててよかったなと感じました。 細かいところだと、安易なOptionalを利用している箇所があり、Optionalを外すために不要な複雑さを生んでいる箇所の発見にもつながったこともありました。おかげで、コードとしてシンプルさがあがったように思います。 また、一言にintといっても、金額なのか?どのような金額なのか?を対応前はコードジャンプして読み解く必要がありましたが、今は型を見れば済むので認知負荷の削減にもつながりました。 チームのナレッジ的にもPythonに詳しいメンバーがそこまで居ない状況だったので、型解析をはじめLintがおすすめするPythonのベストプラクティスに乗ることで特に困らず開発できているように感じています。 今後 現在我々のチームで扱っているPythonは3.9ですが、3.10, 3.11と型周りの力の入れようを感じているので、その恩恵に与れるように色々と追従はしていきたい所存です。 特に3.10で導入された TypeGuard はcastでごまかしている部分もあるので使っていきたいなと思っています。 3.11では大幅速度改善をしているようなので、近いうちにアップデートしてAPIとしての品質も高めていきたいとかんがえています。 我々の開発チームはPHP/Go/Python/Vueとフルスタック・フルサイクルに開発しているチームなので、もしきょうみがあるよって方がいましたらDMや下記のlinkからの応募お待ちしています。 一緒に最高の開発体験を作っていきましょう!! 以下の採用リンクからのエントリーお待ちしています。 open.talentio.com もしくは @glassmonekey までDMいただけると嬉しいです。 明日は同僚の @re_yuzuy さんによる、BASEカードの裏話と、デザイナーの @hoteco さんによる入社後の体験についての2本立てですです。楽しみですね!!
アバター
この記事は BASE Advent Calendar 2022 の19日目の記事です。 はじめに こんにちは、DataStrategyチームの竹内です。 今回はBASEで作成されたショップが扱っている商品のカテゴリを機械学習モデルを使って推論するための取り組みについてご紹介いたします。 はじめに TL;DR 商品カテゴリ データセットの作成 ラベルセットの検討 データのサンプリング AWS Ground Truthを利用したアノテーション アノテーション対象のフィルタリング モデルの学習とテスト BERTのファインチューニング モデルの性能評価 gokartを利用したパイプラインの構築 AWS Batchを利用したバッチ推論基盤 おわりに ※ 記事内のコードはサンプルとして簡略化しています。 TL;DR BASEで作成されたショップに登録されている商品のカテゴリ(ファッション、食料品など)を予測するモデルを作成しました 分類モデルにはBERTをファインチューニングしたものを使用しました(商品画像の利用は今後の課題です) アノテーションにはAWS Ground Truthを利用しました カテゴリ数分の2値分類モデルを作成し、8カテゴリ分をマルチラベルでラベル付けしています モデルの学習は社内オンプレGPUマシンを利用し、推論はAWS Batchを利用しています 商品カテゴリ 現在BASEで作成されたショップからはファッションアイテム、インテリア用品、食料品など毎日数万点もの様々な商品が登録され、販売されています。 しかしながら、それら1つ1つの商品がどういったカテゴリに属するかを把握することは容易ではなく、例えば「BASEを通じてどれぐらいファッション商品が販売されたのか」「不正決済が起きている商品の傾向はどういったものか」といった細かい分析を行う際は、人の手で商品を1つ1つ確認していくか、ショップ側で設定されたショップのカテゴリを利用することが多いのが現状です。 ところが、ショップのカテゴリが必ずしもそのショップで販売されている商品のカテゴリと一致するとは限らず、またショップカテゴリの設定は任意であるためカテゴリを設定していないショップも数多く存在します。 そのため、DataStrategyチームではその日にBASEのショップで登録された商品のカテゴリを、機械学習モデルを用いて自動的に推論するバッチ処理基盤を新しく作成しました。 データセットの作成 機械学習モデルを作成するためには学習およびテスト用のデータセットが必要となります。 着手段階では商品のカテゴリが正確にラベル付けされている一定の規模のデータセットが存在しなかったため、まずはそれらの作成から行いました。 ラベルセットの検討 データセットの作成にあたり、まず商品にどのようなラベルをつけていくかの検討を行いました。 基本的には既存のショップカテゴリをベースにしつつ、実際の商品群に目を通しながら、できるだけ漏れや重複が少なくなるよう大カテゴリ8種類(インテリア、ファッション、スポーツ、電子機器、コスメ、飲食物、サービス)と、その下の中カテゴリ約100種類(調理器具、Tシャツ、ゴルフ用品、お菓子など)に整理しました。 その上で一旦大カテゴリ8種類分に絞った分類モデルの作成を行うことにしました。 データのサンプリング BASEのショップで既に公開されている商品をランダムにサンプリングし、アノテーションを行うことで学習およびテスト用のデータセットを作成しました。 サンプリングする際は特定の季節の商品に偏らないように1年以上幅のある範囲から均等に抽出を行いました。 その上でアノテーションコストを抑えつつ8種類の大カテゴリ全てについて十分なサンプルサイズを確保できるよう、既に十分なサンプルサイズが得られたカテゴリに分類される商品をフィルタリングする処理を入れました。(後述) AWS Ground Truthを利用したアノテーション データセットのアノテーションには AWS Ground Truth のベンダーワークフォースを利用しました。 AWS Ground Truthを利用した理由としては普段からAWSを使用しているため学習コストが小さい点、S3と連携することでデータセットやワークフローの管理が容易である点、ベンダーワークフォースについてはAWSによって品質やセキュリティの手順が事前にスクリーニングされている点などが挙げられます。 アノテーションにはテキストと商品画像両方を判断材料としたかったのですが、Ground Truthで利用できるラベリングツールはテキスト、画像どちらか片方のみに対応したものであったため、あらかじめ商品画像に商品タイトルと商品説明文をキャプションとして付与した1枚の画像を作成し *1 、それを対象に1画像のマルチラベル *2 分類タスクとしてアノテーションのジョブを作成しました。 アノテーション用にキャプションが付与された画像(サンプル) ちなみにGround Truthのジョブ作成時、ワーカー数の設定部分がデフォルトで折り畳まれていますが、この部分はタスクの難易度や必要な精度などを考えて調整しておくことを推奨します。(この部分の初期値が3になっており、そのまま変更し忘れていた場合にデータセットのサイズの約3倍のコストと作業時間がかかってしまった、といったトラブルが起きる可能性があります。) Ground Truthのワーカー数設定 アノテーション対象のフィルタリング 単にランダムサンプリングを行なったデータをアノテーションすると、BASEの商品全体において多数を占めるファッションカテゴリの商品にアノテーションが集中することになります。 一方でファッション商品は比較的分類が簡単なカテゴリのためそこまでサンプルサイズは必要なく、逆に分類が難しい少数派のカテゴリのサンプルサイズを確保しようとすると大量のデータをアノテーションしなくてはならなくなり、コストパフォーマンスが悪くなります。 そのため十分なサンプルが確保できたカテゴリから順次分類モデルを作成していき、モデルのテスト性能が十分だった場合はそのモデルを利用し、以降のアノテーションで事前にそのカテゴリと予測された商品を除外する処理を入れました。 こうして得られた学習データのカテゴリ分布は実際のカテゴリの事前分布と大きく異なることになるため、学習時のミニバッチの作成部分でサンプルサイズの調整を行いました。 モデルの学習とテスト BERTのファインチューニング 分類モデルには事前学習済みのBERTをファインチューニングしたものを使用することにしました。 BERTをはじめとしたニューラルネットベースのモデルの利点としては テキストの文脈や単語の前後関係などを考慮できる点 凝った前処理が不要である点 kaggleなどのコンペで多用されており、分類タスクにおける性能の高さが担保されている点 使いやすいライブラリ(主にHugging FaceのTransformers)が存在し、ベースモデルやタスクの変更、モデルの改造なども柔軟に行える点 使いやすい日本語の事前学習済みモデルが存在する点 などが挙げられます。 また、今回は導入していませんが、いずれテキストだけでなく商品画像も利用したマルチモーダルなモデルにすることも視野に入れています。 *3 ラベルのついたデータセットをtrain/evalに分け *4 、商品のタイトルおよび説明文を結合したテキストデータを簡単に前処理し、PytorchのDataset化した後でtransformersのTrainerクラスにベースモデルと各種パラメータとともに渡します。 学習は社内のオンプレGPUマシン(RTX3090)を使用しました。 ファインチューニング部分の実装例 import pandas as pd from transformers import TrainingArguments, Trainer, AutoModelForSequenceClassification, AutoTokenizer, EarlyStoppingCallback, ProgressCallback class BertClassifier : def __init__ (self, target_label: str , model: str , tokenizer: str , num_labels: int ): self.model = AutoModelForSequenceClassification.from_pretrained(model, num_labels=num_labels) self.tokenizer = AutoTokenizer.from_pretrained(tokenizer) self.item_category_collator = ItemCategoryCollator(self.tokenizer) self.model.config.id2label = { 0 : f "not_{target_label}" , 1 : target_label} def fit (self, df_train: pd.DataFrame, df_eval: pd.DataFrame, early_stopping_patience: int , training_args: TrainingArguments) -> None : dataset_train = ItemCategoryDataset(df_train) dataset_eval = ItemCategoryDataset(df_eval) trainer = Trainer( model=self.model, args=training_args, compute_metrics=self.metrics, train_dataset=dataset_train, eval_dataset=dataset_eval, tokenizer=self.tokenizer, data_collator=self.item_category_collator, callbacks=[ EarlyStoppingCallback(early_stopping_patience=early_stopping_patience), ProgressCallback()], ) trainer.train(ignore_keys_for_eval=[ 'last_hidden_state' , 'hidden_states' , 'attentions' ]) def evaluate (self, df_test, batch_size): ... def inference (self, df_inference, batch_size): ... モデルの性能評価 作成したモデルの性能を検証するためのテストデータは学習データセットと同時期の商品群および比較的最近の商品群からのランダムサンプルの2種類を用意しました。 *5 複数の正解ラベルがついた1つの商品に対して8つの2値分類モデルで推論を行い、モデルの出力が閾値0.5を上回ったラベルと正解ラベルを比較する形で性能評価を行いました。 商品カテゴリの分類はマルチクラス・マルチラベルの分類タスクであり、ラベルは不均衡であるものの誤分類コストについては不正検知のようにそこまで非対称性があるわけではないという点を踏まえ、性能評価の指標としてはミクロ/マクロのf1スコアを重視しつつ、ミクロ/マクロの適合率(precision)、再現率(recall)やラベルごとの適合率、再現率なども参照しました *6 。 テスト結果の例 scores precision recall f1-score micro_avg 0.882 0.885 0.884 macro_avg 0.746 0.742 0.732 weighted_avg 0.884 0.885 0.882 数値に対応するイメージ ● 全体的に漏れなく検出されている(どの商品を見てもきちんとラベルが付いている) ● 全体的に誤分類が少ない(デタラメなラベルが少ない) ● 極端に検出漏れがあるクラスがない(特にラベルが付きにくいカテゴリが少ない) ● 極端に誤分類が多いクラスがない(特にデタラメなラベルがついているカテゴリが少ない) 全体の多くを占めるファッション系のスコアが高いためミクロf1スコアは高い一方、一部分類が難しい少数派のカテゴリのスコアが低くなったため、マクロf1スコアは比較的低い値となっています。ミクロf1スコアをキープしたまま分類が難しいカテゴリのモデルを改良し、マクロf1スコアを改善していくことが今後の課題となります。 gokartを利用したパイプラインの構築 今回は2値分類モデルを複数組み合わせることでマルチラベル分類モデルを作成しているため、全体として以下のように若干煩雑なワークフローとなっています。(実際には画像ベースのモデルの検証など間に色々と実験を挟んでいるのでよりカオスです。) モデル作成パイプライン こうしたワークフローをうまく整理し、他のメンバーが手元で作業を再現しやすくする目的で、画像などの生データのバージョン管理に Data Version Control を利用し、ワークフローの実装にはエムスリーさんが開発されているオープンソースのパイプラインツールである Gokart を利用させていただきました。 gokartはS3との連携も容易なため、学習したモデルのチェックポイントをそのまま推論基盤から利用することでモデルのデプロイやバージョン管理もスムーズに行うことができました。 AWS Batchを利用したバッチ推論基盤 DataStrategyチームではバッチ処理は基本的にFargateを使用していますが、今回は処理にGPUインスタンスが必要となり、残念ながらFargateはまだGPUに対応していないため、今回はAWS Batch+EC2のGPUインスタンス(g4dn)を利用しました。 常時推論対象となる商品をSQSに保存していき、1日に1回AWS BatchからGPUインスタンスを複数台起動しバッチ処理を行なっています。 推論部分に関してはtransformersの TextClassificationPipeline を使用するとかなりすっきりと実装することができます。 推論部分の実装例 import pandas as pd from torch.utils.data import Dataset from transformers import TextClassificationPipeline from transformers.modeling_utils import PreTrainedModel from transformers.pipelines.pt_utils import KeyDataset from transformers.tokenization_utils import PreTrainedTokenizer def inference ( df_inference_target: pd.DataFrame, model: PreTrainedModel, tokenizer: PreTrainedTokenizer, target_label: str , batch_size: int = 16 , device: int = 0 , ) -> pd.Series: result = [] classifier = TextClassificationPipeline( model=model, tokenizer=tokenizer, framework= "pt" , task= "item_category" , batch_size=batch_size, device=device, num_workers= 2 ) dataset = ItemCategoryDataset(df_inference_target) tokenizer_kwargs = { "padding" : True , "truncation" : True , "max_length" : tokenizer.model_max_length, } for out in classifier( KeyDataset(dataset, "text" ), batch_size=batch_size, **tokenizer_kwargs ): if out[ "label" ] == target_label: score = out[ "score" ] else : score = 1.0 - out[ "score" ] result.append(score) return pd.Series(result) 推論された結果は社内のデータウェアハウスに保存され、他のデータと合わせた分析や、Lookerを使用したダッシュボード化などに利用することができます。 おわりに 今回は機械学習モデルを利用した商品カテゴリの推論基盤に関する取り組みについてご紹介させていただきました。 今後に向けて より詳細なカテゴリの分類 データセットの拡大(精度の向上) 商品画像の利用(マルチモーダル化) モデルの精度監視と継続的アップデート Out of Distributionの検知 などなど色々と課題は残っていますが、ひとまず今まで把握できていなかった商品単位の粒度まで解像度を上げた分析が可能となり、既存の別の機械学習モデルの特徴量として使用したり、検索や推薦の精度を上げたり、カテゴリが設定されていないショップのジャンルを推論したりと色々な用途で活用が見込めそうです。 さて、DataStrategyチームでは機械学習エンジニアとして一緒に働いてくださる方を積極採用中です。カジュアル面談も実施しているのでぜひお気軽にご連絡ください。 募集一覧 / BASE株式会社 明日は @yuzuy @ayako-hotehama の記事が公開予定です、ぜひご覧ください。 *1 : こちらの記事を参考にさせていただきました。 https://qiita.com/mo256man/items/b6e17b5a66d1ea13b5e3 *2 : セット商品やスポーツウェアなど、複数のカテゴリにまたがって属する商品も存在するためマルチラベルとしました。 *3 : timm のモデルの出力を正規化してconcatするなどナイーブな手法は色々試したものの、BERT単体のモデルを上回らない結果となりました。悲しい。 *4 : 同じショップがtrain/evalに分かれないようショップのIDでGroupFoldしています。性能検証で使用したテストデータにも学習時に使用したショップが含まれないようにしています。 *5 : 登録時期によるデータドリフトの影響も見たかったため。実際はそこまで影響はなかったので最終的に1つのテストデータにまとめてしまいました。 *6 : 各種スコアの定義は sklearnのdocment が参考になります。
アバター
この記事は、 BASE Advent Calendar 2022 の18日目の記事(その2)です。 SRE Group の ngsw です。 先日ネットショップ作成サービス「BASE」は10周年を迎えました。 「BASE」サービスリリース10周年 ~「好きが、売れる。」をコアメッセージに特設Webサイトの公開とクーポンキャンペーンを開始~ | BASE, Inc. 10th Anniversaryクーポンキャンペーン は現在すでに終了しています 好きが、売れる。BASE・10周年特設サイト せっかくの10周年です。ちなんだ記事を書けたら面白いかなとSRE関連のIssuesを振り返っていたのがこの記事のはじまりでした。 BASEの10年分のシステムの課題を読者の皆さんと共有できたならば面白いかな、というのが(後付けの)動機です。 SRE関連のIssuesはGitHub移行後の2016年より存在し、2022.12現在で4108個存在していました。2016年から7年弱分のIssuesからBASEの課題の移り変わりなど当時の状況を踏まえつつピックアップして紹介いたします。 1 誤解を与えてしまうといけないので補足しますが、この記事内で「BASEでは」と記述されている場合、意味するのはサービス「BASE」のシステムまわりの話題であり、それを担当し責任をもつSREや開発陣の話題となっています。 組織であるBASEには、Data StrategyグループやBASE BANKセクションも存在し、それぞれが別のシステムを担当し管理しています。ある点においてサービス「BASE」のシステムよりもモダンな構成であったりしますので、事前に補足いたします。 AWS関連について BASEは当初短い期間のオンプレミス時代以降、ずっとAWSで運用されてきました。いくつかのAWSアカウントが存在しますが、その中で最古のAWSアカウントの請求書日付をみてみると、2013年03月となっています。時間を追って費用をみていくと本格的に利用がはじまったのが2013年08月であろうと思われます。 VPC移行期(2016〜2017) BASEはオンプレミスからAWSへの移行からしばらく、Classic環境で稼働していました。 そこからVPCへの移行計画がはじまります。 VPCに本番RDS移行 VPC移行ステップ VPC移行 VPC移行第一ステップ VPC移行にあたりアプリケーションエンジニアにDBのホスト変更を依頼する VPC移行にあたりアプリケーションエンジニアにredisのホスト名を変更してもらう VPCにMySQLを移行する[スナップショット版] VPC移行 / 当日 ClassicとVPCとの違いは以下をご確認ください。 EC2-Classic - Amazon Elastic Compute Cloud ここにある様々な制約の解決を目的とした移行計画となっており、おおよそ1年間をかけ対応が行われました。 切替作業当日は深夜メンテを行い、サービス停止のもと無事移行が完了しました。 リソース整理Issuesの登場(2017〜) VPC移行という仕事を終え余裕ができたからかわかりませんが、AWSリソースを整理する目的のIssuesがたちはじめました。 開発アカウントのIAM整理 AWS本番環境のACM整理 使用していないセキュリティグループの削除 セキュリティグループ - 無制限アクセス IAM Access Key 不要なものは無効化/削除 開発速度を優先した結果、性善説に基づく牧歌的運用のつけをここから自覚しはじめる時期という、ある種あるあるな話題が、例にもれずBASEにも立ちはだかった瞬間でした。ここから2022年の今日においても、運用を続ける以上無視することができない一生ものの課題となっています。 2019年ごろには Trusted Adviser を、2021年には AWS Well-Architected を利用して、単純な整理だけでなくセキュリティ強度と開発速度の向上などの相乗効果なども視野に入れ活動をしています。後述しますがIaCなどはこの点を強く意識したものです。 うっかり対応期(2020〜) この頃になると、後手にまわって対応が遅れてしまったな、というIssuesがいくつかみられるようになりました。 [SES]v3署名非推奨のためv4署名への切替 [VPN]AWS Client VPNの調査 SubnetのIP枯渇問題の解消 v4署名切り替えに関しては、AWSからの周知メールにより発覚しました。 AWS Client VPNの調査が必要となったのは、2019年02月コロナ禍におけるリモートワーク全面切り替えのために対応する必要がありました。SubnetのIP枯渇問題は、コロナ禍における想定以上の急成長の対応で、増設を行ってきた結果黄色信号となったため対応した形でした。 ぎりぎりで回避できた点は不幸中の幸いですが、このような不必要な成功体験が積み重なっていくことは不幸中の不幸と言えるでしょう。 Linuxまわりについて ntpの設定 CentOS7のcoreでカーネルパラメータを追加 /proc/sys/net/ipv4/tcp_max_syn_backlogの値を変更 カーネルパラメータチューニング chrony導入 kernel_parameter EC2における単位時間あたりの名前解決制限対応 EC2における単位時間あたりの名前解決制限の対応 - BASEプロダクトチームブログ で対応内容を解説しています こちらについても前項で最後に先述したことと同じことが言えるでしょう。Issuesを追う限りは問題がでるまで設定が抜けていたんだな、という感想を持ちます。 この手の問題で難しいところは 決め打ちである程度まとめて事前に入れちゃう派 問題が起きてから入れる派 の二通りがあって、ngswはどちらかというと前者、BASEはどちらかというと後者であるという形です。 ただこれも結果論のところがあり、事前に設定しておくことで暗黙的に処理されることが果たして嬉しいのかどうか、という交換ではあると思います。 EC2デプロイまわりについて BASEは少なくとも2016年ごろより、当時の担当者である @srockstyle によるIaCが進められていました。EC2まわりのほとんどがChefで記述、管理されており、2017年ごろには Provisioning や Deployment を chat-bot 経由で行えるよう整理されていきました。 作り込みが相当に入っており、自前のB/G DeploymentやRollback機能や、単純な増設機能を有しています。 自動デプロイメント改善案をつくる 2 Mackerelを自動退役する デプロイした時のPRリストを取得&Slack通知する デプロイおよびアーキテクチャの改善プロジェクトを発足する プロビジョニングとデプロイの切り離し ここでシステムの説明をしましょう。 chat-bot(Hubot) api server(Rails) aws-sdk DB (MySQL) chef-server(Chef) Slackからchat-botへ投稿されたリクエスト文言を元に、api serverへさまざまな実行指示が飛びます。 api server はAMIのもととなるEC2へデプロイ用のレシピを実行するchef-clientを投げ終了を待ちます。 api server は終了を検知したのちaws-sdkを利用してAMI取得指示を出します。 api server はaws-sdkを利用して3で作成したAMIをもとにB/Gデプロイメントを行います。 api server は3〜4の間で、Insntace idやAMIの世代IDなど必要な情報をDBに書き込み管理のために利用します。AMIの世代IDがあるため、rollbackが可能となっています。 ほぼほぼの機能が2018年の段階で固まっており、2020年ごろより改修をいれ続け現在も現役で利用されています。その一方で様々な限界も見えつつあるのが現状であり、EC2からECSなどの乗り換えとあわせてデプロイ周りの見直しなどが必要なのではないか、というのが2022年現時点での課題であります。 ただ単純にEC2をECSにうつし、デプロイ周りを別機構にすればそれでOKという未来でもないよう考えており、開発陣からみた利便性と、システム全体のパフォーマンスとを比較勘案する必要があるでしょう。 当システムのB/Gデプロイメントの実現についてはここで解説されています。 Chefとnginxで作るPHPアプリケーションのReliable Blue Green Deployment - Speaker Deck IaCについて chefの話題がでましたね。ついでなのでBASEにおける IaC 化対応について、どのような歴史があるのかご紹介したいと思います。 Chef期(2016〜) Chefのレシピ;Webサーバ関連:簡単な変更のみ Chefレシピ:Fluend導入周り Chefレシピ作成:deploy_branch(デプロイするレシピ) Chefのレシピ:基本部分 2016年のこの時点でChefまわりはほぼ固まっております。2022年現在でもChefは利用され、細かなリファクタリングなどを繰り返し整理運用されています。課題感については先述したデプロイまわりと重複するので割愛します。 AWS リソースまわりもIaC化したい(2019〜) [pj_lottery]SQSキュー、SNSトピック作成依頼 売上データダウンロードAppsに関してのAWSリソースの追加依頼 [売上データダウンロードApps]S3 bucket追加と設定 [売上データダウンロードApps]sqsの追加と設定 [#base-apps-google_shopping_ads]SQSキュー、SNSトピック作成依頼 [SNS, SQS作成依頼]顧客管理で使用するSNS, SQSのstg/prdでの設定 [SNS, SQS作成依頼]リマインドSMS送信で使用するSNS, SQSのstg/prdでの設定 というような感じでS3やSQS、SNSなどのリソース作成依頼が、開発チームより続いたことがありました。2019年頃まではそもそも作業対応者によって構築方法がばらばらで、Web Consoleによる都度作成が行われていました。ここから作業手順の確立の意味をこめてaws-cliを利用したワンライナー構築が行われていきました。 賢明なる読者の皆さんはいま同じ感想をもっているはずです。 「他人の書いたaws-cli使い回すのやだなあ」 そうですね、そうなっていくのが自然です。自分の書いたaws-cliだって読み直すのは手間です。 ですので現在は EC2まわりはChefで AWSリソース周りはterraformで という形にして後者を進めている形です。話題は変わりますが先述しているAWS Well-Architectedもこの判断に少なからず影響しています。 terraform 移行期(2021〜) Terraform Cloud / Team & Governance Plan の稟議を出す GHAでTerraformのplan/applyを実施できるようにする 既存リソースのimportとmoduleの作成を並行してすすめていく中で、2021年当初はterraform cloudをSREメンバーでのみ利用していました。しかしながら使い勝手の部分でGitHub Actionsのほうが勝るよう判断ができたので、2022年12月現在はGHAに寄せている状態です。社内のリポジトリにGHAのお手本がいくつか存在していたことなども、この判断の後押ししたのかもしれません。 terraform化に向けての具体的な行動は、この記事からはじまったと言ってもいいかもしれません。 Terraform導入への第一歩 - BASEプロダクトチームブログ monitoring について mackerel導入期(2017〜) mackerel監視項目追加 mackerel監視設定まわりの整理(2019〜) [mackerel]service,roleの整理 [mackerel]監視項目の整理 [mackerel]internal-api-batchのmackerel-agentインストールのリファクタ [mackerel]通知グループの整理 [mackerel] アカウント周りの整理 [mackerel][監視]Apache Server-StatusにてBusyWorkersの数値を閾値にして監視アラートあげたい [mackerel]監視対象候補の洗い出し [mackerel]service*roleを整理する [mackerel]監視項目の拡充(EC2) [Mackerel]サービス影響のあるクリティカルな取得リソース、監視項目の精査及び組み込み [Mackerel][nginx]プロセス監視 BASEにおいて監視周りはmackerelに強く依存している部分がありました。ある時期から特定時間帯に負荷高騰のアラートが鳴る状態が続いており、社内でみな敏感になっていました。最終的にはその敏感さが「いま重くない?」という会話を生むようになっていました。 携わるプロダクトのシステムに、メンバー全員が関心を持つことはとてもよいことですが、 「重いなあ/重くない?/そんなことないよ?」という個々の体感に基づいた、客観軸のない会話が多発することはよくないことと言えるでしょう。そのための対策が次項になります。 「ユーザからみてサービスが重い」とはどういうことか(2020〜) 「サービスが重い」の指標となる外形監視の見直し [BASE]Mackerel + Twilioによる特定アラート時の自動架電 Twilioを利用した障害時の自動連絡網システムについて - BASEプロダクトチームブログ 外形監視を設定し、メトリクスをもつことでどのように重いのか、ユーザと近いかたちで常に同一の基準軸で「重い/重くない」の判断をつけられるようになりました。またあわせて「重い」と判断できるときにはプロダクトにとって重要な問題であると判断し、連携して架電発報するようしました。 気をつけないといけないのは、ここでのアラート対応は「重いという状態の定義ができ、それを越えたらアラートが出せるようになったね」というだけであって、「もっと速くできるんじゃないか?」ということに関しては無関心であるということです。たとえば常にレスポンスタイムが閾値98%のサービスは、アラート発報はしないが手放しで喜べるような状態ではありません。 New Relic(再)導入期(2020〜) [New Relic]chefの .name を appname に採用する [NewRelic]Apacheを利用しないPHP稼働インスタンスに対して [NewRelic]internal-api-workerだけ暫定無効化する [New Relic][operation-controller]deploy marker用のAPIを設定する New Relic AWSインテグレーションでDSアカウントのメトリクスを取得できるようにする 先述した「もっと速くできるんじゃないか?」という課題感と、「それらのアクションをより開発陣主導で行うことができないだろうか」という組織的なストレッチ目標が New Relic (再)導入という意思決定を生みました。 Issues群は主にAPM初期導入設定時のいろいろな修正です。具体的な事例は本ブログの過去記事よりご覧いただけます。 はじめてのNew Relic - 社内オンボーディングを開催いただきました - BASEプロダクトチームブログ New Relic User Group Vol.0で登壇しました #NRUG - BASEプロダクトチームブログ BASEの顧客管理はどのようにして実現されたか - BASEプロダクトチームブログ New Relic OneでDevOpsのキーメトリクス デプロイ頻度をグラフ化する - BASEプロダクトチームブログ NRUG (New Relic User Group) Vol.1に参加してきました - BASEプロダクトチームブログ レスポンス改善プロジェクトでやったこと - BASEプロダクトチームブログ 今BASEに入社してやることあるの?という疑問に答えるよ - BASEプロダクトチームブログ 商品在庫絞り込み機能のリリース振り返りと、New Relicを活用した観測について - BASEプロダクトチームブログ DBまわりについて Aurora移行(2017〜2018) 開発環境のRDSをAuroraにする 11月メンテ作業(Aurora移行) BASEのメインDBをAurora(MySQL)に移行しました - BASEプロダクトチームブログ クエリ効率化などは定期的に(2018〜) レプリカ向けるSQL SQLチューニング2019年2月 DBまわりについては2017年にRDS for MySQL時代からAurora v1(MySQL)へ移行しています。 またそれ以前からDBAを中心に細かい運用改善が繰り返し行われていました。 特にRDS時代にはストレージの残量について、意識を割かなければいけない状態だったことも強く関連していると思います。 コロナ禍の想定外の急成長(2020) 負荷問題の課題について 「もうさばき切れない」アクセスが激増したECプラットフォームにおける負荷対策 - BASEプロダクトチームブログ この時期の話題をCTOの川口さんに振ると、決まって「記憶がないんだよね」と返ってきます。「何を言ってんだ、こういうことがあったじゃないですか」と問いかけてみるけれど、そういうわたし自身も時系列がぐちゃぐちゃであったりします。つまり我々にはこのときの記憶があまりないです。これは冗談半分であり事実半分であるのが怖いところです。Issues振り返ってみても結局よくわからないんですよね。 そんなあやふやな中でも「Aurora DB Clusterへの新規接続時の問題、これが課題だよね」というのは、確実に共通している部分でありました。 RDS Proxy導入(2022) [#pj-rds-proxy]Subnet Group / Security Groupそれぞれ [#pj-rds-proxy]ph0, ph1 [#pj-rds-proxy]RDS Proxy導入後のReader台数削減 Amazon RDS Proxy が BASE にもたらした期待以上の導入メリット - BASEプロダクトチームブログ 「満を持して」という言葉がこれほど当てはまるシチュエーションは、人生を生きるなかでそうそうないでしょう。われわれは解決方法を手に入れたのです。さらに気持ちがよかったのはRDS Proxyを導入した後に、Readerの台数を削減できたことです。 個人的には「BASEシステム改善における2022年今年一番の大仕事」と考えています。メインを担当した @tadamatu には感謝しかありません。 Costについて インフラコスト意識のたかまり(2018〜) 開発環境のAWSリソース整理と削除 Data Transferの増加について RIの方針決め 商品画像で利用しているS3のドメイン分離 Lambda makeThumbnail の廃止対応 SavingPlan算出(2021/BASE) 2021年のRI/SavingPlan纏め 2018年当時に開発環境の整備の一環で、野放図になっていたAWSリソースの削除などが行われました。先述したリソース管理の意識の萌芽とはいったいなんだったのか。やはりこの手の問題は常に付きまとうものと思うほかありません。 主にこの手の意識を高くもってシステムを見守ってくれているのが浜谷さんです。 現在はSREチームを離れて他のチームに所属していますが、予算面についてはいまも担当してくれています。 過去にはこのような記事も書いています。 TerraformでNGTのポータブル環境を作った - BASEプロダクトチームブログ コスト削減の具体事例(2022) S3ストレージタイプ移行機能検証 [S3]商品画像領域にlifecycleルール適用しINTELLIGENT_TIERINGにする 浜谷さんの過去の指摘内容であった、コスト削減案のひとつを今年完遂できたことは嬉しい話題です。 BASEではショップオーナー様が商品画像を登録する際に、本領域と解析のための別領域をS3 Bucket上に両方もっています。このうち削除可能な領域があり、この領域上のオブジェクト削除が課題となっていました。 当初は当該領域のオブジェクト削除においてaws-cliを用いることを想定して対応を進めていましたが、そもそものリスト出力ができないという状態で、しばらく手つかずの状態が続いていました。 ここで打開策として採用したのが、後付のlifecycleルールの設定で自動削除を待つというものです。削除領域が特定キー配下ということだけは確定していたので、一番手軽な方法であるという判断でした。これで相当なオブジェクト数を削除し、S3使用容量を大幅に削減できました。 しかしこのままでは結局時間稼ぎでしかないため、AWSの皆様や浜谷さんからのアドバイスを受け、INTELLIGENT_TIERINGの導入を行った次第です。 話は変わりますがわたしは前職、前々職で動画配信サービスのインフラを担当しており「頻繁にアクセスされる動画が存在し、その反面まったくアクセスされない動画がそれ以上に存在する」ということを肌感覚で知っていました。「おそらくBASEのような大小さまざまなショップへのリクエストも似たような形であろう」という点からINTELLIGENT_TIERINGの可能性を感じました。 その上で性能面で懸念があったため、INTELLIGENT_TIERINGそのもの検証とレスポンス速度の確認を行い、さらにAWSサポートより「性能差はない」「ただしオブジェクト監視の費用がかかる」という回答もいただいたことで導入を行った形です。 独自ドメインApp と Nginx について 独自ドメインApp HTTPS化対応期(2016〜2018) Certbotを試す 独自ドメインSSL基盤サーバのChef 独自ドメインSSL: ngx_mruby対応 独自ドメインSSLサーバのcore 独自ドメインSSL:の取得サーバのnginx 独自ドメインSSL:デプロイレシピ 独自ドメインSSL:rsyncサーバの実装 独自ドメインSSLサーバのchefレシピ 独自ドメインSSL CentOS7対応 / Core 独自ドメインSSL CentOS 7対応 / Rubyインストール 独自ドメインSSL CentOS7対応 / reverse-proxy対応 独自ドメインSSLのCentOS7化にむけて、coreの編集。 独自ドメインSSL CentOS7対応 / デプロイ global reverse proxyと独自ドメインSSLのwwwユーザのIDは同じでなければならないことをChefに記述する certbotのインストールをyumで yumでcertbotコマンドをインストールするようにした 独自ドメインSSL残課題 独自ドメインApps の証明書切れを事前に検知できるようにする Let's Encryptの活用により、オーナー様が持ち込んだ独自ドメイン名に対して、証明書を発行できるようになりました。もちろん証明書の発行だけでなくWebサーバで証明書を認識できなくてはなりません。その手のシステムを開発したのが先ほども登場した @srockstyle です。 詳しくは本ブログ内の以下エントリがわかりやすいかもしれません。 独自ドメインのショップでhttpsでアクセスできるようになりました - BASEプロダクトチームブログ 対応当時のリリースはこちらです。 「BASE」が独自ドメインのSSL証明書の無料発行・自動管理を開始 ‐常時SSLで安心安全なネットショップ運営を‐ | BASE, Inc. この機能がもしなかったと仮定した場合、「ショップ開設を行おう」「このまま引き続きBASEを使っていこう」というショップごとそれぞれの意思決定が、どれだけの数YesからNoになっていたことでしょうか。ショップにとって独自ドメイン名の持ち込みは、サービスにロックインしないための最後の砦とも言えるので、その手段を安全に提供できていることをわれわれはもっと誇っていいのかもしれません。 さらにはその誇りを実現してくれているのはLet's Encryptの存在であるという気持ちを、忘れてはいけません。スポンサーになろう。 Let's Encrypt 対応期(2019〜2020) [domainssl] Let'sEncrypt 2020.02.29 CAA Rechecking Bug [domainssl]2020.09末期限 / Let's Encrypt延命のために必要なこと Let's Encrypt 周りに関して、運用不要というわけではありません。小さな悩みごと、対応しなければならないことにいくつかぶち当たる場面がありました。 CAA Rechecking Bug 2020.02.29 CAA Rechecking Bug - Incidents - Let's Encrypt Community Support 認証局のルート証明書の切り替え問題 外部のブログ記事でいうと songmu さんのブログエントリがわかりやすいです Android7.1以前でLet's Encrypt証明書のサイトが見られなくなる | おそらくはそれさえも平凡な日々 Let's Encryptの証明書切替周りその後 | おそらくはそれさえも平凡な日々 このあたりは既に懐かしく思えますね。 CertbotからLegoへ(2021) [EOL][domainssl]certbot-autoが1.11.0で非推奨になる [domainssl]certbot->lego置き換えのリリース計画 先述した個別の対応とは別に、Certbotまわりのバージョン管理などで億劫に思えることが多くなりました。具体的にはCertbotとPythonのバージョンとの話題です。BASEではCentOSを利用している背景があり、Pythonのバージョンを云々するのがちょっとめんどうな点があります。 上記にいつまで悩まされるか、ということを損失と捉え、ここでLegoに乗り換えることにしました。 ここで誤算がありました。「Certbotはかなり親切にディレクトリを切ってくれるつくりだったんだな」というところです。このLet's Encryptを利用した独自ドメインAppのシステムは、Certbotのディレクトリ構成に強く依存しているつくりになっていました。 ですのでLego導入時にCertbotのディレクトリ構成を再現させる補助となるShell Scriptをあわせて配置して、Railsに実行させるようにするなどの工夫が必要となりました。 Nginxのアップデート(2020〜2022) IP個別に単位時間あたりのリクエスト数を制限する 1.15.x -> 1.19.x http_limit_req_module 導入時に limit_req_dry_run を利用したかったため nginx 1.19.6 -> 1.21.5 にアップデートするまでの道のり nginx-buildとngx_mrubyの対応のため 証明書が配置され、ショップの正面玄関として重要な存在となったNginxですが、現行のバージョンと乖離した状態になっていました。またそもそもの動機として limit_req_dry_run を採用したいためアップデートが必要となってきました。nginx-buildとngx_mruby、またpcre、OpenSSL、zlib、ngx_dynamic_upstreamとそれぞれのバージョンで整合性を持たないといけないため、buildを行っているchefレシピの修正を行いました。この修正で1.19.xおよびOpenSSLのバージョンを最新のものにアップデートすることができ、目的となる http_limit_req_module および limit_req_dry_run の導入に成功しました。 また1.19.6利用時にpcre問題が発生しました。こちらの catatsuy さんのエントリが問題発生当時の状況を把握する参考になります。 nginxとPCREについて 最終的にはわれわれはpcre2を採用する、つまりNginxのアップデートをし、CHANGES を睨んで確認事項を洗い出し必要なディレクティブやパラメータの変更を行うよう対応しました。 また副次的な恩恵として、OpenSSLアップデート対応をカジュアルに行えるようになったことがあげられるでしょう。 結びに 10年間のうち7年弱のIssuesを振り返ってみました。ここに書ききれなかった日々の小さな対応や、ログ基盤や新カートまわりの話題などもあったわけですが、SREの活動を振り返るには充分であろうと自負があります。 ここには見栄も背伸びもありませんので、読者のみなさんの「このあたりの施策が足りないんじゃないか」「俺だったらこうやってもっとうまくやったな」などの感想は妥当かもしれません。ですのでもしよかったらBASEで一緒に実現していただけると嬉しい気持ちです :-) <ホントダヨ A-1.BASE_SRE - BASE株式会社 A-1.BASE_SRE※マネージャー候補 - BASE株式会社 明日19日は @glassmonekey 、 @take61___0 のお二人のエントリです。 BASEアドベントカレンダー2022を引き続きお楽しみいただければ幸いです。 ほんとうに記事の書きやすさを優先してかなり恣意的に間引いているので、関連するIssuesは実際にもっとあります。ご了承を。 ↩ ちなみにこれが Issues ID 1 です。多忙な開発主要メンバーからデプロイ業務をうまくはがす必要があったそうです ↩
アバター
この記事は、 BASE Advent Calendar 2022 18日目の記事です。 今日担当するのはバックエンドエンジニアの cureseven です。 2022、チャレンジし続けたスクラム phpcon沖縄2022のスポンサーセッションで、「 Gather × Code With Me × ペアプロのお誘い で最高です 」という発表をさせていただきました。 本記事は後日談のような内容です。どのように開発を進めているのかの補足として発表資料を見ていただけると良いと思います。 また、アドベントカレンダー9日目では私たちのチームがどんな雰囲気のチームかを覗くことができます。合わせてご覧ください。 https://devblog.thebase.in/entry/2022/12/09/110000 さて、私のチームは、phpcon沖縄2022発表当時のプロジェクトを終え、新しい機能開発に着手し始めました。 今回のプロジェクトは開発規模も大きいため、以前とは違い2チーム合同でのプロジェクトになっています。 登壇時うまくいっていたことも2チーム合同となるとうまくいかないことも多く、その中でチャレンジしていることについて触れたいと思います。 2チーム合同になり問題になったこと コミュニケーションコストが増えた 1チームは5-6人で構成されているのですが、2チーム合同となるとAmazonでいうところの ピザ2枚ルール には当てはまらなくなってきたと感じました。人数としてはピザ2枚の範囲内かもしれませんが、開発してきた背景の違う2チームが合流したので人数関係なくコミュニケーションコストが発生するようになりました。 2チーム全体で合意・意思決定を行うことは、小さいチームより時間がかかります。さまざまな意見が出て良いこともある反面、スクラムのスピード感にはマッチしないと感じました。 作業内容が被り、コンフリクトが発生した 仕様が定まっていないところから始まったプロジェクトでした。その段階でリファインメントし、開発にちょっとずつ着手していこうという状態で、作業できる箇所が小さかったのでコードもストーリーも近しいものに着手することになってしまいました。作業を並列化するのも難しく、コードのコンフリクトも起こりました。 コーディングルールが2チーム間で異なり、レビューが前に進まなくなった これまで積んできた経験が異なる2チームが同時にレビューすることで、設計思想のすり合わせのコストがかかるようになりました。 工夫していること 私たちのスクラムは、1チームでのスクラムを無理やり拡張させたものではなく、2チーム合同でLarge-Scale Scrum(LeSS)だと改めて認識できました。大規模スクラムのエッセンスを取り入れながら、経験を元に作業効率を上げるための取り組み(プラクティス)を行っています。 チームごとに、全く違うテーマに取り組む 現状はプロジェクトのプロダクトバックログにラベリングし、各ラベリングされたセクションごとに作業チームが別れている状態です。 プロジェクトとして一番優先して作りたい機能はあるものの、複数チーム合同で着手すると時間がかかったという経験から、次の優先度のラベルの機能開発に着手することで全体としての作業効率が上がってきています。 お互いのチームを信頼して任せられるようになりました。 ラベリングの1つとして、フロントエンドが先行してUI実装していくものがあります。このおかげで、課題の発見を早めることができています。また、バックエンドが着手するタイミングで機能要件が明瞭な状態にしておくこともできます。 トラベラーやってみた LeSSのエッセンスとして、トラベラーというものがあります。 https://less.works/jp/less/framework/coordination-and-integration 開発経験・知識がある人がチームを跨いでアイテムに取り組んだり意見を言う役割を負う人のことです。 私は1スプリントだけトラベラーに挑戦してみたのですが、タスクの引き継ぎに有効でした。また、作業メンバーが両チーム奇数人だった場合、トラベラーを一人派遣することで偶数人ずつになりペアプロのレーンが増えると言う副作用も享受できました。 デイリースクラムでは、トラベラーを行っている期間自分のチームへのコミットが薄くなった場合、議論に参加しにくくなってしまいました。その時はトラベル先のチームのデイリーにのみ参加するのが良いかなと思いました。 今は、アプリケーションにおけるクラス設計の意思決定をする有志チームがあり、継続してトラベラーのような役割を果たしてくれています。 作業に集中できる時間を少しでも多くする 2チーム合同でプロジェクトを進めていくために、チーム合同での振り返りとトライを決める「オーバーオールレトロスペクティブ」、プロジェクトとして何を達成したいかをすり合わせる「オーバーオールプロダクトバックログリファインメント」が各スプリントにセットされていますが、エンジニアの参加者は各チームランダムな代表者数名としています。決まったことはデイリースクラムやslackで非同期に共有、気になったら閲覧できるようなミーティングの録画を共有しておくことで対応しています。 2チーム合同になったことで増えがちなミーティング時間も、慣れてきた段階で代表者制にすることで節約できるようになっていきました。 最後に 2022では、BASE全体としてスクラムの導入が積極的に行われていくようになってきました。 スクラムは、経験を大事にします。ナレッジを共有しながら、チームに合わせたスクラムの在り方を模索していきたいです。まだまだ生産性を上げていきたいので、デイリースクラムやレトロスペクティブで議論していきたいです。
アバター
この記事は BASE Advent Calendar 2022 の17日目の記事です はじめに こんにちは!Pay ID 決済 バックエンドエンジニアのzan( @zan__gi ) です。 今回は、BASEに入社して「Speak Openly」っていいよね!と思った経験を綴ります。 BASEでの働き方や開発組織の雰囲気を少しでも伝えることができたら幸いです! そもそも Speak Openly とは Speak Openly とは BASEのプロダクト作りと3つの行動指針のひとつで、 「 素直に話すこと。より良い結論を得るために、その場で意思を伝えよう。 」です! BASE株式会社 会社紹介資料 も見ていただくとよりわかりやすいです。 Speak Openly の良いところ3選 現在携わっているプロジェクトでは実はフロントエンドを担当しています。 (現在進行中なので、プロジェクトの詳細は割愛させてください!) BASEに入社してプロダクト開発(しかも入社後初プロジェクト&フロントエンド!)を通じて 「Speak Openly」っていいよね!と思ったので、今回はその中で3選、紹介します! #ダサいぞ Speak Openly なSlackチャンネルのひとつとして、#ダサいぞ があります。 #ダサいぞ は「ユーザーとの接点全てにおいて、ダサいところを報告して直していく!Speak Openly!」をトピックとしたチャンネルです。 フロントエンド開発への恩恵として、ダサいパターンが蓄積されているので、センスを磨けた気がします。 また、実際に「ダサいぞ」といっているところを見ると、「私もいいプロダクトを作るために素直に話そう!」と前向きになることができます。 (↓2019年から多くの「ダサいぞ」が報告され、改善されている。) 暗黙知に触れやすい 開発以外にも共通して言えることですが、プロダクト開発を進めていると、暗黙知を知ることができると嬉しい場合があると思います。 BASEではpublicなSlackチャンネルが多く、Speak Openlyにコミュニケーションしているので、過去のプロジェクトのチャンネルを探ることで暗黙知に触れることができ、プロダクト開発にも活かしやすいと感じています。 また、プロジェクト参画者の発言を追うこともできるので、一方的に既視感を得ることができ、初めてコミュニケーションを取る際の心理的なハードルも少し下がります。 (↓privateなコミュニケーションチャネルばかりだと、コードやドキュメント等の成果物以外の情報を辿りにくい) 心理的安全性 現在、PdM、デザイナーやエンジニアと共にフロントエンド開発を一緒に進めていますが、 議論やレビューなどの際、「Speak Openly」という共通の行動指針は、 コミュニケーション相手も「Speak Openly」で行動してくる、という心構えでいれるので、ある種の心理的な安心感があります。(もし議論が白熱してヘコんでも、そこはBe Hopefulな気持ちで!) また、バックエンドを担当してきて、コードの美しさ、みたいなところの議論が多かったですが、 フロントエンドでUI、UXがイケてない、みたいな議論や検討ができているのは新鮮です。 文化的行動様式に近い話ですが、組織文化に裏打ちされたコミュニケーション基盤はやはり強い、と実感しています。 (↓多くの人が Speak Openly な行動をしているので、自分も Speak Openly になりやすい) 最後に 冒頭にも書きましたが「Speak Openly」っていいよね!と思った経験でした! シンプルな哲学と行動指針なので、組織文化としてしっかり根付いていて、プロダクト作りに活かせていると感じています。 さて、明日は @chihiro さんの記事が公開予定です!お楽しみに!
アバター
はじめに この記事は BASE Advent Calendar 2022 の15日目の記事です。 こんにちは!船坂( @takumi_funasaka )です。BASEでプロダクトマネージャーをやっています。 先日、所属しているプロジェクトチームで「チームの能力を自己評価し、チームとしての今後の成長方針を決める」ワークショップをやってみました。 これが結構良かったので、ご紹介させてください。 ざっと目を通していただくと、チームの課題を抽出したり、いいチームのどこがいいのかを知るためのヒントになるかもしれません。 チームがいい感じ、な気がする 最近、自分が所属しているプロジェクトチームがとてもいい感じだなぁと思っています。 やるぞ!感もあるし、アウトプットも良い。苦難や衝突もたくさんありますが、それを踏まえても、良いチームになってきていると感じていました。 ただ、 チームの何がいい感じなのか、よく分からない のです。 現在、BASEではプロダクト領域ごとに組織をわけており、僕たちのチームもプロジェクトが終わったらすぐ解散ではなく、しばらく続いていく予定となっています。 そのため、現状の理解のままではなく、チームがいいと感じる要因を明らかにし、同時に課題も認識することで、中長期的なチームの成長方針をたてたいと考えました。 チームについて考える まずは、チームについて疑問があったので、調べながら自分の一旦の考えをまとめてみました。 「チームってなんなんだろうか。人の集まり?」 → チームとは、 ただ人が集まっただけではなく、目的を達成するために密に協働する人の集まり である 「じゃあいいチームってどういうチームだろう?」 → いいチームとは、 チームの存在理由である「成果」を上げることができ、そして評価されるようなチーム である 「いいチームかどうかを知るには、どうしたらいいんだろう?」 → いいチームにはいいチームワークが存在している。チームワーク能力を測ることがチームの機能性を知ることに繋がる。 このあたりの前提に立つために、いくつか研究を参考にさせていただきました。(後述) チームワークを評価するワークショップを実施してみた さて、ようやく本題ですが、自分たちがどういうチームなのかを明らかにするため、チームワークの機能性を評価するワークショップを設計してみました。 ワークショップの流れ ワークショップはチームのメンバー全員で行いました。 僕たちの場合は、 プロダクトマネージャー×1 デザイナー ×1 エンジニア ×5 QA ×1 の計8人で実施しています。 ワークショップの流れは以下になります。 チームワークについてみんなで学ぶ 事前に用意したチームワークの要素※1ごとに、その要素に関連する具体的な行動やコミュニケーション、できていないことなどをPositive / Negativeで振り分けて書き出す 全てのチームワーク要素について書き出し、全員で読む 各要素について、今の自分達のチームは何点になるか、1〜5点で投票する 意見が割れたところに関して、メンバー同士で意見交換をする 議論後、チームとしてのスコアを決定 チームとして不足している能力や今後獲得していきたい能力について、話し合う ※① チームワークの要素として、こちらの論文( 山口裕幸(2007)、チーム・コンピテンシーと個人のチームワーク能力 )に記載されていたもの利用させていただきました。 結果:チームの今を知る やってみた結果、僕たちのチームのスコアは下記のようになりました。(各5点満点。各要素の詳細な解説は省きますが、後述する資料を是非ご覧になっていただければと思います。) チーム指向性 職務指向性 4 対人指向性 5 チーム・リーダーシップ 適切な指示 3 対人的配慮 3.5 チームプロセス モニタリングと相互調整 4 職務の分割と明確化 3 フィードバック 4 知識と情報の共有 3 このように スコアを定量化・可視化したことで、チームについて俯瞰することが容易になり、メンバー同士の議論もしやすくなった と感じました。 メンバーの肌感ともほぼ一致した数値感になり、非常に参考になりました。 ディスカッション:チームについて話し合う このスコアを元に、更にチームで感想や今後チームとして獲得していきたい能力について、ディスカッションを行いました。 結果を見ながら、僕たちのチームは今後の方針として チーム・リーダーシップに課題があるので、今後注力して伸ばしていく チーム指向性が高いことを今後も大事にしていく チームプロセスもまだ改善途上であり、継続的に向上させていく ということをメンバーで合意できました。 これはとても大きな意味があったと感じています。 ワークショップの感想 実感としては非常によい機会になったなと思っています。 個人的に感じたことや、メンバーからあがっていた感想・意見を紹介します。 チーム指向性が比較的高いのはとても良いと感じていて、自信になった。普段から目的の意識付けやそこにコミットする姿勢を全員で共有できていることを再実感できた。 リーダーシップを取るということに対して、メンバーが課題に感じていることが明らかになった。現状は満点でなくても、全員で伸ばしていくという意識付けができたことはとても良かったと思っており、これが今回のワークショップの一番の成果だと感じている。 チームワークというチームを主語にした能力をトピックとして取り扱ったので、個人の能力に言及することなく、課題について議論できた。心理的安全性を保ちながら、オープンに今後について話せた実感がある。 「適切な指示」について考える中で、タスクを全部自分で巻きとろうとしてしまう癖に気づいた。これからは適切にメンバーを頼り、チームとしてもっと効率的・持続的にタスクをこなしていけるようにしたいと思った 特定のメンバーがチームワークという点で大きな役割を果たしているということが明示的になったのが良かった。課題ではあるが、認識できたので、他のメンバーも今後意識的に経験を積みながらチームを改善していけると思う。 チーム力は悪くはないことがわかったが、個人でみると偏りがあることも明らかになった。これからは偏りを分散させることを意識しながら、チームのいいところを高めていきたい。 ⁠ワークショップ後のFigjam(雰囲気だけ) 最後に 今回はふわっとした「チームがなんかいい感じ」の要因を明らかにするために、チームワークの機能性を知るワークショップを実施してみました。 チームワークの機能性をスコアとしてプロットしたことは、メンバー全員で今を見つめ、今後進むべき方向性のすり合わせをすることを容易にした感覚があり、重要なキーだったと思っています。 また、実は僕たちのチームは来年から少し構成が変わる予定があったため、状況が変わってもパフォーマンスを出し続けていくために、やるべきことを考えたいという目的もありました。 これは、ワークショップのstep2において具体的なコミュニケーションをベースに書き出す設計にしていたことで、チーム構成の変動後、どのようにチームワークが変わりうるかを予想することもでき、良かったと思っています。 さて、明日は @gimupop の記事が公開予定です!お楽しみに! Appendix: 参考にした情報と、学んだこと おまけとして、今回このワークショップを設計するにあたって調べた情報と、学んだことを書いておこうと思います。 Google re:Work『効果的なチームとは何か』 学んだこと: "チーム: メンバーは相互に強く依存しながら、特定のプロジェクトを遂行するために、作業内容を計画し、問題を解決し、意思決定を下し、進捗状況を確認します。チームのメンバーは、作業を行うために互いを必要とします。" 効果的なチームに必要な要素は5つ 心理的安全性 相互信頼 構造と明確さ 仕事の意味 インパクト チームの効果性には「誰がチームのメンバーであるか」よりも「チームがどのように協力しているか」のほうが重要である チームワークの教科書 学んだこと: チームの成果を左右するコミュニケーションの要素は コミュニケーションの「熱量」 チーム全体への「関与」 外の世界へと向かう「探索」 チームメンバー同士が長い期間固定されていると、パフォーマンスが向上する しかし、同質化が進み、新たな学習を妨げることがある チームに『異端者』がいると、議論が活発化し、パフォーマンスが向上する 他にも色々学べました 山口裕幸(2007)、チーム・コンピテンシーと個人のチームワーク能力 学んだこと: チームワークの要素とモデル(ワークショップで利用) チームワークの測定項目群(ワークショップで利用) チームワークは個人のチームワーク能力にも影響を受けるが、メンバー同士の相互作用により、個々の能力を超える大きな影響を受けることが少なからずある
アバター
はじめに この記事は BASE Advent Calendar 2022 の14日目の記事です こんにちは。BASEの資金調達サービス「YELL BANK」チームでPMM(プロダクト・マーケティング・マネージャー)を担当している神納(@yuni)です。 9月に入社をして3ヶ月間、中からプロダクトを見てみて、ぜひ皆さんにも知ってもらいたいなと思ったYELL BANKの推しポイントをご紹介させてください。 そもそも、YELL BANKってなに? YELL BANK(エールバンク)とは、BASE加盟店が利用できる「資金調達サービス」のことです。一言で表してしまうと 「未来の売上を前借りしているようなイメージ」 です。 まとめて仕入れを行う時や、新商品の開発、機材の導入などで資金繰りに不安を感じた際にご利用いただくことを想定して、サービスを提供しています。 現在は、BASE加盟店の一部のショップオーナーさまに限定してご利用いただけるサービスで、 調達できる金額は、BASEの売上実績に紐づいており、ショップによって金額規模も変わってきます。 YELL BANKの知ってほしいところ3選✨ 一般的な金融与信とは切り離された「独自の与信審査」 「すぐに欲しい」に応えた即日性 売れた時だけ支払えるから、売上が安定していなくてもリスクが低い それぞれ順にご説明します。 1. 一般的な金融与信とは切り離された「独自の与信審査」 そもそも与信とは、取引相手のことを信用して、資金などを貸与することです。 一般的な金融与信は、利用者の「返済能力(Capacity)」「返済資質(Character)」「返済担保(Capital)」で評価されています。 投資会社側も、融資先が倒産などの理由で返済が出来ない状態(=貸倒)になってしまうと、企業にとっての損失になるため、 安心安全に取引ができる相手なのかを判断する ために、事前に審査を行います。これが「与信審査」です。 金融機関の融資以外でも、クレジットカードを作成するときなどに、耳にしたことがある言葉かなと思います。 金融機関の与信審査であれば、年収、勤務情報、金融資産、借入、住居などの情報を元に評価がされます。 一般的には、窓口に出向きヒアリングが必要だったり、本人確認書類や決算書、事業計画書などの書類の提出が必要だったりします。 YELL BANKも金融サービスになるので、同様の与信審査は必要です。 ただ、YELL BANKで行われる与信審査はたった一つ 「BASEでの運営実績」のみ です。書類提出などの必要は一切なく、 今までのBASEショップ運営の頑張りを評価 します。 このようにYELL BANKは独自の与信審査をしているため、既に複数の借入をしていて追加での借入が難しい方や、個人事業主であるため金融機関での融資に通らない方でもご利用いただけます。 2. 「すぐに欲しい」に応えた即日性 YELL BANKでは「BASEショップの運営状況」をシステム上で常に評価しているので、「今申し込みたい!」と思ったタイミングですぐに調達ができます。予測不能なアクシデントが起きた場合でも、即日対応できるのは強みの一つです。 また、クレジットカードやQRコード決済だと、現金着金が翌月に持ち越してしまうという、キャッシュレス化が進むことでの弊害もあります。売上は安定しているものの、一時的にキャッシュフローに詰まってしまったなという場合でも、YELL BANKで予備資金を作っておくという対処もできます。 利用したい時にすぐ取り出せる自分のお財布のように、YELL BANKを利用してもらえたらいいな と思っています。 3. 売れた時だけ支払えるから、売上が安定していなくてもリスクが低い 金融機関などでは、毎月固定金額の支払いが必要な場合が多いのですが、YELL BANKはBASEショップで商品が売れたら、その売上からn%支払う、というサービススキームです。売上が落ち込む月でも、収入より支出が大きくなる心配はないので安心設計です。 また、支払い期日がないので、「長期的に挑戦したいことがあるから、まとまった資金が必要。だけど、いつ売れるかわからない...」場合でもご利用いただけるので、新しいことに挑戦したいタイミングで活用しやすいサービスかと思います。 おわりに 今回は、ぜひ知って欲しいYELL BANKのサービスのことをシェアさせていただきました。 YELL BANKチームでは、どうやったらショップ運営を続ける中で感じる資金課題や、不安をいち早く解決できるかを考えて、日々機能改善に関する対応を行っています。 もっといいプロダクト、体験を提供できるように尽力しておりますので、今後のYELL BANKのアップデートを楽しみにしていただけると嬉しいです。 また、YELL BANKでは一緒にプロダクトを盛り上げてくださる方を積極採用中です!カジュアル面談も対応しているので、お気軽にご連絡ください。 採用情報は こちら 明日は @funasaka @zan の記事が公開予定です、ぜひご覧ください。
アバター
はじめに この記事は BASE Advent Calendar 2022 の13日目の記事です。 はじめまして、BASEでエンジニアリングマネージャーをしている渋谷と申します。 今回は、textlintを導入したところレビュー工数が90%削減できたので技術的にどのようなアプローチをしたかについて紹介させていただきます。 背景 弊社にはUXライターが在籍しており、BASEプロダクト全般におけるテキストの品質を向上させる、UXライティングを行っています。 テキスト版デザインシステムとして「運用ガイドライン」「用語リスト」を作成し、あらゆるタッチポイントにおいて、日々テキストコミュニケーションの最適化を図っています。 UXライターが文言を作成するケースもありますが、UXライターでない方が文言を作成するケースが多く、その場合UXライターがレビューすることで品質を担保しています。 そのような取り組みの中で見えてきた2つの課題がありました。 ことばのトンマナ(トーン&マナー:デザインやスタイルに一貫性を持たせること)をひたすら磨く作業が、現状のテキストデザイン作業の大半を占めていること 運用ガイドラインがあっても、品質の担保は、最終的にはどうしても属人的にならざるを得ないこと つまり、表面的にはトンマナが統一されていることによって、一定のテキスト品質は担保されている一方、UXライティングの本来の役割である「体験をデザインすること」という本質に時間を割けていなかったのです。 そこでtextlintを導入し、トンマナを機械的に統一させようという試みがスタートしました。 (具体的な背景についてはUXライターの藤井が執筆した こちらの記事 に詳しく記載されているので、ぜひ御覧ください) textlintとは textlint は JSer.info などでおなじみの azuさん が開発されているOSSで、テキストファイルやMarkdownのための文章校正ツールです。 .textlintrcにルールを記述するとそのルールに従い校正が実行されます。 アプローチについて 大きく分けて2つのことを行いました。 textlintのためのルール設定 誰でも使える環境の構築 textlintのためのルール設定 ルール設定までの経緯について UXライターはもちろん非エンジニアであり、textlintの使い方に慣れていなかったため、エンジニアである私がサポートしながら進めることになりました。 設定したい校正ルールをUXライターの方にリスト化してもらい、そのリストに対してエンジニアの私がどのtextlintルールを適用できるか一つ一つ検討し、今回導入するパッケージを決定していきました。 設定したルールについて 弊社では下記パッケージを導入しています。 textlint-rule-preset-ja-technical-writing textlint-rule-period-in-list-item textlint-rule-preset-JTF-style textlint-rule-proofdict 特に今回役立ったのはproofdictです。 proofdictは表記揺れやtypoなどを検知するための辞書管理ツールです。 弊社では単語の表記揺れ対策はもちろん、 下記のようなBASE独自ルールについてもproofdictを活用しました。 ()かっこは半角を使用しない ・・・は……(全角三点リーダを2回繰り返す)にする 金額表記は¥(全角)+半角スペースで表記する 誰でも使える環境の構築 textlintは文章校正がメインの機能になっており、利用する場合にどのエディタを使うかは利用者側に委ねられています。エンジニアの方はローカル環境にtextlintを npm install した上で、VSCodeなどのエディタ経由で利用することが多いと思います。しかし、今回の要件では非エンジニアの方がtextlintを利用するため、ローカル環境の構築はハードルが高く現実的ではありません。 そこで textlint/editor です。 chrome拡張を使ってブラウザ上で文章校正を行うことができます。独自設定をインストールすることで独自の.textlintrcを反映させることもできます。 その結果わずか2ステップで導入することができました。 ステップ1:chrome拡張のインストール ステップ2:BASE独自設定のインストール ただし、このchrome拡張は2022年11月時点でtextareaタグのみに反応する仕様となっており、弊社で利用しているドキュメントツールであるKibelaやGoogleDocsでは利用することができませんでした。 そこで、textareaを有しテキスト内容をローカルストレージに自動保存する簡易なWebエディタを自作しそちらを使ってもらう運用にしました。 (この記事もそのエディタを利用して執筆しています) 導入した結果 UXライターの方いわく、「レビュー前のテキストの品質は、『トンマナ』という文脈においてはとんでもなく担保された! トンマナレビュー工数、体感で約90%削減!」とのことでした。 本来の役割である「体験をデザインすること」という本質に時間を割けるようになったそうです。 私としてもそのような結果は大変うれしく思いますし、なによりazuさんには感謝の気持ちでいっぱいです。 おわりに 本記事では、弊社でtextlintをどのように運用しているかについて説明しました。読んでいただいた方の助けに少しでもなれば幸いです。 明日はmatzzさん、yuniさんの記事が公開予定です、ぜひご覧ください。
アバター
初めに BASEアドベントカレンダーの 13日目です。 こちらの記事では、BASEの開発組織の環境がこれから成長していく若手エンジニアにとってとてもいい環境であることを身をもって体感したため、レポさせていただきます! 自己紹介 こんにちは。Owners Marketing所属の若菜と申します。 普段は、新規ショップオーナーの方によりよくBASEを使ってもらえるための機能改善や、 もっとたくさんの人にBASEを使ってもらえるようにするための機能提供に取り組んでいます。 対象の読者と伝えたいこと こちらの記事は、以下に当てはまる人に特にご覧いただきたい記事になっています。 エンジニアとしてのキャリアをこれからどう伸ばしていこうか迷っている人 また、この記事においてお伝えしたいことは以下です。 BASEが若手エンジニアにとって非常に良い成長環境であると感じている その理由・背景などを実際の出来事ベースにご紹介 入社して1年が経過する私が、この1年で実際にエンジニアとしてBASEで働きながら感じた点を、 仕事面 と 会社生活面 に分けて、お伝えさせていただきたいと思います。 仕事面 🙋🏻プロジェクトの開発責任者として、業界初の機能をリリースした BASE で使用できる配送方法の一つである、 かんたん発送App にて、匿名配送機能を提供するというプロジェクトの開発主担当を担いました。 (詳細は こちら ) BASEは個人の利用であれば、 住所・電話番号を非公開 にしてネットショップをオープンすることができるため、匿名配送機能が実現されれば業界初の 匿名でネットショップを開き、売ることができる こととなり、社内外問わずインパクトの強いプロジェクトでした。 自身の成長につながった点 このプロジェクトを経て、特に以下の2つのことが成長に繋がったと感じています。 開発のいちメンバーとしてだけで参画していたら得られなかったような経験を積むことができ、大変ありがたく思っています。 1️⃣ 1つ目:「確実なプロジェクトの進め方・不確実性をいかに減らすか」という観点が身についた 本プロジェクトを進めるにあたり、経験豊富なマネージャーに進め方を相談しました。 そこで以下のようなアドバイスをいただき、それらを実践に移すことで安心しながらプロジェクト進行を行うことができました。 「タイムラインを管理するガントチャートを用いてプロジェクトを管理すること」 「リスク管理を先手先手で進めること」 中でも リスク管理 は私がこれまで仕事を進める上であまり意識できていなかった点でした。 プロジェクトの初期段階で、今後リリースまでに発生しうる様々なリスクをブレスト形式で洗い出し、それをシートにして毎週の定例などで定期的にウォッチしていきます。 詳細は、以下の記事をご覧ください。 不確実性に立ち向かう一つのTips〜リスク管理に取り組んだ話〜 決して手元の開発だけ行っていればいいわけではなく、自分の開発タスクをこなしながらもプロジェクト全体のリスク回避、安全進行を意識していく。 以降、私の日々の業務においても影響を大きく与え続けている意識改革だったと実感しています。 2️⃣ 2つ目:機能仕様の隅々まで把握し、成果物すべてに責任を持つ意識が身についた 今回、新たに匿名配送を実装した「かんたん発送Apps」は、 2018年から提供を開始している 機能です。 当時開発を担当していたメンバーはすでに退社してしまったりと、BASE内でも機能仕様に精通している人が少ない状況でした。 そのため、 自らがこの機能の 社内で一番の仕様理解者になる 勢いでソースコードや社内ドキュメントなど使えるもの全てを使って調べ上げていき、既存仕様と追加仕様の把握をリードしました。 本機能リリース後も、別プロジェクトに従事する傍ら、かんたん発送Appsにおける社内の調査を積極的に引き受けるなどして、知見を社内に還元できるようにしています。 会社生活面 🙋🏻チャレンジ大歓迎で、成長を一緒に考えてくれる組織 会社や開発組織全体で「 チャレンジを歓迎する 」雰囲気があると感じています。 BASEの行動指針にも掲げられている「 Be Hopeful 」が手伝う形で、チャレンジ歓迎な文化醸成に作用していると思っています。 Be Hopeful 楽観的でいること。 期待した未来は実現すると信じて、勇気ある選択をしよう。 BASEのSlackワークスペースを見ていると、社内の至る所で上記のBe Hopefulを感じる場面が多く、開発組織に限らず全社的に挑戦が歓迎される雰囲気を感じます。 その中でも、私がBASEで働く上で特に感じる、 成長できる環境 について触れさせていただきます。 🏁 目標を明確に設定し、伴走してくれる BASE社内では、四半期ごとにOKRフレームワークを用いて目標設定を行います。 その際、ストレッチの効いたチャレンジングな目標設定を行うことも可能であったり、担当マネージャーが目標設定の壁打ちをさせてくれたり、定期的な1on1で進捗の相談相手になってくれます。 よく、成長していく上で「コンフォートゾーン・ラーニングゾーン・パニックゾーン」3つのゾーンが重要と言われますが、BASEで働いている中で常に 最も成長しやすいと言われる「ラーニングゾーン」 にいられていると思っています。 エンジニアとしてキャリア形成を考えない日はありません。 私は仕事で自分のできる範囲のことしか行わないコンフォートゾーンで停滞していたことに思い悩み、BASEへ転職した背景もあるため日々の業務をこなしながら ラーニングゾーンに居られること が個人的にとてもありがたいと思っています。 🏔"越境"を推奨し、チャレンジを歓迎してくれる 日々業務に携わっていると、業務ドメインや技術ドメインで担当領域などができていくと思いますが、それらを踏まえてBASEの開発組織では「自分の担当領域の枠を越えて活躍する人」「チャレンジする人」が多いように感じます。 以前私も、日頃はサーバーサイドエンジニアでありながらフロントエンドの開発・リリースに携わり、記事も執筆させていただきました。 サーバーサイドエンジニアがフロントエンドに挑戦して最高の経験になった話 私自身、上記の経験を経てさらに日頃の業務内でのチャレンジングなことへの敷居が下がったこともあり、 チャレンジを行うことで次のチャレンジがしやすくなる好循環 を明確に実感しました。 BASEに入社する前の段階では、上記のようなテックブログや今回のようなアドベントカレンダーの執筆も気が引けてしまい「自分は投稿しない(できない)だろうな...」と思ってしまっていたので、こちらは 明確なマインドの向上ができた と思っています。 ✍️ まとめ 私がBASEに入社して成長しやすい環境と感じた理由をお伝えさせていただきました。 日々の業務をこなすことも大事ですが、それと同じくらい 自身の成長を実感できること も大事だと思っています。 何より、成長を実感しながら毎日の仕事をこなせることがシンプルに仕事の楽しさ・充実度にも直結しています。 エンジニアとして働いて数年が経ちますが、この一年が間違いなく 今までのエンジニア人生で一番充実している と自信を持って言えます。 読者の方の中に、エンジニアキャリアのこれからが不安な方、迷っている方、チャレンジしていきたい方などいらしたら、カジュアル面談なども実施していますのでぜひ一度ご連絡ください! 明日はmatzzさんとyuniさんの記事です!お楽しみに!
アバター
はじめに 本記事は BASE アドベントカレンダー 2022 の11日目の記事です。 はじめまして。CSEグループのエンジニアの泉原と申します。 BASEのCSEグループでは社内業務改善や内部統制の整備など幅広い業務を対応しています。 CSEグループについてはこちらをご覧ください。 devblog.thebase.in 今回は、BASEにおける月初処理の概要とreportシステムの自動化、業務フローの見直しなどの業務改善についてご紹介します。 BASEにおける月初処理・reportシステムとは 月初処理 BASEではJ-SOX対応の一環として、 BASEショップの売上金と決済サービス側の入金データ BASEショップの売上金とBASE側の決済データ BASE側の決済データと決済サービス側の入金データ 決済サービス側の入金データと実際の入金額 これら4点の整合性が取れていることを確認することで財務報告上の信頼性を担保しています。 月初処理は月次でこれらの整合性が取れていることの確認を行うことを指しています。 reportシステム CSEグループでは上記の月初処理を行うにあたりreportシステムと呼ばれるレポーティングシステムを構築しており、決済サービス側の入金データの取得やBASE上の決済データとの突合(差異調査)を行なっています。 reportシステムの詳細についてはこちらをご覧ください。 devblog.thebase.in これまでの月初処理の課題 システムの実行手順が複雑 reportシステムではBASEのデータ集計やレポーティングを行い、経理側へ売上データを連携しています。 ただし、最終的に経理側へ必要なデータを受け渡しするまでに、以下のような工程で手動でコマンド実行したりデータを取り込んだりする必要があり、作業者の慣れが必要となっていました。 また、決済によってはreportシステムのDBに決済データが取り込まれるまでにタイムラグがあるため、売上レポートやデータの突合の際に作業者が手動で日付のオプションを指定してPythonコマンドを実行する必要がありました。 こういった手動でのコマンド実行の際に人的ミスが発生する可能性も否めませんでした。 差異調査が複雑になることがある 差異調査とは 月次処理では決済システム側の決済データとBASEの決済データの整合性を確認するために、それぞれの決済データを突合して差異がないかを確認しています。これを差異調査と呼んでいます。 どのような時に差異が発生するか 差異は以下のような条件で発生することがあります。 BASEや決済システム側の不具合や特殊な処理による差異 不具合の解消などに伴う返金処理で発生する差異 決済システムにトランザクションが渡るまでのタイムラグによる差異 これらの差異は毎月発生する可能性があり、CSE内で事前に把握できていない差異があった場合、差異の原因の調査に時間がかかることがありました。 どのような改善を行ったか システムの実行自動化 各決済システムから決済データを取得する箇所に関しては、puppeteerを使ったブラウザ操作で自動化されていましたが、一部の決済に関しては管理画面にログインしてデータをダウンロードしDBにデータを取り込む方式をとっていたため、まずはこちらを自動化できるよう対応を進めました。 また、売上レポートの取得や決済差異の抽出、共有フォルダへの配置など手動で実行していた一連の処理を1つのStepFunctionsにまとめたことで、手動での作業をなくしワンクリックで処理できるようにしました。 差異調査の改善 調査フローの整備 決済の差異が発生するパターンにはある程度決まったパターンがあったため、差異の調査方法をフローに起こし、CSE内で誰でも調査が進められるように対応しました。 また、発生した差異の内、月を跨いで対応が必要なものに関しては、別途シートを作成して対応状況を追える状態にしたことで差異を見失わない体制を作っています。 月初の確認会 毎月差異の確認用のslackチャンネルを作成し、差異として抽出されそうな決済を事前にCSE内で共有しておくことにしました。月末には確認会を設けてCSE内で再度確認することで、差異調査のヒントが得られ調査時間の短縮に繋がりました。 結果 これまで月初処理の際には売上レポートの受け渡しと差異調査を含めて2営業日程度要していました。また、差異調査が複雑になり、CSE総出で時間をかけて調査することもしばしばありました。 改善後は売上レポートの受け渡しは1時間程度、差異調査を含めても半日程度で完結しており、経理側への連携にかかる時間が大幅に短縮されました。また、データを早く連携できるようになったことで、経理側の月初作業も1営業日程度短縮し、決算スケジュール上余裕をもって取り組むことができるようになっています。 最後に 今回の月初処理の改善に関してはCSEグループ内の業務改善でしたが、実際に業務を通じて課題が見えてくることを改めて実感しました。他の業務改善の際にもまずは一度業務を体験して理解することから始めてみたいと思います。 明日は@naoki.munechikaさんと@yuniさんの記事が公開予定です、ぜひご覧ください。
アバター
この記事は BASE アドベントカレンダー 2022 の 10 日目の記事です。 はじめに 初めまして、BASE のバックエンドエンジニアの shiiyan と申します。この記事では、ファットな注文検索モデルをリファクタしたことの経緯と感想について紹介します。 注文検索モデルをリファクタする理由 古典的な MVC モデルでは、スキニーコントローラー・ファットモデル( Skinny Controller, Fat Model )の考え方があるゆえに、プロダクトの成長と共に、モデルが肥大化していくことは多々あります。 BASE において、注文モデルと注文検索モデルはこの流れから逃れられませんでした。2022 年初めの時点では、注文検索を担当するモデルクラスは 1 ファイル 3000 行弱の規模に肥大化しています。こういったモデルクラスでは、コード自体が読みづらいだけでなく、機能改修時に影響範囲が読みにくく、メンテコストが高いという課題がありました。 2021 年 12 月から 2022 年 3 月まで、私は注文管理改善プロジェクトに参加していました。このプロジェクトではボトルネックを特定し、注文検索のパフォーマンス改善を目的としていました。ボトルネックを特定するために、まず処理の流れを理解する必要があり、そして、工数の見積りを出すために、注文検索処理を修正した場合の影響範囲を調査する必要がありました。こういった背景で、改修する前に、まず既存コードが分かりづらいという課題を解消することに合理性を感じ、プロジェクト内でリファクタリングの意思決定を行いました。 リファクタリングの意思決定 今年 3 月ごろに、注文検索周りの処理をリファクタすることについて、担当 PM と合意ができました。リファクタを進めるために、以下の前提があります。 進行中プロジェクトの進捗に影響しないこと 優先度が高いプロジェクトができた場合に、いつでもリファクタリングから切り替えられること これらの前提を満たすために、以下のようなリファクタの進め方を計画しました。 ボトムアップ方式 テストファースト 毎朝 1 時間のペアプロ ボトムアップ方式というのは、注文検索の既存処理を俯瞰してリファクタリング方針を決め、その後に順序的に進むことではなく、まずは変数名や関数名など些細なところからリファクタリングをし、少しずつ範囲を拡大していく方式です。この方式をとる理由は、条件が複雑な注文検索処理の全体を俯瞰し短い時間の中でリファクタリング方針を決めることが難しいと判断したためです。 テストファーストというのは、リファクタ対象のクラスやそのクラスの上位クラスに対してまずテストを追加し、リファクタをしても既存処理がデグレていないことを担保することです。これは、デバッグ時の生産性を高めることとリリース時のリグレッションテストのコスト削減を図ろうとしています。 毎朝 1 時間のペアプロをとる理由は、日中のプロジェクトの進捗に影響を出したくない、また、ペアプロすることにより、リファクタが目指す良いコードの基準を合わせたかったためです。 注文検索モデルの課題点 リファクタする前の注文検索モデルには以下の課題点がありました。 コーディングスタイルが決まった前に実装したため、変数名と関数名にスネークケースとキャメルケースが混在していた 同じ変数名で再代入を重ね、変数の値を追うことが難しかった 200 行を超える関数が複数存在し、関数名も自明ではなかった 注文検索用のモデルだが、クラス名は注文モデルと区別ができなかった 複雑な検索条件の分岐を全て 1 箇所で対応したため、検索クエリを構築する処理が複雑化していた リファクタリングのやり方 リファクタリングの手法や基準はおもに Martin Fowler さんの『 リファクタリング 既存のコードを安全に改善する(第 2 版) 』を参考にしました。これらの手法を PhpStorm という IDE の機能やプラグインと一緒に使うと効率よくリファクタリングを進められます。今回の注文検索モデルのリファクタリングで頻繁に利用したリファクタ手法をいくつか紹介します。 変数名や関数名をキャメルケースにする BASE のコーディングスタイルを基準に、変数名と関数名をキャメルケースに統一します。PhpStorm デフォルト機能で Toggle case というものがありますが、変更したいケースに一発で変えられるようにしたいため、 String Manipulation というプラグインをインストールしています。直前に変更したケースを記憶しているので、複数箇所連続でスネークケースからキャメルケースに変換する時に重宝しています。 変数の抽出と変数のインライン化 同じ変数名で再代入を重ね、変数の値を追うことが難しかったの課題を解消するために、変数の抽出と変数のインライン化を適用します。その時に、利用されるのが PhpStorm のリファクタ機能です。リファクタ対象を選択して、右クリックのメニューで Refactor | Introduce Variable を選ぶと変数の抽出ができます。 Refactor | Inline を選ぶとインライン化ができます。 PhpStorm のリファクタ機能では以下の 4 パターンの変数抽出に対応しております。 ローカル変数 コンスタント フィールド変数 パラメーター変数 関数の抽出と関数のインライン化 200 行を超える関数が複数存在し、関数名も自明ではなかった課題を解消するために、処理の意図が伝わるまでに関数の抽出とインライン化を繰り返しました。関数の抽出はを Refactor | Extract Method 利用し、インライン化は Refactor | Inline を利用します。Extract Method は関数の抽出後、いい感じの関数名を提示してくれるだけでなく、複数箇所で同じ処理が書かれている場合に、全て対応してくれるのでとても便利です。 クラス名、関数名、変数名の変更 注文検索用のモデルだが、クラス名は注文モデルと区別ができなかった課題を解消するために、クラス名を OrderSearcher に変更しました。 Refactor | Rename を利用します。クラス名を変更する時に 1 つ注意点があります。クラスを変更した時に、そのテストクラスの名前は変更されないことです。例えば、 OrderSearcher を NewOrderSearcher に名前を変えても、 OrderSearcherTest の名前はそのままです。追加でテストクラスに対して、 Refactor | Rename を使い名前を変更するようにしています。 不要な use の削除 注文検索モデルに CakePHP 2 依存の App::uses がたくさんあったため、それを PHP の use キーワードで名前空間を利用するようにしました。そうすると、PhpStorm の Code | Optimize Imports 機能を利用して、不要な use の削除ができます。さらに、Optimize Imports を Before Commit フック に入れると、PhpStorm 経由でコミットする前に、自動で import をチェックし、修正してくれるようになります。 ポリモーフィズムで注文検索の条件分岐をシンプルにする 複雑な検索条件の分岐を全て 1 箇所で対応したため、検索クエリを構築する処理が複雑化していた課題を解消するためにポリモーフィズムを導入しました。条件分岐の中で最も複雑なのは、検索対象の中にコイン注文(ショップコインという BASE 内かつて流通していた仮想通貨を使って購入した注文)が含まれているかどうかの分岐です。コイン注文ありなしの 2 パターンで検索クエリ構築、DB へ問い合わせ、返り値の整形という一連の流れを 1 つのクラス内で実装していたため、条件の分岐が散らばり、処理の重複も発生するようになりました。 注文検索モデルのコイン注文ありなしの分岐に対して、以下のリファクタリングを行いました。 同じインターフェイスを実装したクエリ生成クラスを別々に作成した。クエリ生成の共通処理は trait に切り出した。 コイン注文ありなしの条件に応じて正しいクエリ作成クラスを生成するファクトリーを作成した。 注文検索モデルでは 2 のファクトリーを利用してクエリ構築の条件分岐を隠蔽した。 今回のリファクタから学んだこと よかったこと まずはリファクタすること自体がよかったです。既存コードに手を加えることにより、実装者の意図が伝わり、ドキュメントに書かれていない仕様の細かい部分への理解も深まりました。リファクタリングの結果、ソースコードの可読性とメンテナンス性が向上し、注文検索改善など後続プロジェクトが軽い身でスタートできるようになりました。今は、リファクタして損はないと考えています。 テストファーストとリファクタリングの相性がよかったです。テストを予め定義することで、このリファクタでデグレっているのかのフィードバックを最短でもらえるため、バグが発生しても早めに気づいて修正することができ、リファクタの生産性向上に貢献が大きかったです。今回のリファクタで 10 回弱のリリースの内、注文検索の全パターンを網羅的に手動テストしたのは最後の 1 回でしかないです。リリースして半年が経っても、バグが出ていませんでした。 ボトムアップ方式でリファクタの意思決定の合意が取りやすかったです。リファクタリングの合意がうまくいかないほとんどの場合は、進行中の開発タスクを優先したいと思います。ボトムアップ方式ならリファクタのための前期設計と計画が不要となり、いつでもリファクタリングを開始や停止にでき、いつでも開発タスクに戻れる状態が作れやすいです。 よくなかったこと ボトムアップ方式に限界がありました。変数名の変更や、関数の抽出など局所的なリファクタでは設計せずにスムーズに進めましたが、ポリモーフィズムなどクラス全体あるいは、クラスを跨ぐ影響が出るリファクタでは予想していなかった理由でリファクタが進めなくなると手戻りコストが高いです。注文検索モデルの例では、元々はクエリ構築、DB へ問い合わせ、返り値の整形という一連の処理に対して、ポリモーフィズムを適応しクラスを分けようとしましたが、DB へ問い合わせは Model を継承したクラスでなければいけないというフレームワークの制限に引っかかり、2 回ほどやり直しが発生しました。手戻りコストが高いリファクタリングを行う前に、一定程度でトップダウン方式で設計しておいたほうが良いと思いました。 おわりに 本記事では、ファットな注文検索モデルをリファクタした実践について記載いたしました。読んでいただいた方の助けに少しでもなれば嬉しいです。 明日は @izuhara さんの記事が公開予定です。ぜひご覧ください!
アバター
この記事は、 BASE Advent Calendar 2022 の9日目の記事です。 同日公開の @gatchan0807 さん の「 プロダクトの小さな負を解消する有志活動の振り返り 」もぜひご覧ください! こんにちは!BASEでPdMのプレイングマネージャーをしている本山と申します。 チームビルディングについて考えることが多いのですが、オンラインだと格段にハードルが上がるなぁと感じています。 この記事では、今までのトライを通して見えてきた「オンラインでのチームビルディングで意識をしていること」をまとめたいと思います。 似たようなお悩みをお持ちの方にとって、少しでもヒントになれば嬉しいです。 目指している満足度 チームビルディングの企画をする際、私は満足度75%くらいを目指しています。 チームビルディングは、チームの状況にあわせて継続的に取り組むことが大切だと考えているからです。 満足度100%を目指そうとすると、企画や準備のハードルが上がりライトにトライをしにくくなってしまいます。 逆に満足度が低ければ、チームのみなさんに協力をしていただけなくなってしまいます。 「次も参加してみたい」と少しでも思っていただける状態と、自分からお誘いをしやすいバランスの目安として満足度75%くらいを目標にしています。 意識しているポイント チームビルディングを考える際に、意識をしているポイントは大きく3つあります。 ※ 毎回全てを満たそうとしているわけではありません 会話を発生させる 変化をつくる ポジティブな印象で終われるようにする 1. 会話を発生させる 特にオンラインMTGでは、発言・会話をするか迷ってしまう場面があると思います。 参加者の方が迷わず発言しやすいような状態作りを意識しています。 取り入れ方 発言順番は、指名制にする 指名方法は「今日の占い順位」のように変化があるものだと、固定の順番にはならないので相性が良いです アイスブレイク・雑談はテーマを指定する 事前にテーマを募集しておき、ストックをしておくと便利です ビジュアルイメージで表現をしてもらう 今週の絵文字 / 気持ちを天気をスタンプで表現 + その理由を話していただく 2. 変化をつくる 特にオンラインのMTGでは、聞いているだけなど特定の状態が長時間継続した場合、集中力の維持が難しいと考えています。 参加者の方の興味が続きやすい状態をつくるため、気持ちや状態の変化を意識的に取り入れるようにしています。 取り入れ方 タイマーをかけて区切りをわかりやすくする 少し短めでかけると、タイマーが鳴ることで間延びしないのでおすすめです グループ分けをシャッフルする zoomのブレイクアウトルームとの併用が便利です ポジティブ・ネガティブ両方の感情の発散をしていただく もやもや・今後やってみたい・不安 などもお互いを知る上でおすすめの切り口です 3. ポジティブな印象で終われるようにする 「終わりよければすべてよし」という言葉もありますが、最後はなるべくポジティブな印象でおわれる構成になっているか注意をしています。 取り入れ方 感想をシェアしていただく ざっくり👍 👎 などの感情アンケートだと視覚的にわかりやすくおすすめです 自分からここが楽しかった・嬉しかったなどポジティブな感情を伝える 流れとして、ポジティブなテーマが最後にくるようにする オンラインでできるチームビルディングのアイディア 1〜3のポイントを意識してオリジナルの企画をすることもありますが、他の方がつくられた取り組みを使わせていただくことも多くあります。 活用をしたことがあるものや、今後トライしてみたい取り組みのキーワードを貼っておきます。 ※ 自分で全て見つけたわけではなく、まわりの方に教えていただいたキーワードも含めさせていただいています キーワード バリューズカード モチベーションポーカー ソーシャルスタイル診断 16 Personalities Belbin Model スキ・キライ・得意・苦手チャート まとめ 改めて、チームビルディングには正解がないからこそ、難しいですし面白いとも思っています。 今後もチームのみなさんと一緒に、色々なトライをしていきたいと思っています。 明日は、 shiiyan さんの記事が公開予定です。お楽しみに・・・!
アバター
この記事は BASE Advent Calendar 2022 の9日目の記事です 同日公開の(この活動にも参加してくださっている) @yuripiiiii さんの 「オンラインでのチームビルディングで意識をしていること」 もぜひご覧ください! ごあいさつ はじめましての人ははじめまして、こんにちは!フロントエンドエンジニアのがっちゃん( @gatchan0807 )です 今回の記事では1年近く継続して実施してきた、 プロダクトの細かな不具合や使いづらい部分を有志チームで改善していく「#iikanji-pkb-kaizen」という活動 についてご紹介します! なかなか利益に繋がっているかが計測しづらく、組織の間にボールが落ちてしまいがちな細かい不具合対応や改善をチームとして対応するために「どのようなことを考えて」「どのように進めて来たのか」を共有することで、読んでいただいた皆さまの組織でも実践するヒントになれば嬉しいなと思っています! 周辺の環境 まず初めに、この活動を行っていたチームとそれを取り巻く組織について組織について紹介します。 #iikanji-pkb-kaizen の「pkb」とは BASEというプロダクトに対して、様々な経路で受け取った改善要望をまとめている場所の「Product Kaizen Backlog(プロダクト改善バックログ)」の略称です。 現在はAsanaを使っていて、そこに予め用意したテンプレートの内容を埋めて、改善要望を登録してもらう形を取っています。 PKBがなかった頃は、CSへのお問い合わせで届いたフィードバック、BASEとしてショップ運営を有人サポートしているショップからのフィードバック、社内で気づいたちょっと気になる点などの様々な改善アイデア・改善要望が様々なツール上に散らばってしまっていました。 それらをまとめて確認出来るようにする場所を作ることと、正式なお問い合わせとは別に、ショップオーナー向けの管理画面下部から直接要望やフィードバックを送れる以下のようなフォームを作成するプロジェクトを遂行して現在の形になっています。 まだまだ運用方法を模索中ではありますが、一旦ここに蓄える。という場所ができたのは検索性・一覧性の観点からとても運用しやすくなりました。 組織構造の変化 この活動はもともと、 Owners Experience(以降、OXチーム)という「ショップオーナーさんのショップ運営の体験向上」にフォーカスした組織のメンバーが有志で集まって、 月曜朝と金曜夕方という、集中力が高まりにくい業務時間のウォーミングアップ&クールダウンとしてやりだした のが始まりです。 「プロジェクトのように数ヶ月単位でやるレベルじゃないけど、BASEへのお問い合わせなどでちょいちょい届く、BASEの使いにくい部分をガンガン改善していこう!」というモチベーションで始め、いずれ他の組織の人も集まっていければ良いね〜と実施していました。 そこから数ヶ月が経ち、ビジネス優先度と組織の全体最適化のために「目的別組織」への移行が進んで「OXチーム」という組織はなくなり、より具体的な「CRM」「Back Office」などの領域に紐づく目的別組織になりました。 結果として、現在では #iikanji-pkb-kaizen の参加メンバーは様々な部署から有志でPdM、デザイナー、バックエンドエンジニア、フロントエンドエンジニアが集まる形で合計6名で実施しています。 活動名の「iikanji」とは BASEのSlackコミュニケーションにおける文化として、Slackチャンネルをサクッと作って特定のトピックをそこでガッとコミュニケーションを取ろうという文化がありました。 「iikanji」というのは、そのSlackチャンネルを作る時に「プロジェクトでもないし、かといって何かが決まってるわけでもない、モヤッとした課題感を "イイ感じ" に解決していきたい」という感覚値を表したワードで、いつからかこれをSlackチャンネル名にプレフィックスとしてつけることが社内で慣習になっています。(プレフィックスをつけることで、こういった社内の有志活動を見つけやすくするという意図もあります) "#iikanji-pkb-kaizen" というチャンネルは上述の通り「OXチーム」がなくなったタイミングで、今までやってきた細かい改善の有志活動を引き続きやっていきたいという思いで作った形になります。 ちなみに、過去のテックブログには他にも #iikanji-agile や #iikanji-conference-toudan という活動について紹介された記事があるので、もしご興味があればぜひ読んでみてください!👀 運営してみてわかったこと、やったこと ここまでで「#iikanji-pkb-kaizen」という取り組みがどういうものなのかを紹介できたので、ここからは実際にこの活動を運営していて考えたこと、チームで実施したことを紹介していきます! 9月のタイミングで行った振り返り OXチーム時代から続けてきた活動が #iikanji-pkb-kaizen という名前に変わり、約半年がたった今年9月末にこの活動の振り返りを実施しました。 まずはその振り返りをしている中で改めて見えた、言語化が出来ていなかったけどぼんやりと感じていた課題感について共有します。 1. 活動時間だけで進捗を出せている感じがしない これは週に2日1時間ずつ、それも週の頭と終わりの日に行っているので、ウォーミングアップとクールダウンという目的にはあっていたものの、活動の時間でタスクを進めるという目線だと、 思い出す時間の方が多くて作業が進まない… という声でした。 また、この会にはPdM、デザイナーの方も同じように参加してもらっていて、エンジニアに限らず彼らからも同様の声が上がっていました。 ですが、こういった声を振り返り会の中で深ぼってみると、それぞれ少し異なる原因があることがわかったので、2つの対応方針(後述)を決め運用してみることにしました。 2. 我々がやってることは新入社員向けオンボーディングタスクとなにが違う? / カニバってない? 少し話は変わりますが、BASEではありがたいことに2021年から2022年にかけて、月数名のエンジニアが新入社員として入社してくださる時期が続いていました。 そんな中で1つ問題になるのが、 「オンボーディング時にプロダクションコードを触るきっかけになるちょうど良い粒度のタスクが見つからない問題」 です。 「オンボーディングタスクを探すこと自体も大変だけど、そもそもこの活動でそういったちょうどいいタスクを消化してしまっていたらどうしよう…」という思いも頭のどこかにあり、この振り返りで議題に上がりました。 これに関しては、話している中で上記 1. の課題と同時に解決する方法(後述)が見つかったので、それを試してみることにしました。 3. タスクの管理方法がやりにくい これは、歴史的経緯と具体的なツールの話しになるので、あまり読者の皆さんの参考にならないかもしれません。 もともと #iikanji-pkb-kaizen では FigJam というホワイトボードツールに現在対応中のタスクを付箋にして貼る、作業が進んだら移動させる。という形を取っていました。 これは、チームやプロジェクトによってはAsanaを活用しているチームもあったものの、社内的にはまだ普及しきっていない + タスク管理をボードでカジュアルに行いたかった(+ 個人的な好み)ことから、 FigJam を使った運用を選択した形です。 しかし半年も経って、社内の覇権を握っているタスク管理ツールもツールに対しての参加メンバーの認識も変わってきたことから FigJam を使った運用はやりにくい!となったのです。 そのため、その場で FigJam のタスクボードはアーカイブとしてファイルだけ残した上で、Asana上で管理するように切り替えました。 振り返ってわかった課題とその解決策 活動時間だけで進捗を出せている感じがしない この課題感に関する根本原因を深ぼってみたところわかったのは、 「なんらかの機能全体の体験の改善を行うには、活動時間がそもそも足りない(思ったよりも規模が大きくなりがち)」 ということでした。 具体的には、以下のように2つのパターンで問題が起きていました。 ① エンジニア主導で進める場合、 業務フローの理解や調査、他チームへの確認が多くなってしまう ため、結果的に実装だけでないところに手がかかること(回答待ちが発生してなかなか実装に進めないことも) ② PdM・デザイナーが対応していた作業は 「そこやるならついでにここも直したい→規模が大きくなってしまう」パターンと、「近いうちにプロジェクト側で代替の対応が入るから触らなくてOKとなる」パターンが発生する ことでした。 これらの問題は、有志メンバー以外のプロジェクトやチームとのすり合わせが必要なために発生していたので、 #iikanji-pkb-kaizen で取り扱うもののスコープをもう少し絞り、運営体制としてはもくもく会のような形に移行することにしました。 エンジニア側は 「ゴールが明確で、実装対応と進捗把握がしやすい不具合の解消を進める」 。 PdM / デザイナー側は 「ショップオーナーから受け取ったフィードバックを整理し、対応方針・担当領域も含めてPKBのアイテムとして起票をする」 。 という部分にそれぞれフォーカスし、週2回もくもく会に集まったメンバーでそれぞれ上記のような対応をしつつ、別の職能の知識が必要な場合はもくもく会で適宜質問をし合えるという形に切り替えました。 運用方式を変えて得た効用 エンジニア側 エンジニア側で対応する「不具合」には以下のようなものが含まれるのですが、これらの対応は短い時間でも対応しやすく、サクサクとリリースすることが出来ました。 納品書ダウンロード App でダウンロードできるPDFファイルの決済方法の表示部分だけ外国語対応されない 商品詳細登録画面のスマホビューのときにだけ表示されるボタン文言が旧式の呼び方のままだった レビュー App の設定項目が新しいデザインテーマだと不要なのに表示されてしまっていた などなど… これまでに対応したものの中の一部ですが、上記であげたような細かな不具合は短い時間で解消〜リリースまで完了することが出来ました。 PdM・デザイナー側 こちらの運用方式の変更を図解すると、以下の図の紫色の枠で囲った部分をガンガン進めていくぞ!という形です。 この活動を行うことで、今までよりも対応要望の詳細度が上がったバックログアイテムがPKBに積まれることになります。 これによって #iikanji-pkb-kaizen に参加しているエンジニアが対応しやすいバックログアイテムが増えるというメリットはもちろん享受できたのですが、副次的に 我々がやってることは新入社員向けオンボーディングタスクとなにが違う? / カニバってない? という課題に対しての解決策にもなりました。 図では以下の紫色の枠で囲った部分が増え、オンボーディングタスクが必要な時はPKBから探す。という運用がしやすくなりました。 まとめ 以上、プロダクトの小さな負の部分を解消する「#iikanji-pkb-kaizen」という活動についての紹介でした! こういった有志活動は「こうすれば活動がうまくいく!」「これが絶対的な正解だ!」というものを見つけるのはなかなか難しいと思っていて、会社全体の組織状態に合わせて臨機応変に対応していきながら、 なによりも継続し続けること が一番大事だと思っています。 なので、BASEでも1年近く有志活動をしているとこんな状況になって、こういうことを考えて解決していったよ!というケーススタディの材料として皆さんに知ってもらえればよいなと思ってこの記事を書かせていただきました。 今回紹介できた内容は、会社組織の状況に対するかなり対処療法的なものばかりでしたが、少しでも皆さんの参考になれば幸いです。 明日は同じチームの shiiyan さんの記事です!お楽しみに!
アバター
この記事は BASE アドベントカレンダー 2022 の8日目の記事です。 はじめに BASE BANK Section Dev Group Manager/ BASEカード Engineering Program Managerの松雪( @applepine1125 )です。 普段は BASEカード のEPMとして開発をリードしながら、BASE BANKがもつプロダクト開発チームそれぞれがガンガンアウトプットを出していけるように様々なサポートを行っています。 最近は、まだ日本であまり馴染みのないEngineering Program Managerについて色々とアウトプットしているので、特にマネジメント視点からアジリティの高いチーム作っていきたいぞ!という方は是非読んでいただけると幸いです。 プロダクトのデリバリー、クオリティに責任を持つEngineering Program Managerという役割 オーナーシップを持ち自己組織化するチームに必要な Engineering Program Managerという役割 今回は、BASE BANKでも掲げているフルサイクルエンジニア(Full Cycle Developer)というスタンスについて、定義だけでなく実際の仕事の中で見出した姿をお伝えします。 フルサイクルエンジニア(Full Cycle Developer)とは 2018年にNetflixが記事で公開し、日本でもCARTA Holdingsさんが訳してくださったことによりさらに広まりつつある概念です。 Full Cycle Developers at Netflix — Operate What You Build Netflixにおけるフルサイクル開発者―開発したものが運用する 上記記事の日本語訳 詳細な内容については上記記事に任せますが、要はこれまでソフトウェアライフサイクルの各段階を分業、専門化していた状態から、よりスピーディにプロダクトアウトプットし続けるために一連の段階を価値提供に関わるエンジニア、チームが責任を持ち、実行できるようにしようというスタンスです。 https://netflixtechblog.com/full-cycle-developers-at-netflix-a08c31f83249 別にNetflixが提唱して初めてそういった働き方、関わり方が生まれたわけではなく、これまでも自律性の高いチームだったり、良くも悪くもカオスなチームに所属するメンバーは似たような働きをしていたのではないでしょうか。 プロダクトや事業を前にすすめるために、創るべきプロダクトについて考え、実装し、インフラや安定したリリースのためのCI/CDフローを構築し、効果測定のための分析基盤まで整備し開発のサイクルを回し続ける。 webアプリケーションエンジニアが担ってきたこの責務にNetflixがFull Cycle Developersという名前付けを行うことで、プロダクトアウトプットのサイクル全体をより能動的に効率よく回そうとする流れができつつあるのは喜ばしいことです。 フルサイクルエンジニアはフルスタックエンジニアなのか? フルサイクルエンジニアを志向する上で、よく話に上がるのがフルスタックエンジニアとの比較ではないでしょうか。 果たしてフルサイクルエンジニアを志向することはフルスタックエンジニアになることなのでしょうか? 個人的な意見ですが、結果的にフルスタックエンジニアになっていくことはあるものの、必須ではないと思っています。 フルサイクルエンジニアは “Operate what you build” (開発したものが運用する)というアプローチで、開発だけでなくテストや運用、様々なものを効率化します。 ここで重要なのは、 個人ではなくチームで 一連のサイクルをスピーディに回すことに取り組んでいることです。 全員が全技術領域において圧倒的なアウトプットができれば理想ですが、現実世界ではメンバーによってスキルや興味関心のある領域が異なるのは当たり前です。 そういった中で、CI/CDやテストなどの技術的なツールだけでなく、各メンバーの得意領域における知見やスキルもチームのツールの一つとして活用することで、チームとしてより良いアウトプットを生むことができます。 とはいえ、チーム内で技術的に完全に分業してしまうとこれまでのような専門化した分業体制をチーム内で再現することになるため、各メンバーが少なくとも各技術領域にチャレンジすることは求めるべきだと思っています。 プロダクトのために、自分の強みを活かしつつもその時々ですべきことを行っていくことで、いわゆるT字型のようなスキルセットをもったエンジニアになっていくことはあるでしょう。 フルサイクルエンジニアは専門性が身につかないのか? 広いプロダクトライフサイクル、技術領域に関わることで、器用貧乏になることを恐れている方を時々見かけます。 チームや会社の状況により、仕方なくいろいろな領域に関わらざるを得なくなった結果、自身の強みとなる領域を見つけられずもがくこともあるでしょう。 フルサイクルエンジニアの場合、より良いプロダクトアウトプットのために自ら様々な領域にチャレンジしていきます。 上でも書いたように、自身の強みをチームのツールの一つとして活かしながら、プロダクトのために実行できる領域を広げていけるように成長戦略を立てていくことで、技術的にも十分専門性を育てることができます。 とはいえ、チームとして分業体制がうまく構築され、いわゆる深いI型のスキルを持ったエンジニアに技術的な専門性で劣ると感じることもあるでしょう。 しかし様々なスキルをプロダクトのためにどう使いこなすか、それによってメンバーと共に成果を出し続けられることも十二分に専門性の高いスキルだと思っています。 個ではなくチームのアウトプットを最大化する 事業やプロダクトは常に成長圧力に晒されます。プロダクトの要求も複雑かつ柔軟に変化していきます。 自らの手だけで全領域実行できるようになったとしても、いつか個人の物理的なアウトプット量の限界にぶつかります。 素早い市場の変化、柔軟な要求の変化に追従し、リードしていくためにはチームで課題に取り組まなければなりません。 Some developers view design+development, and sometimes testing, as the primary way that they create value. This leads to the anti-pattern of viewing operations as a distraction, favoring short term fixes to operational and support issues so that they can get back to their “real job”. But the “real job” of full cycle developers is to use their software development expertise to solve problems across the full life cycle Netflixのブログでもこう言っているように、専門性を発揮しつつもあくまで チームとしてライフサイクル全体の問題を解決することにフォーカスする 必要があります。 そのなかで各個人に求められることは、少なくとも すべてのライフサイクルの段階にオーナーシップを持つこと です。 現実にはインフラ構築はSREの方に実行いただいたり、カスタマーサポートの方にユーザーのサポートをしていただいたりすることもあるでしょう。 そういった場合でもライフサイクル全体をより良くするためにステークホルダーとどうコラボレーションしたり、場合によってはチームの責務として巻き取れるか 主体的に 検討し実行することにより、個人だけではなくチームを強化することができます。 By combining all of these ideas together, we arrived at a model where a development team, equipped with amazing developer productivity tools, is responsible for the full software life cycle: design, development, test, deploy, operate, and support. 個人的にNetflixのブログ内のこの一節が好きです。 個人ではなくチーム なのです。 Netflixのエントリのタイトルも Full Cycle Developer ではなく Full Cycle Developer"s" であることにお気づきでしょうか。 developerが複数形であることに(勝手に)意味を感じ取っています。 プロダクト開発は基本的にチームで行います。チームがよりよい価値提供を目指して一丸となり、そのために個々人がチームに対しどういった貢献をするのか。そこをうまく組み立てることができれば、各々の強みを最大限に生かした、プロダクトへの様々な関わり方を生み出すことができます。 フルサイクルエンジニアとして働く意義、意味を創る ここまで主にメンバーの立場でフルサイクルエンジニアについてお話してきました。 ただプロダクトのためにやるべきことをやれ!では人は動きません。そこでマネジメントの腕の見せ所です。 チームとしてフルサイクルエンジニアとして取り組むことがインセンティブとなるように目標や評価を設計する必要があります。 個人が直接プロダクトに価値を与えていくだけでなく、解決すべき問題を見つけるための視点の時間軸を切り替えられるように、チームが余裕を持てるような投資も行っていく必要があります。 例えば、短期的に目の前のプロジェクトをなんとしてもスケジュール通りに終わらせることだけをひたすら求められた場合を考えてみましょう。 当然目の前のタスクに集中し、プロジェクトを完遂させるために払った技術的負債を返済する余裕もなく、ツールやスキルだけではどうにもならなくなります。 すると、短期的な視点で任された自分の仕事だけをこなすことに躍起になり、保守的な見積もりや越境を回避することによるディスコミュニケーションが多く発生するようになり、PMやビジネスサイドとエンジニアとの間で信頼関係が構築できずチームとして破綻していきます。 チームやメンバーは燃え尽きのリスクに晒され、プロダクトアウトプットのライフサイクルが破壊されてしまうのです。 とはいえ、長期的な視点で技術的な投資ばかりしていては事業は前にすすめることができません。 あくまでプロダクトアウトプットのためにどういった投資ができるか考え、それを実行したことで日々の開発がどのように効率化したか常に振り返り続ける必要があります。 直接事業を進めるための仕事と長期的な投資のバランスを取るためには、マネジメントをする人間が両方の視点を持ってうまく優先順位付けを行い、メンバーの成長をサポートし生き生きと働けるような環境づくりをする責任があります。 BASE BANKでのフルサイクルエンジニア像 色々と偉そうなことを書いてきましたが、我々BASE BANKチームもまだまだ発展途上の段階です。日々改善を積み重ねています。 BASE BANKチームはショップオーナーさんのキャッシュフローの課題解決を行うために2018年に誕生し、そこからYELL BANK、やBASEカードなどのプロダクトを生み出してきました。 新規事業立ち上げ、グロースを担うチームとして、最初から意識していたことはとにかく早くリリースし、素早く改善のサイクルを回し続けることです。 これを大前提として今に至るまで組織設計や技術選定、文化の醸成を行い続けています。 現在BASE BANKは全体で15名ほどのチームです。 そのうちエンジニアは10名で、下記組織図のようにDev Group内でBASE BANK管掌の3プロダクトごとにチームを分けています。(他にもチームはあるがBASE BANKに関係する組織構造だけ抜粋) プロダクトの意思決定に関わるメンバーを組織構造的にも近い位置に置き、よりスピーディにコミュニケーションを取り意思決定を進められるように組織設計をしています。 https://speakerdeck.com/base/basebank?slide=29 なぜやるのか考え、フィードバックループを通じて学び続ける エンジニアとして解くべき本質的な課題を発見し、フォーカスしてもらうために、なぜ今のような組織構造や開発プロセス、文化になっているのかについて深く腹落ちしてもらい、その上でチームの一員として何をすべきかを一緒に考え、アウトプットしています。 そして個人やチームがアウトプットの結果何を得られたか、何を改善すべきかを振り返りつづけられるようにサポートすることで、学びを積み重ね、発見する課題とそのアウトプットの質を高めていけるようにしています。 エンジニアチームのいわゆるレトロスペクティブのようなスプリントごとの振り返りだけでなく、様々なタイミング、粒度での振り返りやそこから生まれたネクストアクションの実行、そしてまた振り返り・・・といった積み重ねが、エンジニアに限らずBASE BANKチーム全体で当たり前のように行われています。 チーム全体でとにかく学び続ける。 これを徹底しています。 背中を任せ合う。コラボレーション BASE BANKのメンバーは、皆がプロダクトのライフサイクルすべてを完璧に回せる超人というわけではありません。 各々の強みを最大限に活かしながら、個ではなくチーム全体で高い生産性を維持、向上させ続け、まさに"個ではなくチームのアウトプットを最大化する"の項で書いたことを体現してくれています。 日々の開発のサイクルは各チームが主体的にまわしつつ、チームを横断しレビューや技術的なサポートと通じて背中を任せ合っています。 背中を任せ合うのはエンジニアに閉じた話ではなく、product group(事業企画やマーケティングを担うチーム)やdesign group(デザイナーが所属するチーム)とも密に連携しあい、よりスピーディに仕事をすすめるにはどうコラボレーションしていけばよいか?を日々の振り返りを通じてアップデートし続けています。 https://applepine1125.hatenablog.jp/entry/20220818/1660750909 個人的に昔書いた"みんなでアジャイル"の書評の中でもふれましたが、アジリティの高いチームであり続けるための原則の一つとして 早期から頻繁にコラボレーションするのがアジャイル というものが掲げられています。 変化に対し、チームとして柔軟に適応し続けるためには互いに密にサポートしあうのは当然の流れなのです。 越境 "フルサイクルエンジニアは専門性が身につかないのか?"の項で、T字型のスキルについて触れました。 フルサイクルエンジニアとして高いアウトプットを行い続けるためにはプロダクトに必要なことのために越境し続ける必要があります。 技術的なスキルに限った話だけではありません。必要なステークホルダーへのコミュニケーションなどチームの越境や、これまで持ったことのなかった範囲の責任を持ちチャレンジする越境など、様々な越境の形があります。 BASE BANKのメンバーは自分が関わるプロダクトにまつわる領域に高い興味関心をもち、積極的に越境しコミュニケーションを取り、主体的に仕事を前に進めてくれています。 その背景にはプロダクトやユーザーへの高い理解や、相互の信頼があるのかなと思っています。 とはいえ闇雲に越境し続けるとコンフォートゾーンを一気に突き抜けパニックゾーンにまで到達してしまい、越境から得た学びを積み重ねることができずに消耗してしまうこともあるでしょう。 そうならないためにも、自分がマネージャとしてOKRや日々のコミュニケーションを通してプロダクトの方向性とメンバーの志向をすり合わせ、チャレンジしてもらう範囲を着実に広げています。 信用、信頼 ここまで書いてきた学びのサイクル、背中を任せ合うこと、越境、すべての根底には互いへの強い信頼関係があります。 より柔軟にコミュニケーションを取り、学びを積み重ねながらスピーディにプロダクトや事業を前にすすめるためには、技術や経験だけではなく 互いの信用、信頼が何より重要 と考えています。 "フルサイクルエンジニアとして働く意義、意味を創る"の項でも書いたように、互いの信頼関係が構築できないと、越境することもなく、保守的になりプロダクトアウトプットのサイクルは鈍化していきます。成長もできません。 互いに信頼関係を構築するには手放しで任せ合うのではなく、日々の仕事を通じて互いに腹を割って議論し、成果を出し続ける必要があります。 腹を割ったコミュニケーションができるようになると、意思疎通がスムーズになるだけでなく、相手の理解も深まり、結果的に深い信頼関係を築く事ができます。 また社会人として至極当たり前の話ですが、約束を守り、成果を出し続けることで、信頼を積み重ねることができます。 これができるようになると、よくあるビジネスサイドとエンジニアサイドでやりたいことが食い違い衝突するようなこともなく、状況に応じて仕事の優先順位を適切にコントロールできるようになります。 チームとして仕事をする上で互いに深く理解し合い、頼り合える関係の構築を何より大事にしています。 おわりに 様々なツールが充実しエンジニア自身で実行できる範囲が広がる中、プロダクトのために越境し実行し続けるとフルサイクルエンジニアになっていくというのは自然な流れなのかなと思っています。 我々自身もまだよりよいチームづくりの途中です。今後事業やチームメンバーが増える中で様々な課題にぶつかることでしょう。 それでも互いに信頼関係を構築しあい、背中を預け合いながら、プロダクトのために何ができるか考え続ける姿勢さえ忘れなければ、どんな課題もこのチームであれば乗り越えていけるのではないかと思っています。 当然さらなる成長のためにより多くのメンバーの力も必要です。BASEやBASE BANKの事業、我々の働き方など少しでもご興味があれば気軽にお話しましょう! open.talentio.com 明日は @gatchan0807 @yuripi の記事が公開予定です、ぜひご覧ください!
アバター
はじめに 本記事は BASE アドベントカレンダー 2022 の8日目の記事です。 BASE BANKの @osushi_maguro 🍣です。 「BASEカード」というプロダクトのPMM(プロダクト・マーケティング・マネージャー)を担当しています。 『HUNTER×HUNTER』が大好きです。 今回は、ユーザーリサーチとABテストを通じて、 「BASEカード」 の効果的なメールマーケティングが実現した話をします🙋‍♀️    その前に……「BASEカード」って何?🤔 BASEカードは、BASEショップの売上を全国のVisa加盟店で「即時決済」できるカードです。 ショップオーナーさんは、 「振込申請をすることなくすぐに」「手数料をかけずに」 売上をご利用いただくことができます。 1分でわかる、「BASEカード」のきほん - BASE U|ネットショップの開設・運営・集客のノウハウを学ぼう    ユーザーリサーチ内容✏️ ユーザーリサーチは、3ステップでおこないました。 BASEカードのファネル分析: 「離脱が多いファネル」を把握する ヘビーユーザーへのインタビュー: ヘビーユーザーの「BASEカードに対する愛着」が強くなったきっかけやポイントを把握する 未発行ユーザーへのインタビュー: 1の調査により「発行ファネル」における離脱率が最も高いことがわかったため、発行の阻害要因を把握する    ユーザーリサーチ結果💡 上記ユーザーリサーチの結果、わかったことが 3つ ありました。 BASEカードのヘビーユーザーは、主に 「法人化していない個人事業主の方」「BASEを副業として位置付けている方」 に多かった ヘビーユーザーにとって、BASEカードの最大の魅力は 「振込申請のペイン(入金までのリードタイムが長い・手数料がかかる)が解消されること」 未発行者はBASEカードを クレジットカードだと誤解 しており、「クレジットカード = 発行が面倒臭い・年会費がかかる」というイメージから発行に至っていない 以上から、BASEカードのマーケティング戦略として、 「現在のヘビーユーザーのような層をターゲットとし、クレジットカードのイメージを払拭しながら、振込申請のペインが解消されるというメリットを強調する」 という方針で施策を実行していくことにしました。    ABテスト内容✏️:文面検証編 マーケティング施策として、まずはメールから始めることにしました。 発行ファネルの離脱率が高いことから送信対象を「未発行ユーザー」に絞り、 ユーザーリサーチ結果を踏まえて2種類の文面を用意し、テストをおこないました。 A.「 振込申請のペインが解消されること」を強調した内容 件名:振込手数料が無料になる「BASEカード」が発行できます! BASEカード・振込申請の比較イメージを載せたもの(図の中央) B. 「クレジットカードではないこと」を強調した内容 件名:「BASEカード」(プリペイドカード)が発行できます! BASEカード・クレジットカードの比較イメージを載せたもの(図の中央) 発行率が高かったのは、果たしてどちらの文面でしょうか? 結果を見ていきましょう!    ABテスト結果💡:文面検証編 発行率が高かったのは A「 振込申請のペインが解消されること」を強調した内容 のメール文面でした。 振込申請と関連づけながらアプローチする方法は確実に効果がある 、ということがわかったので、続いてもう1つテストをおこないました。    ABテスト内容✏️:タイミング検証編 前述のABテスト結果を受け、 「振込申請に対するペインが”特に”高まるタイミングにアプローチすると、さらに効果的なのでは……!?🥸」 と考えました。 そこで、 「振込申請に対するペインが”特に”高まるタイミング = 振込申請の直後」 と仮定したうえで、 振込申請をした かつ その当日に「振込申請のペイン解消を強調した内容」のメールを送信したグループ 振込申請をした かつ 上記メールを送信しなかったグループ 振込申請をしていない かつ 上記メールを送信したグループ 振込申請をしていない かつ 上記メールを送信しなかったグループ という4つのグループを作り、発行率を比較しました。 さて、こちらの結果はどうだったでしょうか?    ABテスト結果💡:タイミング検証編 発行率が高かったのは 「振込申請をした かつ その当日に上記メールを送信した」 グループと、 「振込申請をしていない かつ 上記メールを送信した」 グループでした。 振込申請した・しないにかかわらずメールを送ったグループの発行率が高かったことから、 送信タイミングが効果に及ぼす影響はあまり高くない = メールを送信すること自体が重要 だと思われます。 これは、個人的には結構意外でした😳    おわりに 今回は、ユーザーリサーチ結果をクイックにアウトプットに活かせたこと・ABテストを経て効果的なメールマーケティングが実現したことが非常に良かったと思います。 また、「ユーザーの声からどんな仮説を作るか?」「どんな検証をおこなうか?」「検証の結果、何がわかったのか?」「仮説をどのように修正するか?」という点はまさにPMMの腕の見せ所で、緊張感がありつつも(あるからこそ)日々面白いと感じます。 今後はメールマーケティングにとどまらず、Web画面のUI/UX改善・プロダクトの機能改善にも着手し、BASEカードがユーザーにとって最高のプロダクトになるよう尽力していきたいと思います! 明日は @gatchan0807 @yuripiiiii の記事が公開予定です、ぜひご覧ください。
アバター
カートチームを振り返る この記事はBASEアドベントカレンダーの7日目の記事です。 devblog.thebase.in Payment Dev Group マネージャーを担当している田仲( @tosh )です。 Payment Dev Groupは決済領域のプロダクト開発を担当しているグループになります。その中でも主にショッピングカート機能を担当しているカートチームについて、どういう経緯で生まれたのか、チームの役割や今後のことなどご紹介させてください。 カートチームについて BASEというECプラットフォームにおいて決済はサービスのコア領域になります。 BASEの中で決済は2つの方向性があると考えています。 ショップオーナーと購入者の間で行われる決済 BASEとショップオーナーの間で行われる決済 カートチームは前者のショップオーナーと購入者の間で行われる決済、システムの機能でいえば実際に商品が購入されるショッピングカート機能(以下、カート機能)をメインに担当しているチームで2022年7月に組成されました。 カートチーム組成のキッカケ BASEの課題としてEOLを迎えたフレームワークからの移行を進めています。その中でもカート機能はまず初めに移行が完了した機能になります。ですが、移行して終わりではありません。サービスは成長していくので併せて機能を改修していく必要がありますが、新しいアーキテクチャを理解せずに間違った方向で改修が進むと複雑な負債を生み出してしまう可能性もあります。またアラート対応やパッケージ更新などの日々の運用もあり下記のような課題がありました。 新しいアーキテクチャをどう適切に開発していくのか? アラート対応やパッケージ更新などの運用はどうするか? 上記の課題をカート機能をリニューアルしたエンジニアが有志的に対応していましたが、スケール面において好ましくない状況だったため、カートチームとして組成して、開発・運用・グロースを含めて責任を持つのが望ましい形なのではないかと考えた結果、リニューアルしたエンジニアを集めてカートチームが誕生しました。このチームをマネジメントする立場になったのですが、当初、私はチームトポロジーで紹介されているチームでいえば、コンプリケイテッド・サブシステムチームの役割をイメージしていました。 コンプリケイテッド・サブシステムチームとは、システムの中でスペシャリストの知識が必要となるパーツを開発、保守する責任を持つ。ほとんどのチームメンバーがその分野のスペシャリストでなければ、理解や変更が難しいようなサブシステムを担当するチームになります。 カート機能は決済が行われるサービスのコア機能であり、お金というユーザーのセンシティブな部分に関わることや決済を行う外部システムの仕様などを踏まえて開発するので専門的な知識が必要になります。そのため、この役割が良いと考えて他チームのカート領域の開発を巻き取り認知負荷を下げつつ責任を持って開発をしていけるように動き始めました。 進めていく中での課題 組成時の課題として巻き取るのは難しいのでは?というのがありましたが、案外いけるのではと思いカート機能に関わる案件を各チームからヒアリングしたのですが、やはり案件が多く当時のメンバーの数では案件を捌ききれない可能性が高い。またメンバーを増やすといってもカートチームに関わるチームは複数あり、採用は同じスピードで進むのでメンバーが不足している状況は続きそう。案件に優先順位を付けて対応していくことはできると思いますが、カートチームの対応待ちで他チームの開発が滞ってしまうとサービス成長を止めることに繋がり、本末転倒の話なので避けたいと考えていました。 イネイブリングチーム その課題を解決する上で役立ったのがイネイブリングチームのような役割のイメージでした。 イネイブリングチームとは、特定のテクニカル(プロダクト)ドメインのスペシャリストから構成され、プロダクトのデリバリー全体に関わる開発チームの能力ギャップを埋めるのを助ける役割のチームになります。 カート機能は専門的な知識が必要になる機能ではあるものの他チームの要件が絡んだ改修が入ることが多く、ビジネスに求められているプロダクトの成長を考えると一部のチームではなく開発チーム全体で改修していける体制がゴールだと考えました。新しいアーキテクチャを理解してもらいカート機能を他チームにも開発できるようになってもらう。周囲とのギャップを埋めていくための役割が良いのではないかと思い、メンバーから話を聞きながら下記の進め方が良さそうと判断をしました。 他チームの開発にカートチームのエンジニアが参加してカート機能開発を行う カートチームのエンジニアのサポートのもと、他チームにカート機能開発を行ってもらいカートチームがコードレビューすることで伝えながら品質を維持する 勉強会のようなものでアーキテクチャの理解を全体に展開することも検討しましたが、個人のスキル差は存在するので伝える粒度が難しいことや変更されていくため継続的なアクションが必要という観点があり、案件ベースで触ってもらいながら伝えていく方法を地道ですが選びました。 現在の状況 2022年7月にカートチームが組成してから5ヶ月目になります。組成時はまだ整理が追いつかずメンバーにマルチタスクをお願いすることもありましたが、現在は1つのタスクに集中しています。また他チームをサポートする体制も取れてきており他チームのメンバーにカート機能を伝えていくことも徐々にできていて、カートチーム要因で開発が遅れることは避けながらもカート機能の品質を維持するということは実現できています。採用に関しても自分たちでメンバーを増やしていくことできていて開始時は4人でしたが現在は8人になりました。 今後の課題 日々の問い合わせ対応やアプリケーションのアラート対応、パッケージ更新やデプロイなど、運用面は改善できると考えていて、チーム内でまだ偏りがある決済知識の平準化を含め、日々の問い合わせからの継続的な改善サイクル、ショップの増加と共に増えていく決済トランザクションをどう処理するか?という未来の課題に向けてのアクションなど。カートチームとしてカート機能・決済に責任を持って品質を維持することから高めていけるような取り組みを今後していきたいと考えています。 さいごに ここまで読んでいただきありがとうございました。 最後になりますがBASEを一緒に支えてくれるエンジニアを絶賛募集中です! A-1.BASE_Webアプリケーションエンジニア/ショップオーナー向け開発 / BASE株式会社 A-1.BASE_エンジニアリングマネージャー / BASE株式会社 明日は @applepine1125 と @osushi_maguro の記事です。お楽しみに〜。
アバター
この記事は BASEアドベントカレンダー の7日目の記事です。 初めに こんにちは。Owners Marketingチームの竹本です。 この記事では最近BASEに入社した私がどのようなオンボーディングを経てBASEの開発フローやチームに馴染んでいったのかを紹介できればと思います。結論を先に言うとBASEのオンボーディングフローは非常に体験が良く、スピーディーにチームに溶け込めていけたという実感があります。これからBASEに入社される方や入社を検討される方の参考になれば幸いです。 自己紹介 改めましてBASEの竹本と申します。私は今年の10月15日にBASEに入社し、フロントエンドエンジニアとして働いています。所属はOwners Marketingというチームで、ネットショップを開きたいと思われている方にBASEを選んでいただけるような改善活動やネットショップ公開までを迷いなくスムーズに行えるような機能開発を行っているチームになります。 私は元々はバックエンドエンジニアで、主にPHPを書くエンジニアでした。少し前までフロントエンド領域の知識はjQueryとBEM程度の知識しかありませんでしたが、近年のフロントエンド領域の進化やエコシステムの広がりは興味を惹かれるものがあり、プライベートで現在主流となっているフロントエンド開発を体験してみたり、トレンドになっているOSSを覗いてみたりするようになりました。そんな中、運良く前職でPCアプリをElectronで新規開発するという案件に関わらせていただき、そこで改めてWebフロントエンドという領域の奥深さと幅広さを実感しました。その案件が落ち着いたタイミングでフロントエンドを主軸にやっていきたいと思い転職活動をしたところ、縁があってBASEに入社することになりました。 BASEは新卒の頃からPHP系のカンファレンスでよくお見かけしていましたし、テックブログも参考にさせていただいていたので、よく知っていた企業ではありました。BASEへの入社を検討するにあたって改めてそれらを見返し、入社の決め手となったのは以下の記事を読んで技術の幅を広げながら業務を楽しめそうだと感じたからになります。 次世代の管理画面を作るフロントエンドの取り組み BASEのノーコードはどのように実現されているのか? 私のオンボーディング日記 ここからは私の入社初日からのオンボーディング体験を、日記形式でお届けします。 なお、以下の内容はあくまで私個人の話になりますので、オンボーディングフローは所属するチームやロールによって多少違うことにご留意ください。 1日目 コロナが落ち着いていたこともあって物理出社しました。オフィスに着くとチームメンバーとメンターの方が歓迎してくれました。普段はリモートワークでお仕事をされているそうですが、この日は顔合わせのために全員出社で迎えていただけたらしくとても嬉しかったです。 この日のお昼はチーム全員でひつまぶしを食べにいったのですが、そこである程度チームの雰囲気や人となりを知ることができたと思います。皆さん気さくで話しやすく技術に対して明るい方ばかりだったので、このチームなら上手くやっていけそうだとこの時から感じていたと思います。 帰ってきてSlackを覗いてみると onbording-takemoto チャンネルができており、入社時点でオンボーディング中になんでも聞けるチャンネルが用意されていて安心感がありました。「やるぞ〜」という気持ちが湧きましたね。 業務初日は自分のMacbookのセッティングをしたり、業務で使用するアカウントの申請を行ったりして終了となりました。 2日目 2日目は主に環境構築を行いました。BASEのローカル開発環境はDockerで構成されており、またセットアップ作業のほとんどがスクリプト化されていて、いくつかのコマンドを叩くだけで環境構築が完了します。途中、少しつまづくところもありましたが基本的にはドキュメントを読んだり、Slackで聞いたりすることですぐに解決しました。前職・前前職と環境構築は一大作業だったので、 特定の誰かに聞かないと作業が進められない という状況に陥らなかったことが振り返ってみて非常に良い体験だったなと思います。余った時間でリポジトリのREADMEを読んだり、コードリーディングしたりしていました。 3日目 環境構築も終了したところで、最初の開発タスクに取り掛かります。BASEでは入社してからできるだけ早く最初のリリースを行えるよう取り組んでいます。これはリリースするまで作業を通じてBASEの開発フローを理解してほしいという意図があります。これは非常にありがたく、開発に必要なドメイン知識の理解とタスク起票からリリースまでの作業フローを分けて考えることができました。私が最初に振られたタスクはある画面の文言の一部を修正するというものだったので、私はこのタスクに取り組む間、以下のような点を理解できるように努めました。 - タスクはどのように起票されるのか - これから触ることになるコードはどのようなディレクトリ構成でどのような書き方になっているか - PRを作る時のフォーマットはどうなっているのか - どのタイミングで誰にレビューを受けるのか - 社内開発環境へのアップロード方法と本番リリースの手順について 3日目は上記タスクをリリースできる状態まで持っていって終了しました。 4日目 いよいよ最初の修正をリリースします。BASEのリリース作業は完全に ChatOps 化されていて基本Slack上のみでリリースが行えるようになっています。今回は修正内容が軽微だったので動作確認する項目もほとんどなく、スムーズにリリースに行うことができました。この時は入社してわずか4日目で最初のリリースができたことに感動しました。デプロイを高速・高頻度に行える工夫が随所にあり、新しく入った人でもリリースを行える仕組みがあったのでサービスの改善を高速に回していけそうだなと感じました。 5日目以降 5日目以降は時々入る新入社員向けの研修を除けば、オンボーディング感がグッと薄くなった感覚がありました。BASEの開発チームの多くはスクラム開発を採用していて、私のチームでもスクラム開発を行なっています。入社から1週間が経つ頃にはメンターやチームメンバーのサポートを受けながらではありますがスプリントバックログにあるタスクを普通にこなすようになっていました。スクラム開発に加わってからもSlackのオンボーディングチャンネルは存在していましたし、EM・メンターと毎週1on1が設定されていたので、疑問や不安を抱えたりすることはありませんでした。 オンボーディングで良かったところ ここからは私が体験したオンボーディングフローで良かったと感じた点を挙げていきます。 質問・相談しやすい雰囲気がある 前述の通り、BASEでは入社するとSlackに onbording-〇〇san チャンネルが出来ます。 分からないところや疑問に思ったことはこのオンボーディングチャンネルで呟くと、チームメンバーがこれでもかというくらい親切に教えてくれます。メンターの存在も相まって、 分からないことが出てきても大丈夫 という安心感がありました。 ドキュメントが整備されている 誰かに聞かないと作業を進められない状況がオンボーディング期間に起こると誰に聞いていいのかわからず、ストレスになりがちです。BASEでは業務で知っておくべきことは基本的に社内WikiかリポジトリのREADMEに分かりやすい形でまとまっているので、少なくとも私はこの事態に陥らずに済みました。普段からドキュメントをメンテしてくれる人たちに感謝しかありません。 社内の人と交流を持てる制度がある BASEでは メンターランチ という制度があります。これは新入社員が社内の人とランチした時に、その費用を会社が負担してくれるという制度になります。この制度を使って普段業務で関わることのない人と交流を持つことができました。リモート環境下で社内のつながりが希薄になる中、こういう制度があることはとてもありがたかったです。 今後より良くしていくために 私の所属するOwners Marketingチームは比較的最近発足した若いチームで、私の入社後にも2名ほどチームにジョインされた方がいました。短い期間でオンボーディングが立て続けに発生したので、躓きやすいポイントやドキュメントの意図が正しく伝わっていない点が徐々に明確になってきました。これについては現在ドキュメントやオンボーディングフローの見直しが進められていて、次に入社される方にはより良いオンボーディングを行えるようになっていると思います。 終わりに 冒頭にも書きましたが最高のオンボーディング体験でした。入社から1週間も経たないうちに最初のリリース、スクラム開発の参加、チーム外の人との交流と盛りだくさんの内容をこなせて充実した日々を過ごせました。 BASEは このブログ や Youtube , 技術カンファレンス等で積極的に業務で取り組んでいることを公開しています。私がBASEに入社するきっかけになったのもこれらのアウトプットから会社として取り組んでいることや課題について知ることができたからでした。この記事もまた「BASE気になってるけど入ったらどんな感じなんだろう」と思われる方の参考になってくれると嬉しいですね。BASEのサービスや技術的な取り組みが気になった方は、ぜひ他の記事やYoutubeも覗いてみていってください。 ここまで読んでいただいてありがとうございました! 明日は松雪さんの「Real World Full Cycle Developers」と@osushi_maguro さんの「ユーザーリサーチを活かしたメールマーケティング」の2本立てです!お楽しみに!
アバター
はじめに はじめまして。エンジニアの近藤( @kon_engineer )と申します。本記事は BASE アドベントカレンダー 2022 の6日目の記事です。 本記事では、私が苦い経験から学んだ、スクラム開発で未来の落とし穴を回避する考え方について書きたいと思います。具体的には、ユーザーストーリーの優先度を決めるとき、ユーザーにとってどれだけ価値を提供するかという視点だけでなく、プロジェクトとして何がリスクで、それを回避するために何からやっていくのか、しっかりバランスを考えるべきだった、という経験談を記載します。また、本記事で事例として記載するスクラム開発は、1スプリントごとにリリースする形ではなく、スプリントをある程度回して、大きな機能が出来上がったら都度リリースしていたスクラム開発の形式になります。 ユーザーストーリーについて ユーザーストーリーは、システムがユーザーに届ける価値を表現するものです。例えば、ショップオーナーは、管理画面で任意の配送可能日時を指定して、ショップに反映することができる、といった形で、登場人物が何をできるのか明確にするものであり、スクラムチームがスプリントで達成するべき重要なものと思います。 ユーザーストーリーの優先度について ユーザーストーリーの優先度を決めるためには、いくつもの考え方があると思います。私たちのチームでは、ユーザーにとって最も重要で、このストーリーがなければ後のストーリーは成り立たないものの優先度を高くしていました。この判断基準自体は間違っていなかったと思います。ただ、優先度としては後半に取り組むストーリーで、一度もチームメンバーが触ったことのない領域の開発がありました。その時は、優先度も高くないし、それほど難しい機能でもないから何とかなるだろうと思い、あまり注視していませんでした。これは良くなかったです。 リリース手前のスプリントで初めて大変さに気づく リリースも近くなったスプリントで、今まで経験がないBASEの領域の開発を行いました。その結果、修正量は少なかったとしても、その領域を深くまで理解していなければ影響範囲が読めず、開発が自分達にとって難しいことがこのタイミングで分かりました。結局、当初の見積りより倍以上の時間がかかってしまい、チームメンバーに助けられてなんとかリリースに間に合った、というギリギリの開発になってしまいました。開発を進めていくと実は大変だったというのはあるあるですが、元々知見がないのは分かっていたので、もう少しやりようがあったと思います。 どうすればよかったのか 懸念があるユーザーストーリーの優先度は上げる 今回の事例では、機能としての優先度が高くないストーリーであったため、詳しくない領域の開発を後ろに回してしまいました。しかし、プロジェクトとして事前に不確かな部分、不安な部分を早めに潰して安定した開発をすることは、ユーザーにとって優先度の高い機能を開発することよりも、時として重要であると考えます。なぜなら、懸念を後回しにすることで、プロジェクトの失敗確率が上がったり、全体の工数が伸びてしまうのであれば、長い目で見るとユーザーにとっても不利益であるためです。もちろん、ただ分からないからという理由で、闇雲に優先度を上げることはよくありませんが、プロジェクトの懸念が払拭されて成功率が高まるのであれば、今やった方が良いと思ったものは、優先度を上げる検討をした方が良いと思います。 懸念があるユーザーストーリーとはどういうものかについて、もう少し補足したいと思います。私が考えるものは、以下の図でユーザーストーリーBにあたるものです。 ユーザーストーリーの重要度はCの方が上であるが、ユーザーストーリーBは例えば使ったことがない技術を使用する必要があるとか、外部サービスと連携しなければならなくて、その調査が必要であるといったことで、考えなければいけない課題が多く存在するような状態です。この場合は、ユーザーストーリーCよりも先んじてBをやった方が良い場合があると考えます。 調査タスクを切る ユーザーにとって重要なストーリーから届けたい、しかし技術的に懸念があるストーリーなどは事前に備えておきたい場合に、当該ストーリーの調査タスクだけ切って、先に問題がないか確認することも有効だと思います。一度もチームメンバーが開発したことのない領域や技術であったり、技術的に実現できるのか分からない課題がある場合、後々何かしら問題が起きる場合があります。特に手戻りが発生して、すでに開発もしくはリリースしたストーリーに影響する事態は避けたいので、今取り組んでいる優先度の高いストーリーを安心して進めるために、事前調査して懸念を払拭しておきます。 ユーザーストーリーの優先度は常に見直す ユーザーストーリーの優先度は、最初に決めたら動かさないものではなく、状況によって柔軟に変更すべきものだと思います。今回の事例では、一度決めた優先度でそのまま開発を進めてしまっていました。ユーザーストーリーの優先度を見直す機会を設けていれば、そういえばこのユーザーストーリーは懸念はないかなど、改めて議論する場が用意されるので、もう少し早めに開発する上で懸念があることに気づけたかもしれません。 おわりに 本記事では、自分の経験を通じて、スクラム開発におけるユーザーストーリーの優先度決めについて記載いたしました。読んでいただいた方の助けに少しでもなれば幸いです。 明日はsatoshi_takemotoさんとtoshさんの記事が公開予定です、ぜひご覧ください。
アバター
はじめに 本記事は BASE アドベントカレンダー 2022 の6日目の記事です。 はじめまして!BASE株式会社で、ネットショップ作成サービス「BASE」のプロダクトチームのマネージャーをしている @yusaku と申します。記事を書くに当たって、自分がいままでやった1on1を振り返りつつ、数えてみました。   時期によってもちろん変動はあるのでざっくり試算ではありますが、社内では自分の組織でのメンバーや上長と週1回の15分〜30分の1on1、新しく入社して頂いた方がいるオンボーディング時では毎日15分の1on1を行っていたので、週5~15回くらい1on1していました。またプライベートでは、プロコーチとしてパーソナルコーチングも行っており、2022年では100回ほど1on1を行っていたので、 合わせて500回以上は1on1をしていました。 その結果わかった1on1で大事なこと を記事にしていきたいと思います。自分なりに大事なことを言語化することで、普段1on1をしている方の助けに少しでもなれば幸いです。 1on1ってなんだろう 最近では1on1に関する本( yahooの1on1 や、 シリコンバレー流1on1 )もよく目にするようになりましたが、そもそも1on1とは 「上司と部下が定期的に行う、”アジェンダのない”1対1のミーティング」 のことです。 一般的には週に1回、少なくとも月に1回の頻度で行われ、もともとシリコンバレーで生まれたマネジメント方法ですが、国内でも多く取り入れられています。 BASEでも、もちろん行われており、月1回30分以上行うことを推奨しています。 1on1ってなんのためにやるの? では、1on1はなんのために行われるのでしょうか? 進捗報告?  →いいえ。チーム全体でやったほうが効率が高いはずです。 目標設定?  →いいえ。すでに決まった目標であれば、ドキュメントでの共有でいいはずです。また目標は週ごとに変わるものではないですよね。 雑談?  →いいえ。雑談であれば、ランチや立ち話、懇親会でもよいのではないでしょうか。 1on1は「メンバーのための時間」 です。 個人的にさらに補足すると、気づきが生まれ行動や経験や学びが促進されるための時間だと捉えています。週1で30分の時間は1ヶ月の割合にしたらたったの1〜2%の時間でしかないので、1on1以外の時間における、行動や経験にどれだけ影響できるかが大事です。 話を聞けていない状態が最も危険 行動や経験を促進するメンバーのための時間である1on1にも関わらず、上司が話を聞けていない1on1が、最も危険な状態です。オンラインだからといって、Slackなどのコミュニケーションツールを見ながら相手の話を聞いていたことはありませんか? 話を聞けないと、信頼関係を損ない、心理的安全性が担保できず、下記の3つの危険な状態に陥ります。 リスクに気が付けない →心の声「ちょっと不安なことがあるけど言い出しづらいな、また今度でいっか。」 組織と個人のWillがどんどんズレていく →心の声「なんか納得言ってないけど、相談してもムダだし、話すのは控えよう」 新しいことが生まれない →心の声「やりたいことを思いついたけど、提案しても詰められそうだし、失敗したら怒られそう。相談するのは辞めていこう。」 このような状態にならないように、ここからやってみると良いというポイントを考えてみました。 相手の話をちゃんと”聞く”ことからトライしてみよう 大事なことは、相手の話をちゃんと”聞く”ことです。そのためには、 ①言葉以外にも集中して聞く ②反応する」 ③キーワードに気づく という3つのポイントがあります。このポイントからトライしてもらえると良いと思います。 ①言葉以外にも集中して聞く 人の話を聞くということに対して、実は3段階のレベルが存在します。 レベル1 相手の話を聞き(聞いたフリをし)ながら、自分のことなど相手以外のことを考えている状態です。例えば、「1on1中に、PCを開きながらSlackなどを追いながら聞く」のは、まさにレベル1の状態と言えます。 レベル2 ちゃんと相手の言葉を理解するべく話を聞けている状態です。このレベル2から話を聞いている状態と言えます。自分主体ではなく相手が主体であることが重要です。 レベル3 相手の言葉だけでなく態度や雰囲気も含めて聞く ことができている状態です。 例えば「大丈夫」という言葉1つとっても「大丈夫です…」「大丈夫です!!!!!」といった話し方や表情で、どういう気持ちで話しているかは違うはずです。(字で雰囲気を伝えるのが難しいですが) このレベル3の状態を意識して、話を聞くことが重要です。 ②反応する 話を聞くときに心がけてほしい次のポイントは、聞いている際に 「相槌」「オウム返し」「フィードバック」 といった、話を聞いている反応を行うということです。 例 相槌 :うなずき。「なるほど」「うんうん」といった反応 オウム返し :相手が行ったことをそのまま繰り返す反応。 ex)「ちょっと最近忙しいんです…」→「忙しいんだね」→「そうなんです。◯◯に追われてて〜」 フィードバック :相手の態度や雰囲気について言及するという反応。「今日はなんか楽しそうだね!」「なにか焦っているように見えるよ」 話に対して反応することは、話を聞いてくれているという 相手への安心感を生みます 。双方向に会話していく上で重要なことなので、最初はわざとらしいかもと思っても、まずはやってみることをオススメします。 ③キーワードに気づく 話を聞いていると、この単語ってどういう意味や意図で使ってるのかな?ということが必ずでてきます。知っている情報やバックグラウンドが異なるので、 人によって意味が異なる ことは多いです。 そこから認識がずれていくこともあるので、そういった単語をキーワードとして拾ってみて、「ちなみに、◯◯ってどういう意味あいで使ってる?」などと聞きましょう。そこから 認識をすり合わせて行くことが始まる ので、そういったキーワードを拾っていこうとする姿勢で話を聞きましょう。 話を聞くことによる変化 実際に自分が経験したエピソードを一例としてシェアします。(個人の話なのでかなり抽象的ですがご了承ください。) --- その人は、いつもいつもなにかに追われていて「忙しい」をよく口にしていました。1on1もシンプルに終わることが多く、1on1が進捗報告の時間になっていました。 ただ愚直に話を聞き続けた結果、少しずつ「なぜ忙しいのか」という自分の課題に対して話してくれるようになりました。 よくよく話を聞いてみると「期待に答えるために、自分がなんでもやらなければいけない」と思っていることに気づき、その結果「周囲に頼れていない」「自分で抱え込みすぎてパンク」している状態になっていることがわかりました。 そこからは、自分が完璧である必要はないことを強く意識して、周囲に頼むハードルを下げるために積極的にコミュニケーションを取るなど、周りの情報を取りに行く行動を多くするようになっていきました。 --- 1on1で話を聞くことで気づきが生まれたり変化が生まれたエピソードとして参考になれば幸いです。 まとめ 今回は話を聞けていない状態に対して、まずトライして欲しい3つのポイントについて記事にしてみました。 人の話を聞くことは、 相手への興味を持つこと 思います。相手に興味があれば、話は自然に聞けますし、相手に気づくことも増えます。ぜひ相手への興味を大事にしながら、相手の話を聞く姿勢に向き合ってみることから初めてみてください。 明日は satoshi_takemoto の記事が公開予定です、ぜひご覧ください。
アバター