Kyashの英語表示対応の意思決定ログ

この記事は Kyash Advent Calendar 2023 11日目の記事です。

Kyashの @konifar です。

2023年8月に、Kyashアプリを英語で利用できるようにしました。

www.kyash.co

もともと日本語のみだったサービスをリリース後しばらく経ってから英語でも利用できるようにしたということでして、リリースまでにはいくつかの意思決定が必要でした。

もしかしたら将来の自分を含めどこかの誰かのためになるかもしれないので備忘として残しておきます。

対応前のKyashアプリの状況

対応前のKyashアプリは次のような状況でした。

  • iOS / Android
    • Localizable.strings や strings.xml といったフレームワークの仕組みに従ってほとんどの実装は文字列の直書きがないが、一部直接日本語が書かれている箇所がある
    • 日本語が入っている画像もある
  • サーバーサイド
    • Goで実装され、いくつかのエラーメッセージなどは定義ファイルが分けられているが、ほとんどコード内に文字列が直書きされている
  • Web
    • サービスとしてのWebフロントはなし
    • コーポレートサイト・利用規約・ポリシーなどいくつか対応すべきところがある
    • FAQはZendesk
  • 事業
    • 国内の外国人労働者向けに価値を提供する施策がプランニングされており、労働者の受け入れが増える2023年9月までに対応したい

この状態から、2023年6月頭からやっていくことになりました。

1. 多言語化のためのサービスを使うか

リリースしたいターゲットの日にちがタイトだったこともあり、自前で対応を進める以外に WOVN.io などのSaaSを利用するかどうかを検討しました。機械学習領域の進化もあって、最近は選択肢が増えて素晴らしいですね。

次の5つを意思決定軸として評価し、結果として自前で対応を進めていくことに決め、経営やチームに宣言をしました。

  • 初期実装工数
    • 最初にリリースするまでの実装にかける工数
    • いつ何をどこまでリリースすべきかによって判断は変わる
  • 運用工数
    • リリース後の運用にかかる工数
    • 自前実装の場合に翻訳のフローをどうするかによって変わる
  • 運用金額
    • 運用するのにかかる金額
    • WOVNだと月額利用料が発生する一方で、自前実装だと実装ごとに翻訳料金が発生する
  • クオリティ
    • Kyashが多言語対応したと言えるクオリティを満たせるかどうか
    • 直近/将来に当たり前品質と魅力的品質のどこまでを求めたいか次第で変わる
  • モチベーション
    • 初期実装や今後の改善にあたってメンバーのテンションがアガるかどうか
    • 事業貢献はもちろん一番大事だが、エンジニアとしての経験なども考慮して決めたい

話自体は5月から進んでいましたが、ログを見ると最終意思決定のためのすり合わせを 6/7 (水) に始めて 6/8 (金) に意思決定していました。こういった意思決定のログが誰もが見れる状態で残っているのはよいですね。

2. 何をどこまで対応するか

「国内の外国人労働者への価値提供のベースとして、日本語以外でも利用できるようにする」という目的の認識は揃っていましたが、それを満たすために何をどこまでやるかを決める必要があります。

すべての画面で対応するのか、どの言語に対応しなければならないのか、数詞や通貨の表記も対応するか、文化も考慮したローカライゼーションまでやるのかなど、やることはかなり多いわけです。

BizチームのメンバーやProductマネージャーと一緒に話して、次のように意思決定しました。

  • 対応言語は英語、ベトナム語、中国語簡体、ポルトガル語の4つ
    • 基盤を作って英語対応からリリースする
  • 対応範囲を絞る
    • ミドルネームや姓名表記順の対応、数詞・時刻表記の対応、加盟店名の英語表記の対応などは、リリースターゲットを鑑みて対応しない

もちろん細かいところまですべてきっちり対応した方がよいのは間違いないですが、国内の外国人労働者向けという前提を鑑みると70点の対応でも十分価値を届けられるしビジネス的にも効果はあるという判断をしたということです。海外のサービスが日本語に対応したとき、多少表現に違和感があったり一部翻訳されていなかったとしても十分ありがたかったりしますよね。

これが 6/8 (金) に話して決まったようでした。こういった方針は最初に話してログを残しておくと後々役に立ちますね。実際開発中もちょいちょい参照することになったのでよかったです。

3. ユーザーの設定言語をどう判定するか

ここから少し実装に関連する話を決めていくことになります。

いまのユーザーがどの言語かをどう判定するかを決める必要があります。

Kyashでは技術的な意思決定のログを Architecture Decision Record (以下ADR) に残す運用にしていて、6/8 (金) にPropose Issueが作られました。議論と結論が細かく残っていくので気に入っています。

結果として、すでにサーバーサイドに連携されていた端末の言語設定をもとにサーバーサイドで判定することになりました。

この議論の中で、端末の言語設定ではなくサービスに言語設定を持たせるプランも出ましたが、リリースターゲットまでに必要ないと判断して採用しませんでした。やろうと思えば後から改善できる範囲ですしね。

