この記事では、PayPayのポイントフローをウォレット領域から移行することを決定した背景と、その方法について説明します。
背景について
PayPayポイントは、主にPayPayのキャッシュバックシステムに関連するがそれに限定されない、PayPay内のお金と流れの仕組みです。2023年にPayPayでの支払いを分割できる機能がリリースされました。この開発中にウォレット領域をさらに細分化できる可能性があることに気づき、これがプロジェクトの全体的な方向性とも合致したのです。ウォレット領域におけるポイントの機能が、ウォレットの決済手段とは異なる独立した決済手段へと進化しているという認識による決定でした。また、この分離によりウォレット領域の複雑さが軽減され、特にキャンペーンやポイントフローに関する開発経験とエンジニアリングチームのアジリティが向上することが見えてきました。
既存のアーキテクチャ
移行前のアーキテクチャとウォレット領域のアーキテクチャの背景について説明します。
ウォレット&アカウント

ユーザーは1対1のマッピングで1つのウォレットを所有しています。 ウォレット内には複数のアカウントを保有することができます。 ポイントアカウントもその一つですが、以前はキャッシュバック(獲得履歴)と呼ばれていました。キャッシュバックはポイントを獲得する唯一の方法ではなくなったため、ポイントの現在の適用範囲を考えると、厳密には正確な名称とは言えません。
マネーの移動
ウォレット領域における取引は、複式簿記に基づいています。つまり、すべての引き落とし項目には、対応する入金項目があります。内部では、これらの項目を単に「マネーの移動」と呼んでいます。取引項目を極端に単純化すると、以下の表のようになります。
| id | src_user | dst_user | src_account | dst_account | amount |
| 1 | 123 | 456 | Account A | CASHBACK | 100 |
2PC API 設計
ウォレット領域でトランザクションを開始する際には、2段階コミット(2PC)API設計を採用しています。これは、トランザクションが完了するには2つの段階を経る必要があり、中断された場合はロールバックできることを意味します。例えば、キャッシュバック決済取引には、2つのAPIを叩く必要があります。
- /payment/prepare
- /payment/commit
取引をキャンセルする必要がある場合は、/payment/rollback API が叩かれます。 最終的な会計処理の記録、つまり加盟店のアカウントへの入金は、コミットが正常に完了した後にのみ作成されます。
導入のきっかけ
ウォレット領域が過剰な負荷を抱え、チームが本質的な技術的実現や改善に集中することが目に見えて難しくなっていました。特に、ウォレット領域がPayPayの基盤コンポーネントとしての役割を担っていることを考えると、チームが主要なテクニカル機能や改善に集中することが難しくなっていたのです。
- ウォレットとポイントに関連する機能は、プロジェクトやコードの競合による膨大なオーバーヘッドにより、作業がますます困難になっていました。ウォレット領域は、本質的には、2つの全く異なる領域を1つにまとめたモノリシックな構造になっていることから、移行を適切に実行さえすれば、別々に処理できるのではないかというアイデアが生まれました。
- ウォレットとポイントフローの結合により、卓越した技術を要するプロジェクトやシステム改善はますます困難になっていました。 ウォレットとポイントフローは徐々に別々の存在となり、異なる動作と成果を出しているにも関わらず、同じ基盤を共有する必要がありました。
- ウォレットとポイントフローのニーズが一致していなくても、インフラストラクチャを個別に拡張することはできませんでした。 同じデータベースとアプリケーションポッドが、まったく異なるユースケースに一緒に使用されていたのです。
目的
ウォレット領域における課題を踏まえ、私たちは目標の定義に取りかかりました。最初に取り組んだのは、対応すべき主要な問題を特定し、それらを解決するための最善のアプローチを決定することでした。私たちが着目したのは、ウォレット領域からポイント関連のフローをまず移行することでした。
基本要件
ポイント関連のフローを独自の領域に移行すれば、私たちが抱える多くの問題に対処できると考えました。このコンセプトは一見単純そうですが、既存のアーキテクチャとPayPayの規模を考慮すると、かなり複雑になります。 基本的に、ウォレット領域からキャッシュバックアカウントや、支払い、払い戻し、ポイント有効化のスケジュール、手数料など、ポイント関連のすべてのフローを抽出する必要がありました。 この分離により、ウォレット領域らポイントフローを独立して拡張できるようになり、新しいポイント関連機能の導入が円滑化されます。

