セキュリティチームの日々の取り組みの紹介 (10X アドベントカレンダー 2024)

10xall.notion.site

10Xセキュリティチームの沢田(@swdyh)です。10Xアドベントカレンダー2024 の26日目の記事です。昨日は@yutatatatata さんの「商品データの裏側を覗く:意外に知らない商品IDの世界」という記事でした。自分も商品データに関する開発をしていた時期がけっこうあったので、奥が深くて面白いなと思って読みました。

先日、情報処理安全確保支援士の試験を受けたのですが、今日が結果の発表日でした。結果は不合格でした。JavaScriptのコードができてたり、画面を描く問題あったりして面白く解いてたはずだったんですが、午後の点数が57点で、あと1歩でした。またがんばります。

今日の記事では、セキュリティチームの日々の取り組みについて紹介したいと思います。

プロダクトの設計と実装レビュー

社内で書かれたDesign Docに一通りチームで目を通すようにしていて、気になるものあればレビューをするようにしています。また開発チームから、ここ気になるのでみてほしい言われることもあります。また実装されたときのコードレビューもやれる範囲でやっています。レビュー対象は、外部連携だったり、認証に関わるものが多かったりします。最近の事例だとOpenID Connect連携があります。

10x.co.jp

安全なサービスを提供するというのが第一の目的ではありますが、自分も元は開発をしていて、そういう大事な部分をつくるときには、これで大丈夫なはずだけど、、、みたいな不安を持っていたので、そういう開発者の不安を減らすこともできればと思っています。

プロダクトに関わる脆弱性アラートのトリアージ

GitHubの全リポジトリでDependabotのチェックを有効化し、新しくてできたアラートにに対処しています。さっと更新できそうなものは更新しつつ、そうでなくて影響がありそうなものは、issueを作って調査しています。

それとは別で、全範囲に適用できていないものの、Renovateを運用していて脆弱性のあるなしにかかわらず日々依存パッケージ更新できるようにしていて、こっちの更新でアラートが解消する場合もあります。

それから各リポジトリの更新できていないパッケージ情報集めるスクリプトを書いて、可視化するツールをお試しで作っていて、全体でどれくらい溜まっているとか、どのあたりのパッケージが手当されていないのかなどが分かるようにしています。

未更新パッケージの可視化

クレデンシャルレビュー

サービス連携などの使われるクレデンシャルを発行して使うケースで、それらの情報を記録し、管理方法や権限の強さや範囲をレビューするようにしています。過去、Secret Managerや1Passwordなどに用途不明のsecretがある状態になってしまっていたために、それはら棚卸ししつつ新規に発行するものにつては記録をしようということで始めました。クレデンシャルでできることは、その目的に対して最小限のものになっていてほしいところですが、そもそも細かく権限を指定できるサービスも多くなかったりして、大きめの権限を要求するサービス連携が多いのが悩み種だったりします。あとWorkload Identity Federationが普及してほしいなと日々感じています。Workload Identity Federationであっても適切に設定されているかのレビューは必要ですが、クレデンシャルそのものがないというのは安心ですね。

外部セキュリティアドバイザーとの相談会

セキュリティに関わる施策の相談や、設計レビュー、そのほか悩み事を相談をさせてもらっています。もともとチームメンバーがセキュリティ専門でないことを補うために始めた取り組みですが、悩みはつきないし、自分たちでは気づきにくい視点を得られるため大変助かっています。開発チームから開発担当者を呼んでいっしょにレビュー会をすることもあります。

アクセス制御不備チェック会

定期的に脆弱性診断を実施していますが、よく見つかるのが、本来アクセスできてはいけないデータにアクセスできてしまうケースで、パラメータのチェックが足りていなかったり、認可のチェックが足りていなかったりするものです。これに類似したケースは見つかってないだけで、他にもあるだろうということで、エンドポイントを1から眺めて同じようなパターンがないかを確認するという作業をはじめました。なかなか地味で果てのない作業なので、それぞれの担当場所のコードを読みながら、これどういうことなんだろうとか、ここちょっと危ないかも、みたいなことを話しながらやっています。実際に危なそうな箇所をみつけることもあり、成果もあるんですが、これをずっと続けるのはコストが高いので、ある程度読み進めた中で、いくつかパターンをまとめ、そういうこと自体がおきにくくする仕組みを作れないかみたいなことを考えたいと思っています。

セキュリティ輪読会

セキュリティに関する本やWebの記事を読みながら話合う会をしています。事前準備なしで参加者のた誰かが本文を読み上げ、気になるところがあれば都度話をしながら進めています。これもセキュリティの専門性を補うためにはじめた取り組みですが、ときどき仕事のなかでも「あの本のあれに書いてあった」ということもあったりしています。今年読んだものとしては以下になります。

これらの日々の取り組み以外にも、いろいろな施策をしていて、一部紹介の記事があるので興味のあるかたはこちらも見てみてください。

product.10x.co.jp

これからの話

今まではプロダクトセキュリティをメインに担当していましたが、それに加えて、コーポレートセキュリティ/コーポレートIT領域もやっていくことになりました。いくつかの経緯があってこうなったのですが、それぞれの領域は重なっている部分も多く、ソーシャルエンジニアリングやマルウェアなどの攻撃が高度化してるなかで、プロダクトという枠を超えていくことでやれることも多くあると思っています。

こんなセキュリティチームで、コーポレートIT/コーポレートセキュリティ領域メインに一緒にやってもらえる方を募集しはじめました。応募とまではいかなくても、少しでも興味があるかたは声をかけてもらえると嬉しいです。

コーポレートIT / 株式会社10X

[共通]カジュアル面談 / 株式会社10X

明日のアドベントカレンダーは、代表の矢本さんの記事です。おたのしみに。

商品データの裏側を覗く:意外に知らない商品IDの世界

本記事は10Xアドベントカレンダー2024の25日目の記事になります。メリークリスマス!🎄 🎁 🎅 🤶 🧑‍🎄

昨日はエンジニアの@futaboooさんが、『10Xも子育ても4年目のソフトウェアエンジニアが人生初EMになった話』という記事を公開されています。

膨大な商品データを眺めていて思うこと

こんにちわ!商品データチームの吉田(@yutatatatata)です。

私が所属するチームでは、ネットスーパーアプリ上で表示する「商品データ」を生成するデータパイプラインを開発しています。

複数パートナー様(10Xでは契約先の小売企業様をパートナーと呼んでいます)の膨大な商品データを日々触っていると、「パートナー横断で全商品をきちんと整理して並べてみたいなぁ」という気持ちが湧いてきます。

今回はそんなアイデアから商品のデータを整理して可視化してみた話を紹介します。

意外に知らない「バーコード」の話

普段スーパーなどに並んでいる商品には「JANコード」と呼ばれる商品識別IDが付いています。 世間的には「バーコード」と呼ばれているアレです。

商品コードはそれはそれでなかなか奥が深いですが、ここではややこしい部分は割愛して特徴をざっと紹介してみます。

JANコードとは

  • 定義:
    • JANコード(Japanes Article Numberの略)は、日本国内で広く使用されている商品識別用のIDで「どの事業者の、どの商品か」を表します。13桁の数字で構成されている「EAN-13」と、短縮版である8桁の「EAN-8」があります。
  • 桁数:
    • 13桁の数字(標準)と短縮版の8桁(小型商品用)

バーコードには13桁版と8桁版がある。パッケージ面積の小さい商品に8桁版が使われる。
図引用: https://www.keyence.co.jp/ss/products/autoid/codereader/basic_jan.jsp

  • 用途:
    • 日本国内の流通における商品管理、在庫管理、販売管理などに利用されますが、国際的にもEANコードとして認識されるため、海外でも使用可能です。

また、よりグローバルなGTINコードというものもあります。

GTINコードとは

  • 定義:

    • GTIN(Global Trade Item Number)は、GS1(流通コードの管理及び流通標準に関する国際機関。)によって定義された国際標準のバーコードで、商品やサービスを一意に識別するための番号です。JANコードはGTINの一部として扱われます。GTINは、地域や業界を問わず、世界中で使われる商品識別の基盤となります。
  • 用途:

    • GTINはグローバルに通用する商品識別コードで、輸出入を含めた国際的な取引でも使用されます。

違いのまとめ

  • JANコードは、日本国内の流通システムに特化したバーコードで、GTINの一部として機能する。
  • GTINコードは、JANコードを含む世界共通の標準として、商品を識別するために使われる。

