Gaudiy Tech Blog

Gaudiyの技術、開発組織、カルチャーについてお伝えするブログです

テスト文化はなぜ作れないのか?

f:id:hanahanayaman:20220225125959p:plain

こんにちは。エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでフロントエンドエンジニアをしているkodai(@r34b26)です。

Gaudiyでは、以前のtech blogでお伝えしたように、ATDDやフロントエンドのテストに取り組んできました。

techblog.gaudiy.com

ですが、正直にいうと、Cucumberを使ったフロントATDDは運用がうまく回っていません。

なぜ失敗したか? を振り返ってみると、「設計を変える(=テストを書く)こと」だけに注力してしまい、「コミュニケーションの構造を変えなかったこと」が原因だということに思い当たりました。

そこで今回は、テスト文化を醸成するためのコミュニケーション設計をテーマに、ブログを書いてみたいと思います。

テスト文化を組織に定着させたいけどうまくいっていないチームの方々に、ご参考になったら嬉しいです。

1. テストを書く意義とは

「品質を上げるか、開発速度を上げるか」

ここについては、以下のスライドにもあるように幾度も議論されているし、「質とスピードはトレードオフでない」という点には完全に同意しています。

質とスピード(2020秋100分拡大版) / Quality and Speed 2020 Autumn Edition - Speaker Deck

つまり、テストを書くことで、プロダクト品質も開発スピードも高めることができる。これは多くのエンジニアが理解していることだと思います。

ですが、テストの意義として、実はもうひとつの視点があると考えています。それは「チーム間、職種間のコミュニケーションツール」としてのテストです。

テストが「ドメイン理解者の定義する要件を満たし、その実行結果が正常であると担保されている状態で、実装者以外のすべてのステークホルダーが理解できる」という理想形であるならば、それを Single Source of Truth として意思決定することができます。

これは特に、チームの人数が増えてきて、コミュニケーション課題が生じてきた際に効果を発揮します。

なぜなら、通常はチームを分割すると、認知負荷が増え、組織全体の効率が下がってしまう傾向にありますが、テストをコミュニケーションの「インターフェース」として活用することで、必要最小限の回数での意思疎通が可能になるからです。

つまり、組織が最大効率でアウトプットを出すには、テストを介したコミュニケーションが重要だと言えます。

2. テスト文化はなぜ定着しないのか?

プロダクトの質も開発スピードも高め、コミュニケーションツールにもなる。こんな良いことだらけなのに、なぜテスト文化は定着しないのでしょうか。

これを「Conwayの法則」をもとに考えてみたいと思います。

"組織の設計するシステムは、その組織のコミュニケーション構造をそのまま反映した設計になる"(Melvin Conway)

テストに置き換えて考えると、

(すべて or 特定の) テストを書かないというソフトウェア設計になっている組織は、
(すべて or 特定の)コミュニケーションを必要としない/していないという構造を反映している

ということになります。

たとえば、スタートアップの創業期や新規事業が発足してまもない頃であれば、プロダクトの意思決定からデザイン、実装まで一人ないしごく少数で行うため、阿吽の呼吸が通用する場合も多く、コミュニケーションをそこまで必要としません。

開発者としての効率と質の向上が大事なフェーズであるため、そこにテストを採用すべきかは、その人の実装力以上の問題にはならないと思います。

ですが、順調に拡大してきた時には問題が生じてきます。

人数が増え、PdM/フロントエンドエンジニア/バックエンドエンジニア/デザイナーなどの専門性の分岐が進むと、コミュニケーション構造の変化が追いつかなくなります。

このコミュニケーション構造とチーム編成の変化速度のGAPが大きくなるほどに、明確にその状態がアプリケーションに反映されてしまうのです。

具体的には、

  • UIデザイナーの成果物からズレた実装が多発する
  • UXデザイナーが想定したものと違う挙動になる
  • バックエンドのAPIの形式がフロントエンドから扱いたい形と異なる
  • PMの定めたプロダクトビジョンと乖離したプロダクトになる

などが発生し、手戻りが頻発する。のちに大規模な再設計をしないといけなくなるといった負債が積もっていく。

このような状態になってから問題に気づき、TDD、ATDDのような手法の有用性に辿り着いたときには、あまりに多くの人の動き方を変えなければなりません。

”テスト文化を作る”ことに焦っている。その状態が、もはや失敗です。

3. テスト文化を醸成するための組織設計

つまり言いたいのは、表出した問題に対して、”テスト文化の醸成”という手法だけに捉われるから、テスト文化が定着しないのではないか、ということ。

冒頭でも触れたように、Gaudiyでも設計を変える(=テストを書く)ことだけに注力してしまった結果、フロントATDDの運用がうまく回りませんでした

何が起きてしまったかというと、

  • “受け入れ基準”をドメイン理解者と一緒につくることや、相互フィードバックをして調整することを怠ってしまい、テスト可能な受け入れ条件をつくることができなかった。その結果、テストを書かなくてもいい流れになった。
  • 視覚的にテスト対象のUIが見れなかったため、結局のところデザイナーはアプリケーションになったものしか見なくなってしまった。
  • ビジネスサイドの人に確認し、意図のズレを把握するような調整をしなかった。

つまり、コラボレーションを生むという課題に対して、ATDDという手段だけ導入し、コミュニケーション構造の変化に取り組まなかったことが原因でした。

では、どうすれば良いのか。先ほどのコンウェイの法則に対して、「逆コンウェイ戦略」で考えてみます。

つまり、

ソフトウェアの理想形から逆算した、組織のコミュニケーション構造を形成することによって、結果的に理想的なソフトウェアになることを目指す

逆コンウェイは一般的に有効性があると言われていますが、テスト文化の醸成にも、これが有効なのではないかと考えています。