移行における制約
既存のアーキテクチャと、信頼性の高いサービスとして欠かせない存在であるPayPayの性質を考慮し、この移行には慎重なアプローチが必要でした。 私たちは、これらの点を念頭に置きながら、慎重な設計と計画を優先しました。
スケジュール
PayPayを取り巻く環境は常に目まぐるしく変化し、お客様に最高の体験を提供するために、常に何かしらのプロジェクトが進行しています。この移行の完了に依存する新規プロジェクトに影響を及ぼさないよう、開発を確定し移行を完了させるまでの猶予はわずか8か月しかありませんでした。
段階的な移行
この移行は重要であると同時にリスクも伴うものでした。 移行プロセスでバグやエラーが発生しないよう、あらゆる手段を講じることを徹底しました。 ユーザーに予期せぬ問題が生じる影響を最小限に抑えるため、限定的なリリース戦略を実施しました。 このアプローチにより、すべてのユーザーを同時に新しいシステムに移行させるのではなく、段階的に移行を進めながらベータテストを実施し、新しいシステムの安定性を監視することができました。
ダウンタイム
データの完全移行と移行中のデータの整合性を確保する必要がありました。そのため、ポイントフローに関連するAPIとデータの切り替えには、短期間または長期間の停止期間を設けることが不可欠でした。 1回分のメンテナンス枠は確保していましたが、そのタイミングと期間は柔軟に変更することができない為、時間との戦いでした。 このようなメンテナンス枠は年に1~2回しかなく、PayPayの中核サービスに大きな混乱が生じることは許されません。PayPayはすでに、一般のお客様や加盟店様が日常生活のあらゆる場面で利用する、日本における重要なインフラとして広く浸透しています。
ポイント関連のフローには決済など主要機能に不可欠なものも含まれるため、ダウンタイム戦略を慎重に検討する必要がありました。そこで、ポイント関連機能の利用に限定し、他の主要サービスに影響を与えないのであれば、限定的なダウンタイムは許容であると判断しました。
設計
先に述べた要件と制約を考慮した上で、移行の設計と計画を開始しました。ここからは、設計方針とそれらの理由について、ハイレベルな概要を説明します。
データ移行のカットオフ
問題:データSSOTスイッチ

金融サービスプロバイダーとして、口座残高の誤りは決して許されません。常に信頼できる唯一の情報源(SSOT)を確保し、キャッシュバックとPOINTの口座が完全に同期している状態を維持する必要があります。また、更新されたフロー用の新しいAPIを導入する一方で、旧ウォレットシステムAPIとの下位互換性を維持する必要もあります。段階的な移行展開という目標と相まって、解決が難しい複雑な問題が浮き彫りとなりました。
キャッシュバックとPOINTのレプリケーションをほぼリアルタイムで実現することは比較的容易ですが、さまざまな制約により、いくつかの重大な課題が生じました。
- 信頼できる唯一の情報源 (SSOT):ウォレットシステムとポイントシステムの両方が同期して動作し、真実のソースは常に1つだけであることを認識する必要があります。
- 移行中のシステム間のインタラクション:下位互換性を維持し、段階的な移行を行うために、展開が完了するまでは2つのシステムが相互にインタラクションを続ける必要があります。ウォレットシステムは移行したユーザーについては新しいポイントシステムを参照する必要があり、一方、ポイントシステムはまだ移行していないユーザーについてはウォレットシステムをチェックする必要がありました。
- 移行前の検証:ユーザーの移行を開始する前に、次の2つの条件が満たされていることを確認する必要があります。
- 移行対象のアカウントに影響を与えるアクティブなデータベース・トランザクションがないこと。 ポイント決済の頻度が高いため、ウォレット・アカウント・データの保証は困難です。また、移行が完了するまでは新規の決済を受け付けることができません(多くのフローが同期しているため、単に操作をキューに入れることは現実的ではなく、それらを微調整すること自体に膨大な移行作業が必要となります)。
- 新しいシステム内のポイントのデータは、古いキャッシュバックのデータと同一でなければなりません。
絶え間なく更新されているデータを移行することは大きな課題であり、移行期間中の戦略的なカットオフが必要となります。目立った混乱を最小限に抑える方法を見つけましたが、それぞれのオプションにはトレードオフが伴いました。
アイデア:ダウンタイムのないアプローチ