簡単に言えば、JANコードは日本向けの識別コードであり、GTINはそれを含むグローバルな識別コードです。

普段何気なく見ているJANコードですがきちんと法則があり、先頭数桁は販売している企業を示す企業コードとなっています。そしてそのうちの先頭2桁はその企業の国コードを示しています。

先頭2桁は国コードを表す。日本のメーカであれば 45か49から始まる

日本の企業が販売する商品のバーコードは先頭が必ず 45 もしくは 49 で始まります。こういった商品は日本企業が販売している商品なので “ナショナルブランド商品” と呼ばれたりします。

なので、例えば輸入品オリーブオイルや韓国の食品などの海外食品のバーコードはそれぞれの国コードから始まります。

これでバーコードに詳しくなりましたね!今度スーパーに行ってみた際にぜひ確認してみてください。

10Xでは、スーパーのスタッフさんが商品をピッキングする際に使う便利なアプリも作っている関係で、パートナー様からそれぞれの商品のバーコードデータも受領しています。

バーコードには上記のような規則があるので、これを使えば一意に商品を識別できるIDとして使えそうです!

と、思うじゃろ?

ところがどっこい、厄介なバーコードたちがいます。

例えば↓

みんな大好きジャイアントコーンには複数の味がありますが全て「4901005312005」というJANコードになっています。

データ管理の観点からは、味ごとにユニークなJANコードが振られていてほしいですが、JANコードは「商品を完全にユニークに識別する」というよりは、「その商品を販売している企業が商品管理できるように」振られているようです。

そのため、「販売終了となった過去の商品のバーコードを再利用する」というケースもあり、時間的にも、商品的にも必ずはユニークにならないというなかなか難しい状態があるようです。

さらに、生鮮食品までこの話を展開すると、更に大変です。

生鮮食料品(野菜や肉など)は、個々の重さによって値段が異なるため各スーパー独自のコードを発行しています。このように店内でのみ使うコードをインストアマーキングといいます。

インストアマーキングの商品はその店内のみでしか販売しないため、JANコードとは異なりある程度自由に設定することができるようです。ただし、JANの国コードに対応する最初の2桁については、混同を避けるため20~29を使用するように決められています。

図引用: https://www.keyence.co.jp/ss/products/autoid/codereader/basic_jan.jsp

ここまで来ると「パートナー横断でJANコードをユニークIDとして商品データを統合する」ことが片手落ちになってくることがわかります。特に生鮮食品は難しそうです。

が、「結合が難しい商品もいろいろあるなぁ」ということを頭に入れつつ、とりあえず結合できるものは結合してみるかの精神でやってみます。データ分析あるあるですね。

商品の価格推移を出してみた

dbtとstreamlitで社内限定のダッシュボードアプリとして作成しています。

ナショナルブランド(バーコードが45,49から始まる日本の商品)に特に絞って商品データを整理してみました。10Xではサービス維持のため過去の商品データもある程度保持しているため、時系列データとして見ることもできます。

(注釈※10Xでは以下のような情報提供サービスを行っているわけではなく、あくまでデータ活用の可能性を考えるうえでの社内研究です。)

例えば、僕はここ数年毎朝お決まりのヨーグルトを食べていますが、そのヨーグルトの直近3週間ほどの価格推移を可視化してみるといろいろ興味深いです。

各パートナーで販売されている、とあるヨーグルトの3週間の価格変化

線は1つのパートナー様の価格推移を示しますが、同じヨーグルトでも日によってコロコロと価格が変わり、そして比較的価格差もあります。 ヨーグルトのような多くの人が日常的に購入する商品は、絶対値としては小さな金額差でも”あそこの店は高い/安い”という印象が残りやすい(”価格弾力性が高い”と表現される)ため、各社が価格競争を頑張っている雰囲気が伝わってきます。

ある1日における最安値との価格差を見てみても差が大きいことがわかります。

とある牛乳でも同じ雰囲気があります。赤い線のパートナー様は定期的にセールをしているんだろうな、など。

各パートナーで販売されている、とある牛乳の3週間の価格変化

他方で、とある缶ビール350ml缶は各パートナー様で固定の価格で販売されており、価格差もそれほど大きくありません。商品によって値段の付け方、売り方は様々だなぁと感じます。

各パートナーで販売されている、とある缶ビールの3週間の価格変化

最近は卵の価格が上がっているとニュースで聞くので、またその時系列データも見てみたいなと思いました。価格推移ひとつとっても、やはりデータを眺めているといろいろと思いつくことがあり面白いです。

小売データは堀り甲斐がある

いつもスーパーで見る馴染の商品のデータを触るのは単純に面白いですし、商品単位に整理されたデータは商品理解を深めるきっかけになり業務のいろいろな場面で役立ちそうです。また、単純に商品データ量が膨大であること、上述したような商品IDの難しい問題もありデータエンジニアリングの観点からも面白いテーマだと思っています。

私見ですが、この「商品を管理するID体系が微妙にイケてない」ことが小売企業のDXに少なからずブレーキをかけている面もあるんじゃないかなぁと感じています。中には、JANコードとは別に小売企業独自の商品IDを新規に振り直して管理されている気合の入った企業も見られます。現状のJANコード体系でも「店舗の運営」は可能かもしれませんが、デジタルによる業務効率化を行うには「(本当の意味で)商品単位でユニークに管理するID」が必要になると思っています。小売データの管理や分析は10Xの強みなので、このあたりもいい感じにしたいなと!

P.S. 最後に、私達 商品データチームが全パートナー様に対してどのように日々膨大な商品データを生成しているかの試行錯誤の歴史をまとめた90ページの気合が入ったスライドも公開しています。商品データのエンジニアリングに興味が湧いた方はぜひ御覧ください!

speakerdeck.com

(今回お話した商品データチームとは別職種ですが、)10Xではメンバーを募集しています!採用ページもぜひご覧ください。

まだまだ続くよ10Xアドベントカレンダー!明日はエンジニアのSawadaさんからプロダクトセキュリティーの取り組みのお話です!

本記事の参考:
GS1 Japan 一般財団法人流通システム開発センター
JANコードとは?JANコードの意味や作成方法などを紹介|ECのミカタ
JAN | バーコード講座 | キーエンス

人生初の在職エントリー

この記事は10Xアドベントカレンダー2024の22日目の記事になります。
昨日はSREの栗原さんが、Google Cloud IAM一時付与システムを「作らなかった」話という記事を公開しています。


こんにちは。10X 在籍1年目のQAエンジニア、こじしょー @KojiShaw です。
私の10Xの推しポイントは「オープンチャンネルが多く透明性の高いSlack環境」です。

実は今日、誕生日を迎えました。新しい1年に新しいチャレンジということで「人生初の在職エントリー」と題して、1月に10Xに入社してからのこの1年を振り返ってみたいと思います。(記念すべき初めてのブログ記事執筆です。)

入社の経緯

QAエンジニアとして

わたくし、QAエンジニア(以下、QAE)を名乗っておりますが、社会人キャリア16年半の中でQAEとしてのキャリアはまだ4年半です。前職からこの職種で働いています。

そのきっかけを作ってくれた一人が、アドベントカレンダー9日目に10Xに入って1年半でやったこと・感じたことという記事を公開しているブロッコリーさんです。前職の一次面接官の一人だったブロッコリーさんにより、私のQAEとしてのキャリアの扉は開かれました。

キャリアの転機・人生の転機

2022年の後半頃から、組織変更や異動が重なって求められる役割が大きく変化したり、一緒に働きたかった同僚が異動や卒業で離れてしまったりして、先々のキャリアについて考えざるを得ない状況になっていました。

さらに、年齢的にも節目を迎え、この先5年〜10年で起こるであろうライフイベント(身体の変化・生活の変化)にも自然と向き合うようになりました。コロナ禍が終息し多くの企業で出社回帰の動きが活発になる中、都心に住み続け都心に週の半分以上出社するフルタイム勤務に耐えうるのか不安を感じ始めた頃でした。

社内外の先輩・知人・友人に相談を重ねていたそんなとき、ブロッコリーさんが何だか楽しげに働いていそうだぞ、ということを聞きつけ、ご連絡してカジュアル面談をしてもらいました。

すると、私の好きなことに近い事業領域*1、噛みごたえありそう*2なプロダクト、QAEとしてやりがいがありそう、中長期で長く働けるよう配慮された制度がありそう...と10Xの魅力にグイグイ引き込まれてしまいました。