手段としてのテストを導入し、一時的に実行できたとしても、組織を変えていかないとテスト文化は定着しない。であれば、組織のコミュニケーション設計を理想の形に変えることが、テスト文化醸成につながるはずです。

4. Gaudiyが失敗から得た学びと改善

ここからは、Gaudiyが失敗から得た学びをいかして、どんな改善に取り組んでいるかをご紹介します。

特に、フロントエンドのテスト改善としては、以下に取り組んでいます。

  • エンジニア以外が使い方や有効性を理解できる環境をつくる(完了)
  • レビューの構造と参加者を変更する(途中)
  • 受け入れ条件を調整する(途中)

テストを書くことや、良いテストであることは重視せず、現在はステークホルダーが実際に "参加する" ことにこだわっています。

特に、エンジニア以外が使い方や有効性を理解できる環境づくりに対して、実際に取り組んだ例を挙げてみます。

フロントテストでは、テスト結果の状態を誰でも見られるように、CSF3.0とinteraction storyを活用することがとても有効であると考えています。(詳細は、以下の記事が詳しいのでご参考ください。)

zenn.dev

zenn.dev

これをPRごとにstorybookをデプロイすることで、

f:id:hanahanayaman:20220225015930p:plain

f:id:hanahanayaman:20220225015945p:plain

このようにコードを理解していなくても、検証したいパターンを誰でも認識できるようにしています。

f:id:hanahanayaman:20220225020105p:plain

Defaultの状態

f:id:hanahanayaman:20220225020217p:plain

不適切なパスワードを入力したケース

これによって、どのstoryのどの挙動が、本来の意図とどのように違うのかを、誰でも指摘できるようになりました。

5. まとめ

今回は、テスト文化を醸成するためのコミュニケーション設計についてご紹介しました。

現在は、同じチームのフロントエンドエンジニアには意識の変化が起きていますが、まだデザイナーやドメイン理解者とのコミュニケーション構造までは変化しきれていません。今後は、ここを変えていきたいと思います。

テスト文化づくりやコミュニケーションを促進する仕組みづくりに興味がある人がいれば、ぜひお話ししたいです!

meety.net

Gaudiyの技術選定について知りたい方は、以下の記事をご参考ください。

techblog.gaudiy.com

GraphQLにおけるエラーハンドリングの実践

f:id:hanahanayaman:20220217214432p:plain

こんにちは。エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでエンジニアをしている高島(@takashima_katsu)です。

Gaudiyでは現在、BFFレイヤとしてGraphQLサーバを利用しています。導入してから1年以上が経ちますが、スキーマ駆動開発はDXの向上につながっていると実感しています。(以下のブログが詳しいです。)

techblog.gaudiy.com

今回は、GraphQLの利点を活かしたエラーハンドリングの方法について、Gaudiyでの実践をもとに書いてみたいと思います。エラーハンドリングの実装について課題感のある人や、現在GraphQL Errorsを使っている人に、ぜひ読んでいただけると嬉しいです。

1. エラーハンドリングとGraphQL

エラーハンドリングとは、プログラム実行時にエラーが生じた際に、すぐにその実行を終了させず、あらかじめ用意しておいた処理を行うことです。これをすることで、意図しない構造のデータが保存されたり、異常終了してしまう事態を防ぎます。

Gaudiyでは、GraphQLでのエラーハンドリングを行っており、そのベストプラクティスを探ってきました。

GraphQLの特徴は、データをモデル化し、スキーマとして定義することです。これによって、APIドキュメントなどを別途作成せずとも、クライアントがイントロスペクションを通じてスキーマの詳細を知ることができ、必要な情報を要求することができる、というメリットがあります。

GraphQLエラーハンドリングにおける一般的な手法としては、以下の errors エントリーにエラーの詳細を含める、GraphQL Errorsがあると思います。

{
  "errors": [
    {
      "message": "Name for character with ID 1002 could not be fetched.",
      "locations": [{ "line": 6, "column": 7 }],
      "path": ["hero", "heroFriends", 1, "name"],
      "extensions": {
        "code": "CAN_NOT_FETCH_BY_ID",
        "timestamp": "Fri Feb 9 14:33:09 UTC 2018"
      }
    }
  ]
}

これは GraphQL SpecのErrorsセクション から持ってきたものです。このエラー表現を、後述するエラー表現と区別するために、便宜上「トップレベルエラー」と呼びたいと思います。

トップレベルエラーは、GraphQL Specでも説明されていたり、GraphQLサーバの実装でよく使われる Apollo Server のドキュメントでも紹介されているので、よく利用されている表現だと思います。

しかし、ここで考えていただきたいのですが、これはGraphQLの利点を活かすことができているのでしょうか?

今回はその課題提起と、解決策としての実装方法について紹介したいと思います。

2. GraphQL Errorsにおける課題

GraphQLの利点は、先述の通り、スキーマとして定義することで、クライアントがイントロスペクションを通じてスキーマの詳細を把握できる点にあります。

ですが、トップレベルエラーには、このスキーマがありません。そのため、クライアント側がどういったエラーがあるかを知ることができなかったり、型の自動生成もできなかったりして、別途、ドキュメントの作成やコミュニケーションコストが発生してしまいます。

また実際に運用していく中で、エラーの追加や変更に気がつかず、フロントで適切なエラーフィードバックを出せなくなってしまったり、そもそもエラーによって細かくフィーバックを出すことが億劫になってしまい、抽象度の高いエラーフィードバックを出してしまうこともありました。

結果として、Gaudiyが大事にしている『Fandom』ではない体験の提供につながってしまったり、DXも悪くなってきていると感じていました。

また、 extensions エントリーなどでエラーを拡張したりと便利なことも可能ですが、これもスキーマ外で定義することになるため、同じように別途ドキュメントの作成が必要でした。