最終的にダウンタイムのないアプローチは採用しませんでしたが、その検討プロセスを振り返ることは有意義であると思いご紹介します。特に注目したデザインのひとつに、マイグレーションジョブがありました。このアイデアは、古いアカウントを元のデータベースに残したまま、新しいデータベースにゼロ残高のキャッシュバックアカウントのコピーを作成するというものでした。これが完了すると、ユーザーに新しいポイントサービスAPIへの移行を促します。ユーザーの移行状況に応じて、ウォレットシステムがポイントシステムを信頼できる唯一のシステム(SSOT)として参照するか、またはその逆の方法をとります。また、移行状況は一元管理され、両システムから簡単にアクセスできるという仕組みです。以下は、取引の流れの概略です。

この期間中、バックグラウンドジョブがアカウントの移行を処理します。このアプローチが正しく実行されれば、PayPayのサービスに目立った中断が生じることなく、シームレスな移行が可能になります。各ユーザーのサービス中断時間は、下図に示されているように、移行ジョブの処理時間のみに限定されます。

しかし、このオプションを要件と比較検討した末、最終的には以下の理由により採用しないことを決定しました。
- 開発に多大な労力が必要:このアプローチは他の選択肢と比較して、はるかに多くの開発リソースを必要とする複雑なものでした。 混乱を最小限に抑えるというメリットがあっても、膨大な開発コストを正当化することはできませんでした。
- 品質保証コストの増加: 開発に多大な労力を要することは、品質保証コストの増加にもつながり、特に一度限りの移行を目的としていることを考えると、実用性が低いと考えました。
- 高まるリスク:実装の複雑性により、リスクレベルが大幅に上昇しました。実装に些細なエラーが発生しただけでも、深刻なデータ不整合につながり、多数の潜在的な障害ポイントが生じる可能性があります。
考慮すべき基準は他にもあり、最終的なアプローチについて説明する際に詳しく述べますが、これが別の方向性を検討する主な理由となりました。まとめると、ダウンタイムなしのアプローチにはメリットがあったものの、関連コストとリスクを勘案した結果、別の戦略を追求することになりました。
解決策:最終的なアプローチ
データ移行時に可用性よりも一貫性を優先させる場合、最もシンプルなアプローチは、PayPayシステム全体をオフラインにする包括的なメンテナンスウィンドウを設けることのように思われます。しかし、制約のセクションで述べたように、このオプションはPayPayには適用できません。そこで、私たちはいくつかの代替案を検討し、次の重要基準に基づいて慎重に評価しました。
- 開発作業
- 開発範囲
- 完全移行リリースの完了予定時刻(ETA)
- ロールバック計画 の複雑性
- 混乱の度合い
- リスク評価
これらの基準に基づいて選択肢とそのトレードオフを慎重に検討した結果、私たちは「部分メンテナンスアプローチ」を採用することにしました。この革新的な戦略は、特に利用の少ない時間帯に顧客のポイント残高へのアクセスを一時的に制限しながら、PayPayの重要な機能を維持することが可能です。当社の既存のUIコンポーネントとインフラストラクチャを考慮すると、このアプローチは比較的範囲が狭く、実装も容易であることが分かりました。完璧なソリューションとは言えないかもしれませんが、基準に合致しており、バランスの取れた妥協案を策定することができました。
次に、この部分メンテナンス戦略の詳細の設計と計画に取り掛かりました。このソリューションは、段階的な移行ロールアウトと連動しており、各段階で複数の部分メンテナンスセッションを実施し、段階毎に一部のユーザーグループを移行します。メンテナンス中は、各ロールアウトの対象ユーザーのみに影響が生じます。以下は、メンテナンス手順の主要な概要です:
- メンテナンス開始の約20時間前に、対象ユーザーにメンテナンスバナーを表示。
- 影響を受けるユーザーに対して部分メンテナンスモードを有効化。この間、ポイントの利用は不可。
- 進行中のキャッシュバック処理がすべて完了または終了していることを確認。
- データの検証チェックを開始。
- 対象ユーザーの移行構成を更新し、新しいデータベースでキャッシュバックからポイントに切り替え。
- 部分メンテナンスモードを無効化。
- メンテナンスバナーを削除。
このプロセス全体は、2時間以内で完了するように設計されています。私たちは、リリース前のデータの一貫性の検証を実施することで、このアプローチに対する自信を深めました。このソリューションは、移行中のデータの一貫性に関するリスクを効果的に軽減すると同時に、お客様への影響を最小限に抑えることができるのです。