選考過程でQAEだけでなく、SWE・PdM・Designerにそれぞれインタビューする機会をいただき、そこで皆さんが品質に対しての思いや課題感を自分の言葉で語れること、QAEが求められていることを実感したことも大きかったです。

そして2024年1月、私も10XにJOINすることになりました。

開発体制と私が所属するチーム

10Xではドメインベースの開発体制を採用しており、ドメインごとの開発チームがあります。QAEは品質管理チームという横軸の組織に所属しつつ、各開発チームの中に入り込んで各チームの品質に関する幅広い業務を担います。

私は入社〜2024年3月までの3ヶ月はお買い物チーム、その後4月以降は店舗チームで活動しています。店舗チームはお買い物チームのドメイン領域を分割したチームなので、入社以来同じチームを担当していると言えます。

店舗チームはパートナーの店舗がネットスーパー・ネットドラッグストアを運営する上での各種管理機能を扱っています。例えば、お客様へ何時から何時までに商品をお届けするか・何件の注文を受け付けるかなどを定義する「注文枠」を作成や、その店舗からどの地域に配達するかを定義する「配達エリア」の登録などです。

入社当時の状況

お買い物チームに入った当初、既にチームには2人のQAEがアサインしていました。ただ、チームとの関わり方は以下のようになっており、もっと融合できる・もっとスクラムを組む ONE TEAM になれると感じました。

  • QAEのタスク状況はQAEのみが参加するQA朝会で会話され、チーム朝会(daily scrum)では必要なとき以外は特に報告していない
  • QAチケットのボードはチームボードと分かれている
  • Planningには参加せず、Planningの結果を後から把握してQAEのタスクを振り分けている
  • (全てのスクラムイベントに参加していないので)輪番で担当するスクラムイベントのファシリテーターもやっていない、ちょっとゲスト参加者っぽい

SWEとQAEのコミュニケーションは問題なく取れていますし、テストに必要な情報も双方向にやり取りをしながらきちんと取得できていて、問題が起きているわけではありません。

でもなんとなく、開発チーム内に専門のQAチームが別にあるような感じです。

この1年でやったこと

その1:QAEも含めた ONE TEAM を目指す

QA独自の活動をなくし、チームの活動に統合

まずはQA朝会を残しつつ、チーム朝会でQAの状況を報告することから始めました。

QAの状況をチームに伝えることで、特にEM(スクラムマスター)がQAタスクも含めたチーム全体の最適化をしやすくなるのではないか...

などと堅苦しい理屈を書くこともできるのですが、もっとシンプルに、朝会の場でQAEの存在感を出そうと思いました。それ以前も必要があれば朝会の場でQAEとSWEの会話はありましたが、アジェンダとしてファシリテーターが話を振ることで全員の注意が向き、そこにQAEがいる実感が生まれるのではないかということです。

また、お買い物チームから店舗チームに移行するタイミングでQAチケットをチームボードに統合し、QA独自ボードは廃止しました。SESで参画いただいていたQAEの方との確認用にQA朝会はしばらく残していましたが、その方の離任に伴い廃止して、今はQA独自の活動は残っていません。

Planningを含めた全てのスクラムイベントに出席する(ファシリもする)

Planningに参加せずにバックログだけ見ていると「どういう意思決定で開発着手するチケットを決めているのか」や「チケット同士の(隠れた)依存関係」などの計画に至る背景がわかりにくく、SWEとQAEの間でチケット毎の具体的な内容だけではない、もっと深い部分の認識の共有がしづらいと感じていました。

また、上述の背景がわからないことで先々の見通しも立てづらく、開発の早い段階からQAEが関わり、テストフェーズ以外のフェーズでもテストする取り組み*3に繋げにくいという課題もありました。

そこで、QAEもPlanningに参加するようにしました。これにより計画の背景が見えやすくなったのはもちろんのこと、Planningの段階でQAチケットについても必要に応じて会話できるようになったので、SWEも品質やテストに目が向きやすくなったと思います。

同時にスクラムイベントのファシリテーターのローテーションにQAEを組み込んでもらいました。チームの一員として役割を担っている意識にもなりましたし、ゲスト参加者っぽい雰囲気はなくなりました。

その2:開発のより早い段階からQAEも関わる

店舗チームでは今年、配達エリア移管機能という大物の機能開発に取り組み、12月初旬にリリースを迎えました。

この機能開発ではQAEを要件定義フェーズから巻き込んでもらうことができ、テストフェーズ以外のフェーズでもテストする取り組みを形にすることができました。

PdM、Designer、SWE、QAEが集まりオフラインでホワイトボードを使って議論しながら要件を固めていく場は長時間を要し、大変でしたが達成感があり熱かったです!

この場を通じて機能への解像度が高まっていたので、QAEのテスト分析は開発の初期段階で終えていました。その内容をSWEが機能を作り込む前にお伝えできたので、QAEが気になったポイントは機能開発を進める段階で取り入れられ、開発完了後のテスト指摘や手戻りをかなり抑えることができました。また、SWEがテスト内容を把握して事前に基本的な確認を行なってくれたので、テストフェーズでは複雑なパターンやエラーパターン、特殊なケースの不具合に集中でき、効率よくテストができていたように見えました。
(私は要件定義フェーズまで参加し、QAテストは別のQAEメンバーが担当しました。)

配達エリア移管機能のほかにも、複数の新機能開発の施策でこのような取り組みができ、早い段階からQAEを巻き込むことが店舗チームの型となって定着したと感じています。

その3:プロジェクト振り返りの企画・運営

上述の配達エリア移管機能は8ヶ月超というかなり長期に渡るプロジェクトとなりました。このようなプロジェクトでの学びを次に活かすべくプロジェクト振り返りが企画されたのですが、その振り返りでどのような手法を用いるかの提案や、その準備作業を 勝手に 引き受けて進めました。

振り返りは店舗チーム全員(SWE&QAE)、担当のDesigner及びPdM、さらに品質管理チームのEMとしてブロッコリーさんの総勢10名が参加予定です。しかし、全員が8ヶ月もの間、同じ密度・強度でプロジェクトに関わっていたわけではありません。途中からチームにアサインしたり、逆に関わりが薄くなったりしたメンバーもいます。このため、通常のスプリントレトロスペクティブで採用しているKPTだと個人間の認識の差が大きすぎ、チームとして振り返りにくいという懸念がありました。

そこで、タイムラインを用いた振り返りを採用するとともに、小チームに分かれたインタビューのプラクティスを取り入れることにしました。タイムライン上の付箋についてその要因やきっかけとなる出来事などを参加者同士がインタビューすることで、全員が共通認識を持った上で振り返りができるようにする狙いです。

...本来であればこの下に、その振り返りの様子を収めた写真を載せたり感想を書いたりしていた筈でした。しかし、私が直前にA型インフルエンザに感染し、出社できなくなったためリスケとなりました!!ああぁ...。

開催がこの記事の公開後になってしまい間に合わなかったのですが、こんな間の悪いタイミングで感染した私も参加すべきだからとリスケしてくれたチームには感謝しかありません!

この1年の満足度

この1年の満足度はかなり高く、とても良い形で1年を終えられそうです。

上述の通り、QA目線でチームに良い変化があったというのはもちろんですが、何よりそれを支えてくれる10Xのヒトに助けられました。

まずは店舗チームの皆さんです。私のような主張の強いQAEを受け入れてくれました。随分とグイグイ首を突っ込んでくるQAEだなぁと思われたと思いますが(笑)、とにかく ONE TEAM になってテストフェーズ以外でもQAEが当たり前にいるようにしたかったので、自分がわかりそうなところ・できそうなところにはとにかく首を突っ込みまくっていました。

そして、通常業務では関わることの少ないBizDevやCorpの方々。冒頭の推しポイントでも書いた通りオープンチャンネルが多いので、BizDevの皆さんの粘り強い仕事ぶりも、Corpの皆さんの心配りもSlackから知ることができて、勝手に他職種との距離がとても近いと感じていました。スタンプでリアクションするなどして距離感を縮めていたのでたまに出社した時や飲み会がある時に会話しやすく、10Xに馴染むことができました。

さらにはなんと、10Xを卒業した方々とも飲み会を通じて知り合うことができました。たまにカラオケに行くなど仲良くしてもらっています(笑)。

これだけ人の繋がりが広がることはあまりない経験で、今年はそのありがたみを痛感する1年となりました。