3. GraphQLエラーハンドリングの実践

こうした課題に対して、エラーもデータと同じようにモデル化し、スキーマとして定義する方法を取り入れていきました。このスキーマでのエラー表現を、トップレベルエラーと区別するために、便宜上「スキーマエラー」と呼びます。

ここからは、Gaudiyでは実際、どのようにスキーマエラーを実装しているのかについて説明していきます。

3-1. エラーの分類

まずは、エラーを分類します。エラーの種類によっては、今まで通りトップレベルエラーを使った方が良いケースもあり、Gaudiyでも多くのエラーではトップレベルエラーを利用しています。

具体的には、「例外エラー」と「ドメインエラー」の2つに分類しており、前者ではトップレベルエラーを、後者ではスキーマエラーを使用しています。この分類は、GraphQLの作者の1人であるLee Byronも、いくつかのissuesで触れています。

GraphQL errors encode exceptional scenarios - like a service being down or some other internal failure. Errors which are part of the API domain should be captured within that domain.

https://github.com/graphql/graphql-spec/issues/391#issuecomment-385553207

The general philosophy at play is that Errors are considered exceptional. Your user data should never be represented as an Error. If your users can do something that needs to provide negative guidance, then you should represent that kind of information in GraphQL as Data not as an Error. Errors should always represent either developer errors or exceptional circumstances (e.g. the database was offline).

https://github.com/graphql/graphql-spec/issues/117#issuecomment-170180628

「サーバが落ちている」などのシステム系のエラーは「例外エラー」に、「認証情報がない」などのドメインに関するエラーは「ドメインエラー」に分類するようにします。

3-2.ドメインエキスパートへのヒアリング

スキーマエラーの対象となる「ドメインエラー」は、その名の通り、ドメイン知識として扱います。

そのため、どのようなエラーが考え得るかについて、ドメインエキスパートへのヒアリングを通じて、チームで共有することが大事です。 Gaudiyの場合は、実例マッピングや受け入れ基準設定のときに、どういった失敗ケースがあるのかを洗い出しています。

その後、 どのようなフィードバックを出すのがユーザー体験として良さそうかを、CSやデザイナーと議論しながら進めています。

f:id:hanahanayaman:20220217211823p:plain
実際のチケット

これは、最近「シリアルコードを入力してNFTを受け取れる」という機能を実装した際の、実際のチケットです。実例マッピングをして、受け入れ基準の設定まで行いました。(Gaudiyではこのように、ユーザーストーリーベースでチケットに書くようにしています。)

どういった失敗ケースがあるのかをチケットの受け入れ基準に書いていますが、それをそのままスキーマで定義します。

"""
エラー: 該当しないシリアルコードの場合
"""
type CheckSerialCodeNotApplicable {}

"""
エラー: 既に使用されているシリアルコードの場合
"""
type CheckSerialCodeAlreadyUsed {}

"""
エラー: シリアルコードの入力回数が上限を超えている場合
"""
type CheckSerialCodeUsageLimitExceeded {}

3-3. Union を使った Result 型の作成

先ほど定義したスキーマをもとに、Result型を作成し、オペレーションタイプの返り値として返す方法を採用しています。

こちらの方法は 『200 OK! Error Handling in GraphQL』 で詳しく説明されているので詳細は省きますが、以下のように定義することができます。

type Mutation {
  """
  シリアルコードの入力チェック
  """
  checkSerialCode(serialCode: String!): CheckSerialCodeResult!
}

union CheckSerialCodeResult =
    CheckSerialCodeSuccess
  | CheckSerialCodeNotApplicable
  | CheckSerialCodeAlreadyUsed
  | CheckSerialCodeUsageLimitExceeded

"""
成功
"""
type CheckSerialCodeSuccess {}

"""
エラー: 該当しないシリアルコードの場合
"""
type CheckSerialCodeNotApplicable {}

"""
エラー: 既に使用されているシリアルコードの場合
"""
type CheckSerialCodeAlreadyUsed {}

"""
エラー: シリアルコードの入力回数が上限を超えている場合
"""
type CheckSerialCodeUsageLimitExceeded {}

この方法は、複数のエラーを同時に返せないなどの制約はありますが、シンプルな実装になっています。

また、複数のエラーを同時に返したい場合などは、『A Guide to GraphQL Errors』 の Error Union List の方法が参考になると思います。

mutation Mutation($serialCode: String!) {
  checkSerialCode(serialCode: $serialCode) {
    ... on CheckSerialCodeSuccess {

    }
    ... on CheckSerialCodeNotApplicable {

    }
    ... on CheckSerialCodeAlreadyUsed {

    }
    ... on CheckSerialCodeUsageLimitExceeded {

    }
  }
}

このようにスキーマエラーを使うことで、フロントはスキーマの詳細を知ることができ、 __typename の分岐でエラーフィードバックのハンドリングを行うことができるようになります。

4. まとめ

この記事では、Gaudiyで実践している、GraphQLのエラーハンドリングの方法についてご紹介しました。

エラーを「例外エラー」と「ドメインエラー」に分類し、ドメインエラーをスキーマとして定義することで、 DXの良いハンドリングを行うことができます。ドメインエラーはドメイン知識とイコールなので、ドメインエキスパートへのヒアリングを通じて洗い出していくことが大事です。

GraphQLの特性を活かしたエラーハンドリングの仕方として、ご参考になれば嬉しいです。この辺り興味ある方いれば、ぜひお話ししましょう!

https://meety.net/matches/YEieGYUZDYhr

Gaudiyの技術スタックやその選定思想については、こちらの記事をご参考ください。

techblog.gaudiy.com

エンジニアがCSチームとのコラボレーションで大切にしていること

f:id:hanahanayaman:20220207120112p:plain

こんにちは!エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでエンジニアをしている永井(@sho0910K)です。