データ移行
問題:データ同期と整合性の課題
ウォレットポイントからキャッシュバックアカウントへの移行の際には、データの整合性を維持することが極めて重要です。ポイントサービスが取引を処理している間に、ユーザーが旧ウォレットシステムを触ると、両方のデータベースで同時に更新が行われた場合に、データの不一致が生じるリスクが生じます。
解決策:二重書き込みと突合
ウォレットサービスが古いウォレットのキャッシュバックデータと、ポイントで消費されるKafkaトピックの両方を更新する二重書き込み方式を導入しました。これにより、変更が両方のシステムに確実に反映されます。定期的な突合プロセスで不一致がないか確認し、正確な決済確定を保証します。
メンテナンス戦略
部分メンテナンス中は、対象ユーザーがメンテナンスモードに入り、効果的なデータ管理が可能になります。
- 未処理のトランザクション:メンテナンス中に未処理のまま残ったトランザクションは、その後再試行され、重複することなく正確な処理が保証されます。
APIの移行
問題:フロースイッチ

ポイントは以前はウォレットシステムの一部であり、他のウォレットアカウントとともに存在し、単一のAPIコールを通じてまとめてアクセスされていました。移行にあたり、私たちは、後方互換性を維持しながら、ウォレット領域とは完全に独立した存在としてポイントを扱う新しいフローへの移行を顧客に案内する必要がありました。
後方互換性の課題は複雑で、特に当社が2段階コミット(2PC)を実装していることが要因でした。データが移行され、顧客が新しいフローに移行した後も、長期間有効なトランザクションを考慮する必要があるため、旧APIとワークフローのサポートを継続する必要がありました。前述の通り、単純な引き落としや入金トランザクションでも、準備フェーズとコミットフェーズが関わってきます。さらに、減算などの他のタイプのトランザクションでは、長期間存続する中間状態が発生する可能性があります。この問題に対処するためには、データがウォレットシステム内に存在しなくなったにもかかわらず、クライアントが古いAPIを使用してこれらの非終端トランザクションを完了できるように抽象化する必要がありました。
APIを2種類維持する必要性:
- 旧API:後方互換性を維持するために必要であり、古いトランザクションの継続を保証します(移行フロー)。
- 新API:段階的なリリースに必要な新しいフローをサポートします(段階的リリースフロー)。
さらに、段階的な移行リリースに対応するため、データソースは現在の移行設定に応じて、ウォレットシステムまたは新しいポイントシステムのどちらかに存在することになります。そのため、両方のAPIセットを効果的にサポートする綿密な設計を開発しました。
ソリューションその1:移行フロー
これは、旧APIを使用する移行ユーザーの従来のトランザクションスキームの継続をサポートするための設計です。基本的には、引き落とし、クレジット、アカウントのプライオリティに集約されます。

この図は、ウォレットシステム内のアカウントのプライオリティを示しています。通常、すべてのアカウントを網羅するユーザーウォレット全体は、単一のAPIを通じてアクセスされます。引き落としのプライオリティは上から下への順序に従いますが、クレジットのプライオリティは逆順となります。キャッシュバックは通常、引き落としの取引では最も高いプライオリティを持ち、クレジット取引では最も低いプライオリティを持ちます。
クレジット

クレジットのシナリオは、引き落としのシナリオよりもシンプルです。クレジットのリクエストに正確な内訳が含まれている場合、移行されたPOINTを含むすべてのアカウントに、分散取引としてクレジットを付与することができます。通常、クレジットのトランザクション間には依存関係がないため、プロセスは単純です。障害が発生した場合でも、自動再試行により、簡単に管理することができます。
デビット