終わりに

なんだかめちゃくちゃ調子が良いまま何の曇りもない1年だったような文章になっていますが、実は一時は自分が価値が出せているのか、どう貢献できるのか不安で相当悩んだりもしました。悩みすぎて、一旦自分のできることを愚直にやろう、あんまり深く考えずにたまに自分を甘やかそう、そんな力加減も身につけて年末を迎えています。

2024年、なんとか走り抜けることができました。来年は他のチームでも何かしら良い変化を起こせるQAEでありたいな、と思うのでした。


10Xではメンバーを募集しています!採用ページもぜひご覧ください。
明日はビジネス本部の佐藤さん(kiyoseさん)が記事を公開する予定です。お楽しみに!

*1:料理が好きで、スーパーマーケットや八百屋・魚屋で食材の買い出しをするのが人生の喜びなのです。

*2:SIの基幹システム開発畑が長かったので、普段知ることのない企業内の業務オペレーションとプロダクト仕様が頭の中で繋がると高揚します。

*3:10Xが目指すQAの姿については少し古いですが、こちらの記事に記載があります。

Google Cloud IAM一時付与システムを「作らなかった」話

この記事は10Xアドベントカレンダー2024の21日目の記事になります。 昨日はBizdevの勝谷さんが「 全国のスーパーマーケットを回る10XのBizdevが出張で出会った美味しかったもの3選 | Notion 」の記事を公開しています。

はじめに

こんにちは、10X在籍3年目のSREの栗原です。 今回は、以前に検討していたGoogle Cloud IAMの一時付与システムについて、その設計思想と最終的に「作らなかった」理由についてお話ししたいと思います。

作ろうとした理由と、作らなかった理由

弊社では、Google CloudのIAM管理をTerraformで一元管理しています。TerraformはIaCとして優秀なツールですが、開発者が一時的に権限を必要とする場合、TerraformのPR作成、レビュー、マージというプロセスを経る必要があり、その体験は必ずしも良いとは言えませんでした。また、作業後に権限を削除をしなければ、そのまま権限が残り続けてしまうというセキュリティリスクも孕んでいます。

これらの課題を解決するため、一時的なIAM付与を自動化するシステムを検討していました。しかし、Google Cloud PAM(Privileged Access Management)の登場により、これらの課題は全て解決できると判断し、自作のシステム開発は見送ることとなりました。今回は、その供養として検討していたシステムの設計思想について共有させてください。

システム構成

今回検討していたシステムは、以下の図のような構成を想定していました。

API Server

API Serverは、クライアント(Slack botなど)からのリクエストを受け付け、IAMの一時付与を処理する中心となるコンポーネントです。APIリクエストには、以下のパラメータが含まれます。

  • 依頼者のメールアドレス
  • 付与したいIAMロール
  • 付与期間

API Serverでは、以下の処理を行います。

  1. メールアドレスのドメイン確認: リクエストの送信元が、許可されたドメインからのものであるかを確認します。
  2. JWT (JSON Web Token) の生成: ペイロードに、メールアドレス、付与するロール、付与期間を含むJWTを生成します。
  3. JWS (JSON Web Signature) の生成: Cloud KMSでJWTに署名を行い、JWSを生成します。
  4. 承認用URLの生成: JWSを含む承認用URLをクライアントに返します。

承認フロー

  1. クライアントは、API Serverから受け取った承認用URLを承認者に伝えます。
  2. 承認者は、承認用URLにブラウザでアクセスします。
  3. Cloud IAPによって、承認者のGoogleアカウントでのログインが必須となります。
  4. API Serverは、JWSの署名検証を行い、 その後JWSの有効期限を確認します。Cloud IAPから提供されるリクエストヘッダーに含まれるメールアドレスが、承認者リストに含まれているかを確認します。
  5. 検証が成功した場合、IAMを一時的に付与します。

IAMの付与には、IAM conditionを用います。これにより、指定された期間のみ有効なIAMを付与することが可能になります。

こだわりポイント

このシステムを設計する上で、特に重視したこだわりポイントは以下の3点です。

データベースレス

このシステムには、データベースが存在しません。データベースのメンテナンスやアップデートによる苦労を避けたかったこと、システムをシンプルに保ちたかったことが理由です。データベースレスでも、JWSを活用することで、システムとして破綻することなく、要件を満たしています。

JWSの利用

このようなIAM一時付与システムは、攻撃者にとって格好の標的となりえます。そのため、セキュリティを確保することは非常に重要です。このシステムでは、改ざん検知のためにJWS (JSON Web Signature) を採用しました。JWSによる署名検証を行うことで、リクエストの改ざんを検知し、不正な権限付与を防ぐことが可能です。これにより、外部からの攻撃に対する堅牢性を高め、システム全体の安全性を担保します。

承認フローの導入

IAMの一時付与には、承認フローが不可欠です。このシステムでは、承認フローを実装するために、Cloud IAP (Identity-Aware Proxy) を活用しました。これにより、承認者は自身のGoogleアカウントで認証を行うことができ、API Server側で複雑な承認ロジックを実装する必要がなくなります。さらに、発行される承認用URLには、有効期限(exp claim)を5分に設定しています。そのため、承認者が意図的に承認を行わない場合は、5分経過するとURLが無効となり、IAM付与が行われない仕組みとなっています。これにより、承認フローをシンプルかつ安全に実現しています。

Google PAMの導入と現状

今回、IAM一時付与システムを自作する代わりにGoogle Cloud PAMを導入し、最近その利用を開始しました。Terraformで google_privileged_access_manager_entitlement を定義し、利用者は必要なEntitlementsを選択して申請する仕組みを構築しています。まだ使い始めたばかりで、Entitlementsの種類は少ないですが、利用者のニーズに合わせて順次拡充していく予定です。

まとめ

今回は、Google Cloud IAMの一時付与システムを開発しようとして、最終的に開発を見送った経緯についてお話ししました。Google Cloud PAMの登場は非常に大きかったですが、その過程で考えたシステムの設計思想は、今後のシステム開発にも活かしていけると考えています。

検索エンジニアとして入社して1年でやったこと

この記事は10Xアドベントカレンダー2024の18日目の記事になります。 昨日はJOJOさん(@joj0hq)が「10Xのエンジニアとして入社から2年目を振り返る」という記事を公開しているので、そちらもぜひご覧ください。

はじめに

こんにちは、10Xで検索推薦の機能・基盤の開発運用を担当している安達(id:kotaroooo0)です。 2024年1月に入社し、もうすぐ1年が経ちます。 今回はこの1年間を振り返り、印象的だったプロジェクトをいくつか紹介します。

取り組んだプロジェクト

自分がリードしたプロジェクトをいくつか紹介します。 今回紹介する以外にもElasticCloudのオートスケーラー開発について以前書いたので参照しておきます。

product.10x.co.jp

類似商品検索の実装

商品詳細ページで、関連商品として類似商品を表示するようにしました。

商品詳細画面

Elasticsearchのmore like thisクエリで実装しました。

他の選択肢としては、ベクトル検索もありましたが工数、Elasticsearchへの負荷、技術的不確実性が高く、まずはmore like thisクエリで実装することにしました。

ただし、セマンティックな検索ができないという課題もあるため、今後改善していきたいです。

新しい検索精度モニタリングの導入

nDCGを活用してランキング精度をモニタリングできるようにしました。 これにより、既存のモニタリング項目(ゼロマッチ率、検索ごとのカート追加率、ヒット件数)に加えて、ランキングの精度も可視化できるようになりました。

これまで、検索改善は主にRecall(検索結果の網羅性)を向上させるフェーズでしたが、今後はPrecision(検索結果の精度)向上に注力していく必要があります。 これに伴い、ルールベースのリランキングやLearning to Rankを導入するためにランキング精度がモニタリングできる必要がありました。

BigQueryでキーワードごとのカート追加率を集計し関連スコアとし、nDCGを計算しました。 Looker Studioでダッシュボードとして利用し、可視化しました。

トップ画面での推薦枠A/Bテスト

推薦にも新しくチャレンジしてみました。

アプリのトップ画面に推薦枠A/Bテストを実施しました。 レジ前推薦でパーソナライズを導入し大きな効果がでたため、サービスの入り口であるトップ画面で推薦を提供することで平均注文額や平均カゴ点数の増加を期待しました。

トップ画面

アルゴリズム