Gaudiyではここ数ヶ月、CSチームとエンジニアチームのコラボレーションがうまく回り始めていると感じています。

GaudiyにおけるCSチームは、Gaudiyが提供するファンコミュニティでユーザーさんのサポートや体験づくりを担当しているチームです。 社内では「コミュニティチーム」と呼んでいますが、一般的にはCS(カスタマーサポート、カスタマーサクセス)チームが近いと思いますので、今回は「CSチーム」と呼ばせていただきます。

先日公開した2022年の抱負blogにある「プロダクト主導型組織」としてはまだまだ改善すべきところは多いですが、以前に比べればCSチームとエンジニアチームのコラボレーションは多くなってきており、CSチームを通してエンジニアチームにもユーザーさんの声がよく届くようになってきていると感じています。

そこで今回は、CSチームとうまくコラボレーションするために、エンジニアとして大切にしていることをご紹介したいと思います。

エンジニアとCSチームの連携がうまくいっていないと感じている方、プロダクトの改善がユーザーさんに届いているか不安に思っている方の改善の参考になれば幸いです。

1. CSチームとのコラボレーションで大切にしていること

より良いプロダクト開発を進めるためには、CSチームとのコラボレーションは不可欠です。その連携において、エンジニアとしては次のことを大切にしています。

  1. フィードバックをプロダクト目線で捉える
  2. ユーザーさんにプロダクトの改善を届ける
  3. エンジニア視点でのみ話さない

1-1. フィードバックをプロダクト目線で捉える

CSチームからはユーザーさんの率直な意見がたくさん共有されますが、これを受け止める際には「プロダクト目線」を大切にしています。

Gaudiyの提供するコミュニティアプリは、共通基盤をもつワンプロダクトですが、IPごとに別々のファンコミュニティとして提供されています。 そのため改善に関しては、特定のコミュニティでのみ考えるのではなく、コミュニティアプリというプロダクト全体に関わる改善として考えています。

そこで大切なのは、フィードバックとして挙げられた要望の背景をエンジニアとしても理解することです。 背景を理解した上で、最適な設計に落とし込めるようにPdM・エンジニア含めて議論しています。

1-2. ユーザーさんにプロダクトの改善を届ける

フィードバックを元にプロダクトの改善を行ったら、その改善をユーザーさんにきちんと届けることが大切です。 プロダクトの改善は、困っていたユーザーさんに改善された旨が伝わり、再度使っていただいた上で実際に改善されたとわかっていただくまでがゴールだと考えています。

これにはCSチームとのコラボレーションが不可欠で、「今回のリリースでは何を改善したのか」をCSチーム宛に連携することで、ユーザーさんにも改善の旨を伝えてもらっています。

1-3. エンジニア視点でのみ話さない

僕の所属するエンジニアチームでは、週の初めに一週間分の開発スプリントを決めていますが、このミーティングにはCSチームも参加しています。実際のユーザーさんの投稿を参考にして、優先度や対応する項目を議論しています。

この議論の際には、エンジニア視点だけで話さずに、実際にコミュニティを使う側を想定して話したり・技術的な用語を噛み砕いて話したりしています。

2. 以前はCSチームとのコラボレーションはうまくいっていなかった

そもそもの背景として、半年ほど前はCSチームとエンジニアのコラボレーションがうまく回っていませんでした。 具体的には、以下の課題を抱えていました。

  1. ユーザーフィードバックの優先度があがらない
  2. CSチームから声があがりづらくなる
  3. フィードバックに対応するエンジニアが偏る
  4. プロダクトの改善がユーザーに届いてない

2-1. ユーザーフィードバックの優先度があがらない

Gaudiyはまだまだリソースの多くない組織です。そのため、事業的な開発リソースと運用上でてくる改善や問題への対応のリソースの配分において、どうしても事業進捗に関わる部分の開発のほうが優先されている時期がありました。そんな中では、せっかくCSチームからあがった改善の対応に関しても優先度が上がりづらくなっていました。

2-2. CSチームからの声があがりづらくなる

開発のスプリントとして優先度が落ちてしまうと、スプリントを決める会において、CSチームから発言や改善要望がなかなかあがりづらい状況になっていました。実際、声をあげたとしても受け入れられるかわからないという感覚をCSチームに与えてしまっていたと思います。

2-3. フィードバックに対応するエンジニアが偏る

CSチームから声が上がりづらい状況になったために、突発的なフィードバックに対応するエンジニアも限られていました。当時はエンジニアチームとCSチーム間のコラボレーションも、限られたメンバーで行うなどの偏りがあったため、そこに関わっているメンバーしか自発的に動かないような状況でした。対応をお願いしたとしても「やらされている感」を感じさせてしまっていたと思います。

2-4. プロダクトの改善がユーザーに届いてない

さらに、フィードバックを受けてプロダクトに反映し改善版リリースを行ったとしても、それがユーザーさんに届いていないことがありました。 CSチームがその改善がリリースされたことに気づいていない、ユーザー告知するリリース内容から漏れてしまうといった問題がありました。

3. 改善のきっかけは率直なフィードバックを求めたこと

そんなモヤモヤした状況でしたが、その流れが吹っきれたのは、取締役でPdMを担う後藤からの「CSチームは率直にユーザーさんの声をエンジニアチーム宛に伝えた方がいいと思います」という一言でした。

僕自身もここにモヤモヤを感じていたため、すぐさま賛同しぜひにと相槌を激しく打ったものです。 そしてこの日を境に、Slackの#mimamoriチャンネルから来る通知の量が格段に多くなりました。

4. CSチームとのコラボレーションで実施してること

  1. ラフにユーザーさんの報告や改善を投稿できる場作り
  2. リリース内容の共有
  3. Whyの明確化