引き落としの処理はクレジットに比べて複雑です。前述の通り、ポイント(キャッシュバック)アカウントは通常、最もプライオリティが高く、分散された取引間に依存関係が生じます。引き落としの順序は次の通りでなければなりません。
- 新しいポイントシステムからの引き落とし
- ポイントからの引き落とし
- ウォレットシステムからの引き落とし
- アカウントCからの引き落とし
- アカウントBからの引き落とし
- アカウントAからの引き落とし
パフォーマンスを維持するために、アカウントの悲観ロックは避けることにしました。しかし、このロックがないと、事前に残高が確認されていたとしても、ポイントの引き落としに必要な金額が取引時に利用可能であることを保証することが難しくなります。これは、アカウントC、B、Aについても同様です。ポイントの引き落としが成功していたとしても、これらのアカウントの資金不足により、ウォレットシステムで取引が失敗する可能性があります。通常、このような状況はオーケストレータと自動ロールバックで管理されますが、私たちはよりシンプルなソリューションを模索していました。
私たちのアプローチは以下の通りです。
- ウォレットシステム内の現在の総残高をTOTAL_WALLET_BALANCEとして計算します
- ポイントから必要な金額を範囲として決定します。
- MAX_POINT_DEBIT = REQUESTED_DEBIT_AMOUNT
- MIN_POINT_DEBIT = REQUESTED_DEBIT_AMOUNT – TOTAL_WALLET_BALANCE
- この引き落としリクエストの状態を維持し、同じリクエストが再試行された場合でも、計算済みの金額を再利用することで、確実に冪等性を確保します。
- ポイントシステムから引き落としをリクエストし、MIN_POINT_DEBIT および MAX_POINT_DEBIT の範囲内でベストエフォート型の引き落としを実行できるようにします。この基準内の引き落としが実行不可能な場合は、リクエストは不可となり、ポイントシステムは実際の引き落とし金額であるDEBITED_POINT_AMOUNT を返します。
- DEBITED_POINT_AMOUNT を受信したら、TOTAL_WALLET_BALANCE を再計算します(前回の計算以降に変更されている可能性があるため)。DEBITED_POINT_AMOUNT + TOTAL_WALLET_BALANCE が REQUESTED_DEBIT_AMOUNT 以上である場合は、処理を続行します。それ以外の場合、自動的に以前にコミットされたポイントの引き落としを取り消し、資金不足のエラーを返します。
このアプローチにより、安全と冪等性を維持しつつ、新たなオーケストレーションシステムを構築する手間を省くことができます。
ソリューション パート2:段階的ロールアウトの流れ
段階的ロールアウトでは、APIを新しいポイントサービスに移行する際、特に一部の移行されるユーザーと移行されないユーザーが混在している場合、エラーを回避するために慎重にトランザクションを処理する必要があります。 ユーザーがシステム間を切り替える際にシームレスなトランザクション処理を確保し、重複トランザクションなどの問題を回避することが課題となります。
問題:分離されたトランザクションと二重処理のリスク
リリース中、新しいポイントサービスへの移行が完了していないユーザーは、従来のウォレットシステムと継続してインタラクトします。 ポイントサービスは、これらのユーザーのプロキシとして、トランザクションをウォレットにリダイレクトします。 移行が完了すると、ポイントサービスが直接トランザクションを処理します。ただし、これはウォレットシステム下でトランザクションが発生し、ポイントサービス下で完了するという現象が起き、ポイントサービスが完全なトランザクションのコンテクストを把握しなければ二重処理が起こる可能性もあります。
解決策: トランザクション試行のトラッキング
段階的なロールアウト中にトランザクションの二重処理を防ぐには、ポイントサービスがウォレットサービスへのプロキシ試行をトラッキングする必要があります。 ポイントメインは、操作を処理する前にウォレットメインに問い合わせ、すでに試行されていないかを確認します。 ユーザーがトランザクションの途中で移行した場合、このログによって重複を回避することができます。
メンテナンス戦略
メンテナンス中は、対象となるユーザーはメンテナンスモードに移行し、未処理のトランザクションは以下のように処理されます。
- 未処理のトランザクション:メンテナンス中に未処理となったトランザクションは、メンテナンス後に再試行されます。これにより、ステータスが正しく付与され、重複することなく正確に処理されます。
このアプローチにより、トランザクションエラーのリスクが最小限に抑えられ、ウォレットサービスとポイントサービスの両方で一貫した処理が保証されます。
IDの排他性
問題