ユーザーベース協調フィルタリングを採用しました。 ユーザーの購入履歴を元にユーザー間の類似度を計算しました。 ネットスーパーでは、繰り返し何度も同じ野菜、卵、牛乳等を買い続けるケースが多く、かつ注文点数が多いです。 そのため、単純に協調フィルタリングすると、どのユーザーにも人気商品を提案することになる問題がありました。

そこで、人気商品はそのユーザーの特徴量として扱わないようにしてユーザー間類似度を計算しました。 どれだけの人気商品を除外するかは、推薦結果が人気順に近づくのとユーザー間類似度の精度が落ちることのトレードオフです。 ここのパラメータはデモを実施することにより定性的な評価で決定しました。

アーキテクチャ

要件として、推論頻度を日次にしました。 ユーザーの購入履歴を元に推論結果が変化するアルゴリズムであり、ユーザーの購入は1日1回以内であることがほとんどのためです。

そのため、stailer-ml-pipelinesというVertex AI Pipelinesベースのパイプラインで日次でユーザーベース協調フィルタリングの推論をして、Firestoreに保存しておきます。 それをstailer-recommenderという推薦APIでServingします。

アーキテクチャ図

A/Bテストの結果は、ネットスーパーさんごとに異なり、他の商品枠との兼ね合いで推薦枠が効果を発揮する場合もあれば、そうでない場合もありました。 そのため、現在はプラットフォーム全体で推薦枠の表示を一律停止しています。 しかし、なぜ結果が異なるのかについて仮説を立てたり、トップ画面で特に効果的な枠について知見を得たりする良い機会となりました。

検索系RPCのレイテンシ改善

検索系RPCのレイテンシ(90パーセンタイル)をモニタリングしていましたが、基準を満たさず、アラートが頻発している状態でした。 このRPCはFirestoreとElasticsearchに複数回リクエストを送る構造になっており、どこがボトルネックなのかがすぐには特定できませんでした。

分散トレーシングを活用し、レスポンスタイムが遅いリクエストを数十件調査した結果、以下の2つが主な原因であることが分かりました。

ボトルネック

1. Firestoreへforループでのアクセス

Firestoreへのアクセスが原因で遅くなっている箇所を発見しました。 調査したところ、他チームが既に修正済みのコードが存在していたため、それを取り込むことで解決しました。 Firestoreのデータ構造を変更し、以前は複数回のクエリが必要だったものを、1クエリで取得可能な形に改善していました。

2. Elasticsearchのprefixクエリ

Elasticsearchへのクエリで、次のような空文字を指定したprefixクエリが発行されている箇所を発見しました。

{
    "prefix": {
        "hoge": ""
    }
}

この問題は、実際に生成されたクエリをKibanaのSearch Profilerでプロファイリングすることで特定しました。 期待外のクエリが発行されており、それがボトルネックになっていました。

対応策として、空文字の場合はprefixクエリを除外するように修正しました。

効果

対応の結果、対象の3つのRPCすべてでレスポンスタイムが改善し、アラートが発生しなくなりました。 それぞれの対応策リリース時にレスポンスタイムが期待以上に縮まってくれました。

レイテンシ(90パーセンタイル)

対応自体は比較的シンプルなものでしたが、、多角的な原因分析と対応策を列挙して比較したりとリアルISUCONできる貴重な機会でした。

Elasticsearchのバージョンアップ

Elasticsearch 7系から8系にメジャーバージョンアップしました。

課題

  • 7系ではElasticsearch単体ではベクトル検索できない
    • Vertex AI Matching Engineと組み合わせれば実現可能だが構成が複雑になる
      • Elasticsearchでフィルタ → Vertex AI Matching Engineでベクトル検索というフローはメンテナンス性が低い
      • Elasticsearchのみでベクトル検索ができれば、Elasticsearchのみで検索が完結し嬉しい
  • いずれ9系がリリースされるとEOLになる

互換性の調査

以下の項目について互換性を確認しました。

  • プラグイン: 形態素解析辞書や類義語辞書、ICUなど使用中のプラグインが新バージョンで動作するか確認。
  • Elasticsearchクライアント: アプリケーションが利用するクライアントライブラリの互換性をチェック。
  • 設定ファイル: mapping.json や settings.json の互換性を確認。
  • 利用機能: 非推奨(deprecated)となる機能や仕様変更をリリースノートで確認。KibanaのUpgrade Assistant機能を使ってダブルチェック。

リリース手順

Blue-Greenデプロイを採用して、本番環境でのリリースを進めました。

1. 新クラスタの作成

Elasticsearch 8系を使用した新クラスタをElasticCloudで構築。

2. 新クラスタへデータ更新導線連携

新旧クラスタに対してデータ更新をダブルライトで行い、データの一貫性を確保。 データ更新リクエストはPub/Subにキューイングされる仕組みです。 キューを処理するWorkerはKubernetes上で動いており、新クラスタ用にWorkerを新しいDeploymentとして起動し、旧クラスタ用Workerと並行して動作させれば簡単にダブルライトできるアーキテクチャになっています。

3. 検索導線の向き先切り替え

検索リクエストの向き先を旧クラスタから新クラスタに変更。 旧クラスタは障害時の切り戻しに備えて1週間程度保持。 障害が発生する可能性が高いのはここであり、切り戻し手順をリハしておきました。

4. 旧クラスタの除却

新クラスタの安定稼働を確認後、旧クラスタとそれに伴うダブルライトを除却。

バージョンアップによるパフォーマンス改善

機能面を目的にバージョンアップしましたが、非機能面でもパフォーマンスが大きく改善されました。

  • CPU利用率: バージョンアップにより半分程度に(StailerのElasticsearchはCPU bound)
  • 検索rpcのレイテンシ: 90パーセンタイルが半分程度に

これからの取り組み

LLMの活用

現在、検索機能へのLLMの活用を検討しています。 まずは、商品への自動タグ付けができないか検証しています。

例えば、「ヤッホーブルーイング よなよなエール 350ml」という商品があった時に、「クラフトビール」と検索してヒットさせたいです。 現状では、タグ付けは手動で行うか、同義語(シノニム)を登録することで対応しています。 これでは、気づかないとタグ付けやシノニム登録でできないし、追加する工数もかかります。

そこで、LLMを活用した自動タグ付けで、これらの課題を解決できないか検証しています。 GeminiやOpenAIのAPIの精度が向上しコストが低下してきているため、大量の商品でも効率的にタグ付けできる可能性が高まっています。

リランキング

これまでの Stailer の検索改善では、主に Recall を向上することに取り組んできました。 その結果、「検索結果の並び順は最適ではないかもしれないし、関係性の低い商品も含まれているが、欲しい商品は見つかる」という状態に近づけました。 次は、「関係性の低い商品は下位に、欲しい商品は上位に表示される」という状態を目指していきます。

将来的にはLearning to Rankに取り組みたいですが、まずはルールベースによる簡易的なリランキングに取り組んでいます。 これは、少ない工数でできるだけでなく、ルールベースによるリランキングをするためのプロセスがLearning to Rankにも生き、ステップを踏むことが無駄になるわけではないからです。

例えば、特徴量の分析や継続的な分析のためのオフライン/オンライン評価(デモ環境や精度モニタリング、インターリービングテスト)の仕組みなどはそのまま活用できます。

おわりに

この記事では、2024年の1年間を振り返り、自分が取り組んだ印象に残っているプロジェクトの概要を紹介しました。 これまでよくやっていた検索基盤の仕事だけでなく、推薦にも挑戦でき充実した1年でした。

明日は橋原さんの記事です!お楽しみに!

「スピード」と「こだわり」を両立したい!shadcn/uiとTailwind CSSを活用したゼロからのコンポーネントライブラリ構築

こんにちは、10X プロダクトデザイナーの日比谷(@suuminbot)です。

現在10Xでは新規プロダクトを複数開発している真っ只中ですが、私もその一環でshadcn/uiとTailwind CSSを活用しつつ、SaaSのサービス画面(管理画面)用のコンポーネントライブラリをゼロから構築していました。

少し前に一通り最低限必要なコンポーネントをFigma・実装ともに作りきり、現在は実際にそのコンポーネントライブラリを使って自分自身が複数のプロダクトのUIを作ったり、開発が進んでいる様子を見ているところです。

このブログでは、今回取り組んだことや学びをご紹介していこうと思います。

新規構築の経緯