4-1. ラフにユーザーさんの報告や改善を投稿できる場作り

CSチームを通してのユーザーさんからの報告は気軽さを優先して、Slackのmimamoriチャンネルに投稿してもらうようにしています。 投稿のフォーマットも現在は設けておらず、かなりラフに投げていただいています。

f:id:hanahanayaman:20220207120042p:plain
#mimamori_改善報告チャンネルでの投稿

この投稿に特定のスタンプを付けることで、Shortcutというチケット管理ツールに自動登録されるようにしており、バックログリファインメントの際に確認できるようにしています。

4-2. リリース内容の共有

リリース内容の共有は、Slackのワークフローを使って情報連携を行っています。

f:id:hanahanayaman:20220207114254p:plain
リリース内容や開発担当者をSlackで連携

リリース内容を確認できるプレビュー環境も共有することで、今回のリリースでどのような内容が更新されるのかを、CSチームのメンバーが実際のプロダクトを触りながら確認できるようにしています。

4-3. Whyの明確化

CSチームから改善要望や施策の相談があがった際には、背景を理解することを意識しています。 その改善や施策が求められている背景は何なのか、一番良い解決策やプロダクトの将来性も含めて議論できるようにしています。

これに関しても、Slackの投稿スレッドでCSメンバーとエンジニア、そしてPdMを交えて活発にやり取りしています。

f:id:hanahanayaman:20220207115050p:plain
実際にWHYを確認するやり取りの一部

5. CSチームとのコラボレーションからの学び

以前はCSチームからの報告に対応するエンジニアは限られていましたが、上述したような工夫をしたことで、これまで参加していなかったエンジニアもCSチームとの会話に入ってきたり、報告をキャッチアップしてWhyを聞きに行ったりと、とても自律的に動くメンバーが増えてきたと感じています。

これはCSチームのメンバーが率直にユーザーさんのフィードバックを届けてくれるようになり、Slack上でのフィードバックや改善に対する議論が盛んになったからだと思います。

6. さいごに

Gaudiyのバリューのひとつに「Fandom」という考えがあります。これはあらゆるステークホルダーに最高のファン体験を届ける、というものです。

まだまだプロダクト主導型組織として足りてないところは多いと思いますが、ひとつでも多くユーザーさんにFandomを届けられるように、よりエンジニアチームとCSチームのコラボレーションを濃くしていきたいと思っています。

Gaudiyで一緒にユーザーさんにFandomを届けたい方(エンジニアやカスタマーサクセス問わず)や、CSチームとの連携で同じような課題感を持っているエンジニアの方、ぜひお話しましょう!

meety.net

Gaudiyの技術スタックやその選定思想については、以下記事をご参考ください。

techblog.gaudiy.com

システムの変動性の特定とアーキテクチャ設計

f:id:hanahanayaman:20220128221846p:plain

こんにちは。エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiyでエンジニアをしている勝又(@winor30)です。

Gaudiyでは、アイドル、ゲーム、マンガなどの様々なIP(知的財産権を有するコンテンツ)をベースにしたファンコミュニティを提供し、そのコミュニティ上で様々なサービスが利用できるような "スーパーアプリ" のようなプロダクトを開発しています。

このような特性のプロダクトづくりにおいて重要なのは、特定のIPコンテンツに特化させずに、どうやってコミュニティ上のサービスをつくっていくのか? という点です。

そこでGaudiyでは、よりスケーラブルでレバレッジの効いた開発をするため、ソフトウェアの原則を重視しながらも、コラボレーションを通じてプロダクトビジョンを捉えることによって、正しい技術的な意思決定をしていこうという考え方があります。

今回は、上述したような意思決定プロセスを、実際に開発した様々なデジタルアイテムの購入システムを例に説明していこうと思います。事業にレバレッジをかけることができるような拡張性のあるソフトウェア開発の参考になれば嬉しいです。

1. レバレッジの効いた開発に必要なことは?

最も大事なことは、プロダクトビジョンを捉え、将来の拡張性を予想することです。

一般的に、将来の拡張性を予想することはYAGNIの精神に反するため、XP的な考え方からするとアンチパターンのように思われます。しかし、投資的な開発を実現できるとのちの追加実装が楽になり、事業進捗を加速させることができます。

そこでGaudiyでは、エンジニアだけでなく、PdM、BizDev、コミュニティマネージャーなど様々なステークホルダーからプロダクトに関するビジョンや将来の方向性を徹底的にヒアリングし、それらを設計に落とすようにしています。

1-1. ヒアリングの方法

ヒアリングの方法は、できるだけコラボワーク(協働できる作業)を取り入れて、ステークホルダーの考え方やメンタルモデルをつくることに注力しています。このコラボワークは、現在だとストーリーマッピングやDDDによるドメインモデルづくりなどがあります。

(GaudiyのDDDの取り組みについてはこちらの記事が詳しいです。)

techblog.gaudiy.com

このときに様々なことをヒアリングするのですが、最も大事だと考えているのは、プロダクトのWHYと将来性をヒアリングしていくことです。この部分は後述する「カプセル化すべきシステムの変動性」に直結していく部分になるので、どういう変化があるのか? というところを様々なステークホルダーにヒアリングすることが重要です。

また、聞き方として気をつけていることとしては、以下の点があります。

  1. ステークホルダーが使った単語・言葉をそのまま使う
  2. 具体例を聞いたあとに抽象的な話を聞く

まず1点目については、ステークホルダーがイメージするモデルを、聞き手のバイアスなしでそのまま引き出すためです。相手が使った単語・言葉を聞き手が言い換えてしまうと少し誘導してしまう形になり、本来のメンタルモデルを汚してしまう恐れがあります。この考え方は「クリーン・ランゲージ」という書籍にある考え方で、どうやって相手のメンタルモデルを100%引き出し、バイアスなしで理解できるか? という方法になります。