ウォレットシステムからポイントシステムへの移行の際に、決済番号の競合リスクが生まれます。決済番号を使用して残高を取得するリクエストが発行されると、ポイントシステムは認識できないトランザクションをすべてウォレットシステムに転送して処理します。このステップは、後方互換性を維持するために重要です。なぜなら、以前はクライアント側で新旧のトランザクションフローを明確に区別することができなかったからです。この分離がなければ、認識できないトランザクションによって残高取得に不整合やエラーが生じる可能性があります。
ポイントシステムが生成した決済番号が、ウォレットの別のトランザクションのIDと一致した場合、ポイントシステムが自身のトランザクションを参照することで、不正確な結果が返されるリスクがあります。この問題は、古いトランザクションがそのまま残り、ポイントシステムの決済番号が先行する傾向にあるため、移行が完了していないユーザーに特に影響します。一方、新しいトランザクションはポイントシステム内のみに存在します。そのため、残高取得プロセスの移行段階では、競合の可能性が特に高くなります。
正確で信頼性の高い取引処理を保証するためには、この問題への対処は必要不可欠です。これにより、最終的にユーザーエクスペリエンスが向上し、移行期間を通じてシステムの整合性が維持されます。
解決策
Snowflake ID 生成アルゴリズムのカスタム実装を使用して、ウォレットシステムとポイントシステム間で一意の決済番号を生成することを保証しました。
- ウォレットシステムは常に最下位ビットを0に設定。
- 新しいポイントシステムは同じUID生成装置を使用するものの、最下位ビットは1に設定。
- このアプローチにより、両システムで同時にIDが生成される場合でも、決済番号の競合を防止。
- このソリューションは拡張性があり、高同時実行性のあるトランザクションでもIDの一意性を維持します。
実行
移行は2回に分割して実行することにしました。段階的な移行展開は比較的低リスクであるのに対し、クライアントAPIとフローの移行にはより大きなリスクが伴うという理解に基づいての判断です。
APIとフローの移行

私たちは、当初は実際のデータソースを切り替えることなく、APIとフローの移行から着手することにしました。ウォレットシステムが多くのクライアントに依存するコアコンポーネントであることから、この段階はかなりのリスクを伴います。広範囲にわたるテストを実施する一方で、本リリースの前に最終的な検証を行いたいと考えました。メンテナンスの予定時間帯は、限られたダウンタイム中に最後の内部チェックとテストを行う機会を設けることができたので、重大な問題が発生した場合にロールバックする余地がありました。 用意したシナリオに沿ってすべてを徹底的にテストした上で、自信を持ってメンテナンスを終了し、フローの移行をサービスインさせました。
段階的なロールアウト
計画通りに段階的な移行ロールアウトを開始し、0%から徐々に100%へと進めていきました。部分的なメンテナンスとロールアウトの各段階において、細かい問題を特定できその都度迅速に修正した上で次の段階に進みました。大きな障害もなくスケジュール通りにロールアウトが進み、ユーザーにはほとんど気づかれないほどシームレスな体験を提供することができたかと思います。小さな問題でも迅速に対応できたことは良かったと思いますし、特に重大な問題も発生しませんでした。もし深刻な問題が起きていたとしても、段階的な移行アプローチにより、早期に対処することができ、ユーザーへの影響を最小限に抑えることができたでしょう。
最終結果
移行を完了したことで、当初の目標を達成し、さらに多くの成果を上げることができました。現在では、ポイント関連のフローをすべて管理する専任チームを擁し、ウォレットシステムから完全にデカップリングした新機能の展開が可能となっています。重要な機能のひとつは、移行中にすでに進行中で、完全な展開に向けた最終的なアーキテクチャに沿ったものでした。この移行によって単一の大型ウォレット領域による競合のオーバーヘッドなしに、チームがポイントフローに専念できるようなり、開発速度が大幅に加速しました。
更に、ポイントフローのインフラを個別に拡大させることができるようになったので、今後はより効率的なリソースの割り当てが可能になるでしょう。
今後に向けて
理想的には、すべてを一度にデカップリングしたと思います。しかし、限られた時間と広範囲にわたる移行を考慮し、最も重要なコンポーネントを優先することで、作業は無事に完了しました。アプリケーションロジックとデータベースクラスタを共有しているサポートサービスなど、まだ残っている作業もありますが、大掛かりな作業が完了しているので、これらへの対応はより楽になるでしょう。私たちは、この2つの領域のモジュール性を強化し、発生し得るあらゆる課題に対応することを楽しみにしています。