10Xの主力事業であるStailerのサービス画面(小売企業の方々が利用する管理画面)はNuxt.jsとBulma(Vuefy)で作られています。今回の新規プロダクト開発にあたっては、@kitakさんが中心となりTypescript・Remixベースでの開発に移行することとなり、併せてコンポーネントライブラリも新しく構築する運びとなりました。

外部コンポーネントライブラリのあるある課題

これまでのStailerや、自分自身が過去携わってきたプロダクトでも、特にデスクトップ利用を想定した業務用Webアプリケーションは外部のコンポーネントライブラリを利用することがありますが、立ち上げそのものはクイックに済むものの、その後の運用で大きな課題を感じることが多かったです。

  • 用意されているコンポーネントライブラリ・デザイントークンだと不十分
    • 種類が足りない、見た目を変えたい等
  • コードとFigmaの一致を保つのが大変
  • コンポーネントの粒度が使いづらい
  • 何はいじれて何はいじれないのかよく分からない

自分たちのプロダクトに合った形のコンポーネントライブラリを、クイックに立ち上げたい

yamottyさんのブログにあるように、10Xでは現在小売企業の変革を推し進めるため、複数のプロダクトを開発しようとしています。(いわゆる"コンパウンドスタートアップ"なのか?)

そんな我々が過去の学びを活かしつつ今回の新規コンポーネントライブラリの構築で実現したいことは次の4つにありました。

  1. コンポーネントライブラリの構築そのものに時間をかけない
  2. こだわりたいコンポーネントは自分たちのサービスに合わせた形で作成・改修する
  3. デザインと実装の見た目と構造を一致させる
  4. 迷いなくデザイン・実装できる

「クイックな立ち上げ」と「こだわり」を両立できるshadcn/ui

他にもいくつかの選択肢がありましたが、今回我々はshadcn/uiを使ったコンポーネントライブラリを構築することとしました。

shadcn/uiは次のような特徴を持ったライブラリです。

  • 好きなコンポーネントだけを導入できるコンポーネントライブラリ
    • 従来のUIライブラリはフルパッケージのインストールを必要としますが、shadcn/uiは開発者が個別のコンポーネントをプロジェクトに直接コピー&ペーストできます
  • 柔軟にカスタマイズ可能
    • コンポーネントのコードはプロジェクトの中にコピー&ペーストして使うため、要件にあわせてスタイルや機能を柔軟にカスタマイズできます
  • ミニマムで使い勝手の良いデザイン
    • shadcn/uiそのもののデザインがシンプル・ミニマムでそのままでも十分使いやすいです
  • Tailwind・Radix UIをベースとした実装

ここからは、実際に取り組んだことをご紹介します。

1. Figmaでのセットアップ

まず最初にFigma側でコンポーネントを作っていくための基盤を整えつつ、ゴリゴリと我々に必要なコンポーネントを洗っていきました。

1-1. TailwindのclassをwrapするSemantic Tokenを用意する

shadcn/uiはTailwindを採用しているので、必然的に我々もTailwindを利用することになります。Tailwindは「ユーティリティファースト」を掲げており、次のようなユーティリティなclass設計を採用しています。

.text-slate-950 .text-2xl

こういったユーティリティベースな命名は汎用的ではあるものの、複数人のメンバーでデザイン・開発するにあたってはどこに何をどう使えばいいのかブレる原因となってしまうため、一部の要素については自社オリジナルの定義を使うことにしました。

現在自社オリジナルの定義を使っているのは、経験上特に利用回数が多くブレやすいタイポグラフィと色に関する指定です。*1

特にタイポグラフィでは、見出しと本文とで当てたいline-heightも異なるため、それらをまとめて指定しておくためにもカスタム定義をつけておくのは重要だと感じました。

1-2. Figmaにshadcn/uiのコンポーネントを起こしつつ、こだわりたいコンポーネントに調整・追加していく

shadcn/uiには公開されているFigmaライブラリが複数ありますが、多くのコンポーネントを自分たちで調整したり、新しく追加したりしたかったため、必要なコンポーネントのデザインをすべて自分で起こすことを選択しました。

まずボタンやフォーム系の基本的なコンポーネントを作った後、直近必要な画面のデザインを作り、その画面を作る過程で必要になった汎用パーツをライブラリ側に作り…の繰り返しで、一連の作業の中でこれが一番時間がかかったと思います。

現行のデザインシステムの反省点を踏まえて、特に汎用的で広く使うコンポーネントについては

  • サイズ設定
  • 色設定
  • サブ要素の表示オプションの追加

など、柔軟性高く利用できるようにしました。

1-3. 実装とFigmaの一致を追求する

Buttonコンポーネントのプロパティの例

すべてのコンポーネントでFigmaとコードの一致を追求しました。

一致させたいのは次のような項目です。

  • 見た目そのもの
  • コンポーネント名
  • プロパティ名

とても地道な取り組みですが、デザイナ・開発双方にとって恩恵が大きいと感じています。

  • 開発視点:
    • 開発(とQA)時の迷いが減る
    • 実装後の手戻りが減る
  • デザイナー視点:
    • コンポーネント設計にエンジニアからのFBを受けられる
    • より実装に近い形でプロトタイプによるUI検証を実施できる

2. コードのセットアップ

作ったコンポーネントのデザインにあわせてごりごりコンポーネントの実装(マークアップ)を進めました。

まずは追加したいコンポーネントをshadcn/uiからインストールしてきます。

npx shadcn@latest add button

このままカスタムすることがなければこれでもうコンポーネントが完成です!とんでもなく楽ですね…!

例えば上記のようなコンポーネントは、色やフォントの指定を独自のものに置き換えただけで、後はすべてshadcn/uiのまま使っています。

3. コンポーネントライブラリの構築にデザイナもコミットするための、ワークフローの取り組み

今回の一連の取り組みで最もこれまでのやり方と異なったのは、デザイナーもコードを書いてコンポーネントを作っていくという点です。

まずFigmaでデザインをし、それをマークアップし、ブラウザで触ってみて確かめ、違うなというところをFigmaに反映する…といった感じで、デザインと実装をスピーディーに行き来するのは立ち上げ期においてとても重要だと感じています。*2

そういったワークフローに関するその他のtryについてもご紹介します。

Storybookの導入

コンポーネントカタログとしてStorybookを導入しました。(SWEの@sinamon129さんがしゅっと導入してくれました🥹)

実際の画面を作らずとも、バリエーションごとにコンポーネントの表示やインタラクションをデザイナーが確認しながら実装調整をすることができるようになりました。

デザイナーが実際の画面を開発するとなるとまた少しハードルが上がりますが、コンポーネント単位での実装をより気軽に行えるようにしてくれたのでとっても感謝しています。

コンポーネントへのフィードバックをもらう

コンポーネントそのものへのフィードバックをお願いしたり、アプリケーション側を実装してみての使いづらい点を気軽に出してもらっています。

いつもフィードバックをくれたり、相談にのってくれる@ryo_ryoo_ryoooさん@kitakさん@sinamon129さんには感謝しかありません。

FigmaのDevモードの導入

VariablesにTailwindの値を入れているので、脳内での値変換も不要

これまで社内ではFigmaのDevモードを導入していなかったのですが、Figma側でコンポーネントのプロパティを実装と揃えたり、Tailwindの値を指定して作っているなら、それをエンジニアにもより簡単にキャッチアップしてもらいたい!と思いDevモードの導入を決めました。

コンポーネントのplaygroundもそうですが、そもそものデザイン指定の値がとっても見やすくなり、デザイナー・エンジニア間のコミュニケーションは相当にやりやすくなったと感じます。

現在社内でDevモードを使っているエンジニアは直近頻繁にフロントエンド開発をする方のみですが、アンケートを実施したところエンジニアさんからの意見もとても好評でした。

  • もうDevモードがない状態には戻れません
  • あった方がとても効率がいいので引き続き使いたいです🥺

(社内アンケートの自由記述からの抜粋)

作りながらデザインパターンとデザイン原則も決めていく

コンポーネントライブラリをサクッと立ち上げられたおかげで、自分自身も早い段階で新規開発する複数のプロダクトのUXやUIを組み立てていく業務に集中することができました。

その過程で、デザインパターンとデザイン原則の定義も進めることができ、複数プロダクトをまたいでの体験の一貫性や、気をつけるべきことを認識できています。

作りながら定義していっているデザインパターン

結論: 現時点ではとても良い!