この手法はコンサルタントやUXリサーチャーなどがよく使っているのですが、エンジニアのモデリングも本質的には同じだと考えており、相手のモデルを理解し、それをアーキテクトしていくことが良いシステムを作っていく上で大切だと考えています。ただ個人的にはバイアスなしにヒアリングを進めるのはかなり難しく、「こういうシステムになるだろうな…」と予想しながらヒアリングをしてしまうなど、認識の誤差が埋まらないケースなどもありました。

次に、具体例を聞いたあとに抽象的な話を聞くこともメンタルモデルの理解を深めるためのひとつの手段です。最初に同じように認知できやすい実際のケースを聞くことによって、その後の抽象的な概念を具体例と照らし合わせることにより、認識の誤差を減らしていくことができます。

1-2. カプセル化すべきシステムの変動性の導出

また、前述のヒアリングを通して「システムの変動性」を見つけることが、プロダクトにレバレッジを効かせるためには不可欠です。

この変動性とは、Righting SoftwareBuilding Microservices, 2nd Editionなどに書かれている、ビジネスドメインの境界を見つける手法の一つになります。

変動性をソフトウェアに適応するということは、変更される可能性がある領域を明確にし、その部分をサービスやシステムとしてカプセル化することで、その変化が他のシステムに影響を与えないようにすることを指します。

サービスの境界を見つける手法としては、DDDを利用して、Bounded Contextが境界になるやり方も存在するとは思います。ですが、変動性による分解を利用する方が、どういった変動領域から他のシステムを守りたいのか?という視点で境界を定められるので、より柔軟なビジネスドメインの境界を見つけることができる印象をもっています。

また個人的には、SOLIDの単一責任の原則と変動性のモチベーションがかなり近いと考えており、分解の手法としてはかなり有用なものだと考えています。

この変動性領域は「あとから変更できる」という意味合いではなく、「将来的にどういう変化をする可能性が実際にあるのか?」という点が大事です。そのために、PdMやコミュニティマネージャーにプロダクトビジョンをヒアリングしながら、「将来どういうことが行われるのか?」「この機能に対してどんなイメージをもっているのか?」などをエンジニアのバイアスなしにヒアリングしていき、どのような変動性があるのかを見極めていきます。

2. 様々なデジタルアイテムの購入に関する適用例

上記で説明したような変動性の導出を実際の機能開発で行ったので、そのプロセスや実際にやったことを説明します。

2-1. ヒアリングによる変動性の導出と技術的意思決定

f:id:hanahanayaman:20220130145151j:plain
デジタルアイテムの購入イメージ

今回開発した機能としては、様々なデジタルアイテムをクレジットカードで購入できる機能です。

この様々なアイテムとは、具体的に下記3つを購入できるようになっています。

  1. コミュニティ内で閲覧できるライブ配信のデジタルチケット
  2. コミュニティ内でデジタルアイテムがもらえるガチャを引くことができるガチャチケット
  3. コミュニティと連携している(Gaudiyが運営していない)ソシャゲのアイテム

これらのアイテムを、Gaudiyが提供しているコミュニティ内から同じようなフローで購入できるような機能を開発しました。

このプロジェクトで実際にステークホルダーに対するヒアリングを実施した結果、「購入条件の変動性」と「購入商品の変動性」が存在することがわかったため、この部分をカプセル化するようなモデリングの意思決定を行いました。

購入条件の変動性としては、コミュニティで販売するにあたって、コミュニティや外部アプリでの条件(ex. コミュニティレベルや外部アプリのアカウントを持っているか?など)がありました。この条件が増えていくことは、将来的にコミュニティで利用できる新しいエンタメの購買体験を作るというビジョンを持っていたため、必要があると考えました。

また購入アイテムの変動性は、販売するアイテムがコミュニティ内部のアイテムだけでなく、同一IPのソシャゲやECなどコミュニティ外のアイテムを購入できることもビジョンとしてあるため、アイテムが増えるという変動性から他のシステムを守りたいと考え、必要だと考えました。

2-2. Sagaパターン x Orchestrationで結果整合性を担保

f:id:hanahanayaman:20220128153040p:plain
Sagaパターンの正常ケースと異常ケース

変動性を導出した上で、今回は機能の特性上、どうやってアプリケーションとの整合性を担保するかを考慮する必要がありました。

一般的には、可能であれば整合性はDBのトランザクション等を利用してアトミックに行うのがよいとされています。

しかし、アイテムが外部のサービスの商品であったり、そもそも決済代行のAPIが外部のものを利用したりしていたため、今回は結果整合性を担保するような方針でシステムを作っていくことにしました。

そのため、マイクロサービスでの結果整合性を担保させるのに有用なパターンである、Sagaパターンを利用しました。結果整合性を担保したいワークフロー的な処理のどこかで失敗した場合は、全てのデータを元に戻すような補償トランザクションを送ることによって、結果整合性の担保を実現しています。

また、Sagaパターンを利用しつつ、OrchestrationとCoreographyの選択としてはOrchestrationを採用しています。

この意図としては、全体的な購入のワークフローにおいて、失敗したときに、直感的にロールバックを実行しやすく、シンプルな構成になりやすいためです。Coreographyの選択も社内で議論はしたのですが、最終的にピタゴラスイッチ的になり複雑化する懸念があったので、シンプルなアーキテクチャパターンの方を選択しました。

3. 実際の構成

3-1. アーキテクチャ

f:id:tkatsumat:20220131111529p:plain
実際のアーキテクチャ

基本的にupstream serviceとしてPaymentServiceがあり、downstream serviceとしてCheckService、GiftService、決済代行の外部APIが存在するようなアーキテクチャになっています。