4. サーバーサイドの各言語のテキストをどこに持たせるか

実装方法としてパッと思いつくのは各言語ごとのキーと文言をもたせた設定ファイルを持たせる方針でしたが、デプロイなくテキストを変更できたほうがいいのではという話もあり、どう実装するかをADRにあげて議論しました。

結果として、設定ファイルに持たせてガッと作る方針にしました。リリース後もそんなに頻繁に変えることはなかったですし、開発中も楽なのでこの方針でよかったと感じています。

5. サーバーサイドでどう実装するか

Kyashのサーバーサイドはいくつかのマイクロサービスに分割され、ほとんどのサービスではGoで実装されています。

通化含めて、どう実装していくかを決めていきました。

結果として、go-i18n を使うことに決めました。

また、言語用のサービスやライブラリで共通化することはせずに各マイクロサービスで実装することにしました。多少同じコードがあってもたかがしれていますし、具体的に対応してから抽象化を考えるほうがよいと判断したためです。

ちなみにこれらの意思決定にあたっては @tenntenn さんの次のSpeakerDeckがめちゃくちゃ参考になりました。素晴らしい資料です。

speakerdeck.com

6. DBのマスタ・トランザクションデータをどう対応するか

例えばカテゴリ機能のカテゴリ名など、マスタデータとして日本語が入っているものがありました。トランザクションデータも同様にいくつかあります。

これについてもADRに記載して、結果としてカテゴリ機能などいくつかの機能のみ対応することとしました。外国人労働者向けの価値提供を考えた時に、ここは最初から満たすべきというポイントをProductマネージャーとすり合わせた感じです。

意思決定材料として、全データベースの全カラムの型の中から文字列が入っているものの一覧をSpreadSheetに書き出すスクリプトを書き、全件チェックしました。こういったスクリプトはChatGPTやGitHub Copilotと一緒にやるとすぐできるので楽ですね。

7. リリースの方針をどうするか

稼働中のサービスの多言語対応には次のような特徴があります。

  • 対応範囲が広い
    • 想定漏れが発生しやすい
    • ビッグバンリリースになりやすい
  • テスト項目自体はシンプル
    • テスト実施に時間をかけやすい
    • テスト期間の見通しを立てやすい

どういう方針で開発を進めて動作を確認しリリースしていくかを 6/21 (水) に話して決めていきました。テストの計画やリリースの方針をプロジェクトの早めの段階で話しておくと、やることも明確になるしスケジューリングもしやすいのでよいですね。

これも例のごとく方針のたたき台を作って、ガッと30分くらいQAチームやProductマネージャー、開発チームと話して決めました。

結論としては、まずログインのエラーメッセージ1つだけを対応してデプロイまで持っていくことにしました。一時期ログインエラーメッセージだけ英語で表示されていた期間があったということです。デプロイは 6/26 (月) でした。

万が一のユーザーへの影響は最小限に抑えつつ、基盤が動くことは本番で確認するところまですぐいけたのでこの進め方はよかったと感じています。

8. 品質保証の方針をどうするか

同時並行で、品質保証をどうしていくかも決めていきました。

APIのテストを Scenarigo を使って追加して最低限のケースで英語の表記になっていることを保証し、あとは皆で触ってみる Bug Bash でカバーしていくこととしました。

また、翻訳文言のキーの間違いといったミスは機械的に拾うべきなので、Linterを作成してCIで動かすことにしました。

go-i18n の文言ファイルのチェックはこんな感じ。若干Kyashの運用に依存していますがgistに入れておきます。go/ast はとても便利ですね。

i18n_locale_file_checker.go · GitHub

キーの間違いや置換文字列のミスをチェックするのはこんな感じ。

i18n_key_checker.go · GitHub

iOSにもキーのミスがないかを確認するLinterを入れています。

localizable_strings_checker.rb · GitHub

iOSのLinterについては、LTの資料にもまとめています。

speakerdeck.com

Androidはキーが間違っているとそもそもビルドエラーになったり、キーが欠けているとAndroid Studioでワーニングが出たりするので自作のLinterは作っていません。優秀ですね。

こういった静的チェックは、最初に整備して入れて走らせておいて本当によかったです。今も元気に動いていますが、実装とレビューで頭を使うことが大幅に減っています。

7/6 (木) の Bug Bashでいくつかの未対応箇所が見つかり、やらないという意思決定をしたものもありました。


他にも、利用規約やヘルプページの対応、CSチームとの連携、翻訳のフローなどいくつかの方針を決定して、 7/27 (木) にいったんすべての対応を終えました。6月から約2ヶ月弱くらいですね。

言語化の対応としてはまだまだ不十分なところはありますが、事業上の目的は果たせましたし、ターゲットとしていた国内の外国人労働者にとってもよい改善になりました。

今回色々な事情があって自分がリードして進めていくことにしたのですが、サーバーサイドやiOS/Android、WebページやZendesk Helpなどひととおり対応していくのはすごく楽しかったです!

将来の自分を含め、どこかの誰かの参考になれば嬉しいかぎりです。