技術的背景からこれまであったデザインシステムが使えず、ゼロからコンポーネントライブラリをスピーディーに構築せなばならない…となると、当初は「本当にできるのかな…?」ときっとエンジニアさんも不安に思われた部分が多々あったと思います。

蓋を開けてみると、技術選定のためのトライアルも含め2ヶ月ほど*3で一通りの構築を実現でき、実際に利用してプロダクトをゴリゴリ作っていくフェーズに入ることができるようになりました。また、当社に合った形のコンポーネントライブラリが構築できたなと感じています。

これから更に開発・運用が進みまた課題が出てくるとは思いますが、「一貫性を担保しつつスピーディーに画面構築ができるコンポーネントライブラリ」のため、今後も継続的に改善していけたらと思います。

10Xではプロダクトデザイナーを募集しています

現在マルチプロダクト化を推し進めている真っ只中で、デザイナーとして挑戦できることが多々あります!フルタイム2人目のプロダクトデザイナーとして一緒にやっていきたいという方を募集しています💥(コードが書けなくてもOKだし、書いていきたいという方もWelcomeです!)

  • 選考に興味がある
  • 転職するかは分からないけど詳細聞きたい
  • デザインシステム・コンポーネントライブラリのことについて話したい

…そんな方は是非お気軽にユートラもしくはXのDMから話しかけてください!

youtrust.jp

*1:shadow, border-radius についてはそのままTailwindの値を利用しています。

*2:社内にフロントエンド領域にフォーカスできる方が在籍していたら別かもしれませんが、弊社の場合スタートアップで一人が様々な領域に越境することが求められるというのも大きいなーと

*3:2ヶ月これだけやってたのではなく、新規プロダクトのUIデザインやその他の業務もやっていた

入社2年目QAの濃厚な日々

はじめに

こんにちは。
10X 在籍2年目のソントプ(@sontob8802)です。品質管理チームの一員としてQA業務に従事しています。

この記事は10Xアドベントカレンダー2024の13日目の記事になります。
昨日はUraさんが、プロダクトマネージャー向け野良ダッシュボードの活用方法という記事を公開しています。

個人的10Xの推しポイント

今年のアドベントカレンダーの共通テーマが「在職エントリー」となっているのでまずは10Xの推しポイントを紹介したいと思います。
弊社のSlackチャンネルには『all_cheers』というチャンネルが存在してまして、些細なことでも社員同士お互いのことをSlackで褒め合っています。
例えば

  • 「先日の○○の件、助けていただいてありがとうございました!」
  • 「○○で困っていたところシュッと対応してくださって感謝です」

などなど。
そういったポジティブな文化が根付いているのが個人的10Xの推しポイントですね!

これはどんな記事なの?

ソントプが10Xに入社してからの1年3ヶ月とちょっとを振り返る形で、10XにおいてQAとしてどんな成果を上げかつ何を学んで身に付けてきたのかをお伝えしていきます。

また10XやStailerには興味あるけどHPとかだとイマイチ見えてこない「QAがどんな仕事してるのか」「開発とどんな関わり方をしているのか」などについても触れているので気になってる方々はぜひ読んでみてください。

10Xは現在ドメインチーム制となっており、Stailerを大きく3つの領域に分けてそれぞれのチームで開発とQAを行っています。

ソントプは10Xの中ではまだまだ社歴も経験も浅いのですが、ドメインチーム制になってからQAの中で全チームを渡り歩いたのは(おそらく)私だけしかいないので(おそらく)私にしか書けないであろう各チームの特色やQAとしてやってきたことを書きつらねています。

入社してからのざっくりとした経歴

  • 2023年09月 入社後、お届けチームに配属
  • 2024年04月 諸事情あり休職
  • 2024年07月 3Dセキュア対応(一時的に無所属)
  • 2024年08月 売場 / お客様体験 / お会計チームに配属
  • 2024年11月 店舗 / 商品データチームに異動 〜現在に至る

各チームの特色とQAとしてやってきたこと

経歴を見てもらえると分かりますが1年ちょっとで全ドメインチーム(+α)を制覇しています。目まぐるしく環境が変わりながらも何とか食らいついてやってきました。そこでの成果というか個人的に学んだことや身に付いたかな〜といった事を順を追って振り返っていきます。

お届けチーム

お届けチームって何してるの?

お届けチームでは主にスーパーやドラッグストアで働いているスタッフさん(店員さん)向けのアプリの保守運用 / 管理を行っています。弊社内ではそのまま「スタッフアプリ」と呼んでいるのですが、ネット注文が入った商品を売場からピッキングしたり、配送に向けてパッキングしたりするために使用するアプリとなっています。

お届けチームでQAとして何してきたの?

チームに配属されて少し慣れてきてからピッキング機能を大改造する長期案件を担当することになりました。

この長期案件が個人的にはなかなかハードというか、とにかく影響範囲が広いのなんの… その案件において開発実装と並行してのテスト設計を試みたのですが、テスト分析で既存機能の棚卸しを担当エンジニアと一緒に行ってもテスト分析だけで1ヶ月ほど費やす結果となりました😵‍💫 そこからさらにテスト設計していく中で新たに出てきた疑問点についても話を詰めていったりしたことで、ここでも1ヶ月ほど時間を費やしてしまいました。

ここまでテスト設計に時間がかかった経験はあまりなく割とヒーヒー言いながら何とか業務を進めていた感じです。当時の私としては最速で業務を進めていたのですが、躓く箇所も多くどうにも思うような早さを発揮できませんでした。普通に私の作業スピードが原因で遅延してしまい、いろんな人たちに迷惑かけました😭

時間が経過するほどいたたまれない気持ちが募っていき精神的にもきつかったのですが、丁寧めにテスト設計を進めていたことと疑問点をすぐにエンジニアに聞けるチームの空気感もあり、何気なく質問したところからインシデントの発見に繋がったこともあったので時間をかけて取り組んだ事自体は無駄ではなかったなと思えました(時間かけすぎて遅延するのはもちろんダメですが)この『リリース前に未然にインシデントを検出できた』ことがこの長期案件での私の最大の成果だと思っています。

お届けチームでQAとして何を学んだの?

またお届けチームは1週間Sprintで作業を進めているのですが、この長期案件の影響範囲がなかなか広くテスト分析からテスト実施を終えるまでにトータルで4ヶ月を越えてしまいました。まわりが1週間でサクサクとチケットを片付けていくのを横目に置いてけぼり食らいながらもほぼやり切ったことで一種の自信に繋がったといいますか、メンタルが鍛えられた部分があります。具体的には『案件によって求められるペースは異なるからその見極めが必要』であることと『まわりのペースに引き摺られない』ということを意識しながら作業することの大事さを再認識させられました。

ここまでがお届けチームでの出来事です。この後3ヶ月の休職を挟んでチーム外の大型案件に合流することになります。

3Dセキュア対応

3Dセキュア対応って何したの?

(めちゃめちゃざっくりとした説明になりますが)3Dセキュア(もといクレジットカードの本人認証サービス)においてクレジットカード・セキュリティガイドラインが改訂されたため弊社Stailerでも3Dセキュア2.0の導入が必須となりました。このため元々のクレジットカード決済処理に機能追加を行うことになったためそのテストも行うこととなりました。

3Dセキュア対応でQAとして何してきたの?

休職明けということもあり最初からではなく途中参加の案件となります。すでに他のメンバーがテスト設計を終えテスト実施にも着手している状態から、QAとしての感覚を取り戻すことも兼ねてテスター的な立ち位置でテスト実施から合流しました。

割り振られたテストケースをひたすら実施していくという内容でしたが、3ヶ月空いたことでStailerの基礎的な仕様が頭からすっぽり抜け落ちている状態からのスタートだったためややスロースタート気味でした。ただ、ひたすらテスト実施に専念できる環境は休職明けの身にはそこまでの負担がなくて良かったです。

なので(テスト実施だけではありますが)QA業務の感を取り戻すことができたことがこの案件での成果かなと思います。

3Dセキュア対応でQAとして何を学んだの?

当時はQA歴9年目(現在は10年目)ですが、直接お金に関わる機能のテストをしたのはこの案件が初めてでした。テスト実施を通してお金まわりの「失敗できないピリピリした(もちろんいい意味で)空気」に少しでも触れられたのは1QAとして経験値を上げられて良かったと思います。

テスト設計段階から着手していればもっと経験値を上げられたとは思いますが、諸事情あり厳しい状況だったため致し方ないですね。