ステータスの状態に関しても、どこで失敗したのかに関しては観測可能な状態になっているため、仮に結果整合性が担保できなかった場合でも、どこまでやり直せば良いのかがわかる仕組みになっています。

また、各サービスは購入のメインユースケース以外にも、クレカの登録や商品情報の表示、購入条件の表示などのユースケースに対しても利用されています。

3-2. ストラテジーパターンの利用

購入アイテムや購入条件の変動性によってチェックロジックが走る部分に関しては、ストラテジーパターンを利用し、インターフェースは共通にしながらも内部実装を種類ごとに分けていきました。

 

また、ソフトウェアの構成的にもストラテジーの選択と実行を分けて、より疎結合な設計にしています。

 

ストラテジーパターンを利用した意図としては、購入アイテムや購入条件の変動性をカプセル化したとしても、変動性による影響がソフトウェア内部で発生はするので、その影響を最小限に留めたかったためです。

この設計パターンを利用したおかげで、基本的には新しいものが追加された場合は、その実装クラスを選択するロジックとその実装クラスの内部ロジックを実装するだけでよくなり、より柔軟なソフトウェアアーキテクチャになりました。

4. まとめ

今回は実際にGaudiyで開発したデジタルアイテム購入の機能に関して、どんなところを気をつけながら事業のレバレッジを仕込めるようなものにしていったのかという点に関して説明しました。

事業を推進させるためのエンジニアの役割として、ステークホルダーのメンタルモデルを正しく探り、ソフトウェアの原則を正しく適用することによってレバレッジのあるアーキテクチャを作っていくことが、非常に重要だと個人的には考えています。

ただし、こういった取り組みはまだまだ試行錯誤している部分も正直あるので、こういった不確実な領域でアーキテクトをしていきつつプロダクトに影響を与えたい方がいれば、ぜひ色々議論していき、よりよいプロセスや原則を探っていきたいです!

meety.net

Gaudiyの技術選定とその思想については、以下の記事をご参考ください。

techblog.gaudiy.com

プロダクト主導型の組織をめざして(2022年の抱負)

f:id:hanahanayaman:20220117175240p:plain

こんにちは!エンタメ領域のDXを推進するブロックチェーンスタートアップ、Gaudiy共同創業者の後藤(@PTeamd)です。

Gaudiyは2018年5月に創業し、今年は5期目を迎える年になります。

創業当初からブロックチェーン技術を活用したプロダクト検証を行い、2020年からはSony Music社、集英社、アニプレックス社などの国内大手IPホルダーと協業。エンタメ業界の構造的な課題を解決するプロダクトを通じて、新しいファン体験を提供してきたGaudiyですが、2022年はさらに「PLG(Product-Led Growth)」(※)へと舵取りをしていきます。

今回のブログでは、その背景とGaudiyが今年注力することについてお伝えします!ぜひご一読ください。

※PLG…「プロダクトがプロダクトを売る状態(Product sells itself)」をめざす戦略

1. 創業時からめざすのは「ファン国家」の実現

2018年の創業時より、ファンの応援や創作といった熱量が適正に認められ、ファンに還元されるエコシステム「ファン国家」の実現をめざしてきました。

Gaudiyでは単にブロックチェーン技術をPoCで試すというやり方ではなく、トークンを使ったコミュニティプロダクトをファンに向けて提供することで、New Standardかつベストな体験を社会に普及する取り組みを進めてきました。

創業初期はブロックチェーンの顕在的なニーズが世の中にあまりなく、先行事例も少なかったため、PMFをめざす上で重要だったのは「いかに関係者に価値を理解してもらえるか」でした。

そこでまずは、クライアント企業に深く入り込み、個別の状況に対して理解と共感を深め、エンタメ企業に共通するペインを見つけながら、それを解決するプロダクトをつくる。そのプロセスが必要であり、意図的に「案件ベース」でのプロダクト開発を進めてきました。

具体的には、Sony Music社のデジタル声優アイドルグループ「22/7(ナナブンノニジュウニ)」や、週刊少年ジャンプの人気漫画「約束のネバーランド」など、大手IPホルダー(知的財産コンテンツを有する企業)との協業案件です。

その中で、ファンコミュニティサービスの開発・提供を行いながら、中長期的なファン国家のエコシステム構築をめざして、様々な”仕込み”を行ってきました。

例えば、そのひとつが「分散型ID(DID)」の開発です。ブロックチェーン技術を活用した独自のIDシステムを構築し、実際のコミュニティプロダクトにも組み込んでいます。

note.com

また、Gaudiyの経済設計顧問である慶大・坂井教授や、同じくコミュニティサイエンス顧問である早大・石川教授とともに、トークンエコノミーの経済設計などにも取り組んできました。

このように、エンタメ企業の課題を解決するソリューションをブロックチェーンベースで組みながら、新しい経済圏づくりに必要な研究と実装を行いつつ、SLG(Sales-Led Growth)での着実な成長を遂げてきました。

2. 昨年起きた市場の変化と「PLG」への転換

そして昨年、市場に大きな変化が起きました。

NFTを中心にWeb3.0が大きな注目を集め、世間からの認知度・関心度が一気に高まりました。ありがたいことに、Gaudiyも大手IPホルダーから数多くのお問い合わせをいただいています。

創業時からこのタイミングが来ることを信じ、案件ベースで様々な仕込みを行ってきたGaudiyにとって、2022年は勝負の年。今後大きく飛躍できるかどうかの転換点になります。

そのために注力していきたいのが「PLG(Product-Led Growth)」です。

f:id:hanahanayaman:20220117084942p:plain

SaaSプロダクトでよく聞く言葉ですが、良いプロダクトが次の顧客を呼び込むような、プロダクト主導型の事業成長モデルのことです。(PLGについて詳しく知りたい方はこちらの本がおすすめです。)

2022年は「ファンと共に、時代を進める。」というミッションに向けて、より多くのファンに「Web3.0の体験」を提供し、最高の体験を実現をめざします。

具体的にいうと、Gaudiyでは単にNFTを販売するのではなく、Non-Fungibleな体験を提供していきます。トークンエコノミーで最も重要とされる「コミュニティ」を形成し、そのコミュニティと従来は散らばっていた関連サービスをDIDで統合することで、ファンの活動に対して還元するエコシステムをつくります。

また、エンタメ企業の課題を解決する、IP独自のファンプラットフォーム「Gaudiy Fanlink」というプロダクトに全集中します。国内はもちろん、海内のIPコンテンツとそのファンに対しても最適な体験を一貫して提供することをめざします。

3. これからの「プロダクト主導型組織」について

PLG型で世界中のファン体験を前進させるために、組織全体としても、プロダクトに対してフルベットします。「Product-Led Organization(PLO)」という言葉もありますが、Gaudiyはプロダクト主導型の組織づくりに注力します。

プロダクト主導の成長・組織構築をしていくためには、ソフトウェアの開発だけでなく、ビジネス、コーポレートなどを含むすべての活動を、プロダクトビジョンへのコミットに紐付けて目標設定と戦略実行のできる体制が重要です。

その大方針として、以下3つに取り組んでいきます。

3-1. 全社でプロダクトをつくる

あらゆる活動を上位のプロダクトに紐付けて設計します。エンジニアリング、デザイン、ビジネス、採用、組織開発、広報、バックオフィスなど、あらゆる活動を個別最適化させずにプロダクト中心に組み立てることで、より良いプロダクトづくりをめざします。

例えば、これまでプロジェクトベースで動くことが多かったBizDevの活動も、いかにプロダクトの成功に紐付くアウトプットにつなげられるかを軸に進めていけるようにする。またtoC向けサービスであることから、プロダクトを触ったり、関連したプロモーションを見て興味を持っていただくことも多いため、採用・広報として伝えていきたいストーリーをプロダクト側でも汲み取り反映していく。

さらには、全社的に「プロダクトの成長」を目標にすると同時に、プロダクトサイドでは全ステークホルダーがプロダクトづくりを「自分ごと化」できるように、要望に共感し成果につながるよう支援することで、全員が一丸となってPLGにコミットできる体制をめざします。

3-2. 人間中心設計(HCD)を強化する

人間中心設計(Human Centered Design)とは、簡単に言うと「人のことを理解し、ユーザーにとって使いやすいシステムを設計する」ということです。 案件ごとに、個別のユーザーやクライアントに向けてプロダクトをつくることは、その要望も目標も個別の最適化が追求できたため、ある意味で対象への共感がしやすい側面もありました。

しかしながら、国内外のより多くのコンテンツとファンにプロダクトを提供していくと、汎用性をめざす必要性が出てきますし、関係者と直に接点を持てる度合いも制限されます。それにより、これまでよりも「共感」をベースとしたFandomな体験の実現が難しくなります。

そこで、より体系的な形でファンにとって最高の体験を作るために、共感をベースとしたプロダクト開発手法である人間中心設計を強化していきます。

3-3. プロダクトを作るように組織を作る

上記のようなプロダクト開発手法を、ソフトウェア開発だけでなく、組織も広義の”プロダクト”として、それぞれの手法を一般化して各所に取り入れていきます。

例えばチームトポロジーに代表されるように、カプセル化・抽象化・インターフェースの設計など、エンジニアリングの観点を組織開発にも取り入れて、組織フェーズごとに最適なアーキテクチャーをつくり続けます。

またUXデザインにおける調査・モデリングの手法を、エンジニアリングではDDDなどのバックエンドの設計手法に、採用ではEXの可視化・改善のために利用します。

さらにピープルマネジメントにおいて重要なコーチングの概念は、プロダクトマネジメントや自律分散的な組織マネジメント、カスタマーサポートなどコミュニティの運営にも共通のコミュニケーションスタイルを利用していきます。

4. おわりに

今回のブログでは、2022年の抱負として、PLG型の事業成長と組織づくりの方針をお伝えさせていただきました。

Gaudiyでは、ファンにとっての最高の体験を実現し、時代を進める取り組みをもっと加速させていくため、プロダクト中心組織を一緒に創りあげていきたいと思う方を全方位で募集しています。

職種や職務で分断された形ではなく、ビジネス・テクノロジー・ユーザーの3領域を横断してプロダクトを磨き続けることは、ある意味では個々の専門性に閉じて役割分担をするよりも大きな負担がかかり、難しいことです。

f:id:hanahanayaman:20220116220154p:plain

出典:The Product Management Triangle – Product Logic

ですが、まだ世の中にない世界観である「ファン国家」の実現に向けて、新しい概念や技術を取り込みながらプロダクト開発を進めるGaudiyにとっては、この形が必要不可欠だと考えています。

困難なチャレンジになるとは思いますが、プロダクト中心組織をつくり、2022年もビッグなIPと時代の先端をいく取り組みを進めていきます。

国内はもちろん、言語の壁を超えてグローバルで通用する突き抜けたプロダクトを生み出すことに興味のある方は、ぜひお気軽にご応募ください!ワクワクする未来を、共創していきましょう。

---

最後に宣伝させてください🙏 1月25日(火)19時〜、クラウドサインさんと一緒に「不確実性に向き合うプロダクトマネジメント」をテーマにしたウェビナーを開催します!Gaudiyの開発全般についてお話しするので、PdMの方はもちろん、エンジニアやデザイナーの方々もよければご参加ください。

bengo4.connpass.com

ほぼ全職種オープンしています。お気軽にご応募ください。

www.wantedly.com

いろんな職種のメンバーがMeetyをオープンしてますので、こちらからでも!

meety.net