ここまでが3Dセキュア対応での出来事です。この後はテストがひと段落したこともありお届けとは違うチームに配属されることになります。

売場 / お客様体験 / お会計チーム

売場 / お客様体験 / お会計チームって何してるの?

この長ったらしいチーム名はなんぞや???と思う方も多いでしょう。

今現在のドメインチーム体制になる前はもう少し細かく領域が分かれていましたが、近い領域をなるべくまとめて新しくチームを作った結果上記のようなチームが出来上がったというわけです。

つまり元は「売場チーム」「お客様体験チーム」「お会計チーム」と分かれていたものが領域が近いこととQAの作業量等を加味した結果がっちゃんこすることになり、かつ良い感じのネーミングが出来なかったのでそのままチーム名もがっちゃんこしたままになっている、という訳です(ちなみに開発チームは別々のままQAチームだけがっちゃんこした状態になっています)

前置きが長くなりましたが、このチームでは主にネット注文をするユーザー(お客様)向けのアプリの保守運用 / 管理を行っています。弊社内ではそのまま「お客様アプリ」と呼んでいるのですが、アプリにログインするところから始まり、実店舗と同様に売場から商品をカートに入れ配達や店舗受け取りの時間を指定し商品を受け取るために使用するアプリとなっています。

売場 / お客様体験 / お会計チームでQAとして何してきたの?

基本的には売場案件の対応をしつつ、状況の応じてお客様体験 / お会計のヘルプに入るといった具合に業務に従事していました。

売場 / お客様体験 / お会計それぞれに窓口となるメンバーがいるのですが、私はそのメンバーの下で作業を振ってもらってとにかくこなしていく、というポジションにいました。

箇条書きになりますが具体的に何をしてきたかと言いますと、

  • 導入も兼ねたリグレッションテスト
  • 定期リリース対応
  • 細々した案件のテスト設計→テスト実施

体感的な割合としては7:3くらいでテスト設計よりもテスト実施の方が多かったです。QA歴9年目にして(あれ、テスターに逆戻りしてないか?🤔)と内心思いつつも大事じゃないテストなんてないのでとにかく愚直にテストしてました。テスト設計も全くやらなかった訳ではないので休職明けの練習みたいな感じで取り組めたのは良かったなと思っています。

なので(テスト設計含めた)QA業務の感を取り戻すことができたことがこのチームでの成果かなと思います。

売場 / お客様体験 / お会計チームでQAとして何を学んだの?

当時はQA歴9年目(現在は10年目)でしたが(2回目)ひたすらテスト実施をこなすというある意味初心にかえれたこと、それから自分なりのテスト設計方法を思い出せたことは一つの収穫でもありました。

また他のメンバーの仕事に向き合う姿勢を見ていく内に知らず知らず受け身になってたことに気付いたことで「ここままではいかん!!」となり、そこから積極的に動くためにはどうしたら良いかと(社会人十何年目にして再度)いろいろ思考錯誤を始めました。

ここまでが売場 / お客様体験 / お会計チームでの出来事です。この後また別のチームに配属されることになります。

店舗 / 商品データチーム

店舗 / 商品データチームって何してるの?

Stailerにはアプリだけではなく管理画面と呼ばれるWebシステムも存在します。

この管理画面ではアプリ上で操作できないことが操作可能なため、例えば

  • お客様アプリ上ではできない締め時間の過ぎてしまった注文をキャンセルできる
  • スタッフアプリ上ではできない誤ってピッキング済みにしてしまった商品のステータスを戻す

といったことが可能です。

また新規店舗の登録 / 編集や商品の登録など、店舗登録〜開店までの一連の操作も管理画面で行なっておりその他諸々を含めた機能の保守運用 / 管理を行うのが店舗チームの役割となっています。

また商品データはこれからQAが始まる領域になるので今のところは(少なくとも1メンバーの私は)特に何もしてない状態です。これからのお楽しみですね!

店舗 / 商品データチームでQAとして何してきたの?

まず最初にQAオンボーディングを実施していただくことになりました。具体的に何をしたかと言いますと、今後店舗チームで管理画面のテストをしていく上で知っておくべき必要最低限の知識を身に付けるための操作練習です。提携しているスーパー / ドラッグストア向けのガイドを参考にしてとにかく手を動かしていました。不明点・疑問点があればすぐに質問できるチームの空気感にも助けられなんとか一通りの操作を経験できました。

QAオンボーディングの次はペアで中長期案件のテスト設計に着手することになりました。10X歴が長くドメインの知識も豊富なメンバーとペアを組んで、開発実装と並行して仕様書のキャッチアップとテスト分析から入ることになりました。今まさにこの案件の対応をしている最中なのですが日に日にQAとして成長できているなぁと感じています。

正直まだ1人では開発実装と並行してのテスト設計は荷が重いですし、ドメインの知識も乏しいのでキャッチアップしていても漏れがあったりします。そのためテスト計画やテスト戦略を立てるところまでは出来なかったのですが、可能な限り隅々まで仕様書に目を通していたことでやり取りがストップしたままの要件を発見 → 開発に共有しPdMも巻き込んで仕様とデザインを固めるところまで作業を進めるきっかけを作ることが出来ました。開発実装中およびテスト分析段階で滞留していた要件を拾うことが出来かつ要件を固めるところまで話を進められたことが、店舗 / 商品データチームに異動してきてからの最初の成果と言えます。

年明けまでこの案件の作業は続きますが、引き続き1QAとして学べるところは学び吸収できるところは吸収して少しでも成長しながら、少しでもなんらかの成果を残していけたらと思います。

また、中長期案件のテスト設計が前倒しで進んでいるので合間に空いた時間には小さめの案件を1人で担当する予定です(執筆時点ではまだ未定)

店舗 / 商品データチームでQAとして何を学んだの?

スロースターターな私には領域の基礎知識を身につけるための「導入体制(ここではQAオンボーディング)」が不可欠なのだと改めて再確認できました。チームに入って動くようになるにあたり、マストで知っておかなければいけない部分をピックアップしてレクチャー&フォローしてくださったのはすごくありがたかったです。

また開発実装前あるいは並行してテスト設計していくに当たって具体的にどう動けばいいのかイメージを掴むことが出来たのも大きく学べた点でもあります。(SES時代含め)今までも開発実装途中でテスト設計をすることはありましたが、なんかしっくりこない、なんかモヤモヤした感じがありずっと自分の中で引っ掛かっていました。開発実装後のテスト設計の経験はそれなりにあったのですが、開発実装中からのテスト設計の経験はあまりなく具体的に実装後のテスト設計とどこがどう違うのか? どのタイミングで何をすれば良いのか? といった部分が明確に見えていませんでした。

それがペアでテスト設計を進めていくにつれて、今まで身につけたテスト設計との違いやどんな進め方をしていけば良いのかといった部分が鮮明になってきて自分の中にストンと入ってきた感覚がありました。上流からテスト設計してどう開発エンジニアと関わっていけばいいのか、今までフワフワしていた部分が噛み合った感じがしたんです。

そこらへんを具体的に言語化するレベルにまではなってはいないのですが感覚レベルでは色々なものを掴みかけている段階なので、このままこのチームでもっともっとQAとして成長していきたいですし出来ると確信しています。

おわりに

今年の9月半ばでQA歴10年目に突入しました。SESとして(良くも悪くも)様々な現場を渡り歩いてきた末に現在は10Xに辿り着きました。

入社してからの1年3ヶ月とちょっとを振り返ってみて色々やってきたなぁ〜と感慨深い気持ちになっております。まさに濃厚!この1年ちょっとを通してこうギュッと凝縮してStailerの基礎知識を叩き込まれたような感覚と「自分QAとしてまだまだだなぁ〜」と現実を思い知らされた感覚があります。今後はこの知見と成長意欲をうまく活かしてQAとしてチームに会社に貢献していけるように精進していきたいと思います。

また言語化してみて、入社してから経験したことを全然アウトプットしてなかったんだなぁとも思いました。思い出すのに苦労した部分もありますし、文章として書き出してみて文量がえぐいことになってしまった&書くのにも時間がかかり過ぎてしまったので定期的なアウトプットは大事だなと痛感しました。

このブログが10XでのQAの働き方に興味がある方にとって参考になれば幸いです。

 

10Xではメンバーを募集しています!採用ページもぜひご覧ください。
明日はSuzukiRyotaさんが記事を公開する予定です。お楽しみに!