ドキュメント

Appendix

モバイルアプリのアプリ内課金 実装・運用設計ドキュメント の「Appendix」をまとめたページです。

Appendix

Appendix A. 一次情報一覧

Apple

Google

Appendix B. モノレポ構成時のディレクトリ構成のヒント

本付録は、既にモノレポで運用されているプロジェクトに、NestJS の API アプリNestJS の batch アプリを追加・共存させる場合の構成例を示すものです。
本編の必須要件ではなく、既存構成を大きく崩さずに導入するための実装ヒントとして扱います。

B-1. 前提

ここでは、次のような既存構成を前提にします。

bff/
  api/
    prisma/
    src/
      common/
      infrastructure/
      integration/
      shared/
      modules/
      utils/
    test/
  xxxx/
docs/
mobile/

このような構成では、Nest CLI の標準 monorepo mode に無理に寄せるより、既存のリポジトリ構成を維持したまま bff/apibff/batch を並列に持つほうが現実的です。

B-2. 推奨する考え方

  • bff/apiAPI 用 NestJS project root とする
  • bff/batchbatch 用 NestJS project root とする
  • bff/BFF workspace root として扱う
  • API と batch の両方で使うコードは bff/libs/ に段階的に切り出す
  • 最初から大規模なディレクトリ移動は行わず、共有が必要になった箇所だけ整理する

このドキュメントの文脈では、同一コードベースに統合しつつ、API と batch は別プロセス・別デプロイ単位で実行する構成を推奨します。

B-3. 推奨ディレクトリ構成

最もわかりやすい形は、bff/ の下に apibatch を並べ、必要に応じて libs を追加する構成です。

bff/
  package.json
  tsconfig.base.json

  api/
    package.json
    nest-cli.json
    prisma/
    src/
      common/
      infrastructure/
      integration/
      shared/
      modules/
      utils/
      app.module.ts
      main.ts
    test/

  batch/
    package.json
    nest-cli.json
    src/
      common/
      infrastructure/
      integration/
      shared/
      jobs/
      commands/
      utils/
      app.module.ts
      main.ts
    test/

  libs/
    billing/
      src/
        domain/
        application/
        infrastructure/
        query/
    platform/
      src/
        config/
        logging/
        time/

B-4. 役割の分け方

bff/api

bff/api には、HTTP で受ける責務を置きます。

  • 購入情報反映 API
  • Apple 通知受信 API
  • Google 通知受信 API
  • 利用可否取得 API
  • 契約詳細取得 API

ここには、controller、guard、interceptor、request / response の整形など、HTTP サーバとしての責務を置きます。

bff/batch

bff/batch には、定期実行や手動実行の責務を置きます。

  • 失敗イベント再処理ジョブ
  • 通知欠落補正ジョブ
  • Google acknowledgement 救済ジョブ
  • 期限近辺の再照合ジョブ
  • バックフィルコマンド
  • 通知再生コマンド

bff/batch は HTTP サーバである必要はありません。
HTTP listener を持たない NestJS の standalone application として起動しても構いません。

bff/libs

bff/libs には、API と batch の両方で使うコードを置きます。

  • 課金ドメインの状態判定
  • 再照合 use case
  • projection
  • repository interface
  • Prisma repository 実装
  • Apple / Google 連携 client
  • lock / queue / config などの共通基盤

B-5. package.json の置き方

この構成では、package.json を 3 つ置くと理解しやすくなります。

  • bff/package.json
  • bff/api/package.json
  • bff/batch/package.json

B-5-1. bff/package.json

bff/ 全体の workspace root として使います。

{
  "name": "@your-org/bff-workspace",
  "private": true,
  "workspaces": [
    "api",
    "batch"
  ],
  "scripts": {
    "build": "npm run build -w api && npm run build -w batch",
    "build:api": "npm run build -w api",
    "build:batch": "npm run build -w batch",
    "start:dev:api": "npm run start:dev -w api",
    "start:dev:batch": "npm run start:dev -w batch",
    "lint": "npm run lint -w api && npm run lint -w batch",
    "test": "npm run test -w api && npm run test -w batch",
    "prisma:generate": "npm run prisma:generate -w api",
    "prisma:migrate:dev": "npm run prisma:migrate:dev -w api"
  },
  "devDependencies": {
    "@nestjs/cli": "^11.0.0",
    "typescript": "^5.7.0"
  }
}

B-5-2. bff/api/package.json

bff/api の project root として使います。

{
  "name": "@your-org/bff-api",
  "private": true,
  "scripts": {
    "build": "nest build",
    "start": "node dist/main",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
    "test": "jest",
    "test:e2e": "jest --config ./test/jest-e2e.json",
    "prisma:generate": "prisma generate",
    "prisma:migrate:dev": "prisma migrate dev"
  },
  "dependencies": {
    "@nestjs/common": "^11.0.0",
    "@nestjs/core": "^11.0.0",
    "@nestjs/platform-express": "^11.0.0",
    "@nestjs/config": "^4.0.0",
    "@prisma/client": "^6.0.0",
    "reflect-metadata": "^0.2.2",
    "rxjs": "^7.8.1"
  },
  "devDependencies": {
    "@nestjs/testing": "^11.0.0",
    "@types/jest": "^29.5.12",
    "@types/node": "^22.10.1",
    "eslint": "^9.0.0",
    "jest": "^29.7.0",
    "prisma": "^6.0.0",
    "ts-jest": "^29.2.5",
    "ts-node": "^10.9.2",
    "typescript": "^5.7.0"
  }
}

B-5-3. bff/batch/package.json

bff/batch の project root として使います。

{
  "name": "@your-org/bff-batch",
  "private": true,
  "scripts": {
    "build": "nest build",
    "start": "node dist/main",
    "start:dev": "nest start --watch",
    "start:job:reconcile": "node dist/commands/reconcile-subscriptions.command.js",
    "start:job:retry-failed-events": "node dist/commands/retry-failed-events.command.js",
    "lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
    "test": "jest"
  },
  "dependencies": {
    "@nestjs/common": "^11.0.0",
    "@nestjs/core": "^11.0.0",
    "@nestjs/config": "^4.0.0",
    "@nestjs/schedule": "^5.0.0",
    "@prisma/client": "^6.0.0",
    "reflect-metadata": "^0.2.2",
    "rxjs": "^7.8.1"
  },
  "devDependencies": {
    "@nestjs/testing": "^11.0.0",
    "@types/jest": "^29.5.12",
    "@types/node": "^22.10.1",
    "eslint": "^9.0.0",
    "jest": "^29.7.0",
    "ts-jest": "^29.2.5",
    "ts-node": "^10.9.2",
    "typescript": "^5.7.0"
  }
}

B-6. git mv は必要か

結論として、最初から必須ではありません。

すぐに git mv しなくてよいケース

  • まず bff/batch を新設したい
  • batch 側のジョブをゼロから実装する
  • 共有したいコードがまだ少ない

この段階では、bff/api は大きく動かさず、bff/batch を追加するだけで始められます。

段階的に git mv したほうがよいケース

  • apibatch の両方で同じ Prisma repository を使いたい
  • apibatch の両方で同じ Apple / Google 連携 client を使いたい
  • 同じ projection や reconciliation use case を共有したい

この場合は、その部分だけを bff/libs に移し、git mv で履歴を保ちながら整理するとよいです。

B-7. 移行の進め方

最初の移行は、次の 2 段階に分けるのが安全です。

段階 1. bff/batch を追加する

  • bff/batch/src/main.ts
  • bff/batch/src/app.module.ts
  • bff/batch/src/jobs/
  • bff/batch/src/commands/

まずは batch 専用の入口だけを作ります。

段階 2. 共有コードを bff/libs に切り出す

次のようなコードが共有候補です。

  • api/src/integration/apple
  • api/src/integration/google
  • api/src/infrastructure/prisma
  • api/src/shared/billing
  • api/src/modules/billing のうち HTTP 依存を持たない service / use case

このとき、controller や guard まで一緒に移さないことが重要です。
共有するのは、あくまで API と batch の両方で使う ドメイン・ユースケース・基盤実装です。

B-8. 最小変更で始めるなら

初回は、次のような簡略構成でも十分です。

bff/
  api/
    prisma/
    src/
      common/
      infrastructure/
      integration/
      shared/
      modules/
      utils/
    test/

  batch/
    src/
      common/
      infrastructure/
      integration/
      shared/
      jobs/
      commands/
      utils/
    test/

この構成で運用しながら、共有したい部分が増えた段階で bff/libs を足す形でも問題ありません。

B-9. 補足

NestJS には monorepo mode がありますが、既に独自のモノレポ構成で運用している場合、Nest CLI の標準的な monorepo へ無理に寄せる必要はありません
この付録で示した構成は、既存のリポジトリ構成を尊重しつつ、API と batch を NestJS で共存させるための実務的な一例です。

B-10. 参考リンク

NestJS の公式ドキュメントとして、次を参照すると理解しやすいです。

特に今回の構成では、既存の独自モノレポに apibatch の 2 つの NestJS application を追加する考え方HTTP listener を持たない batch app の作り方cron / interval による定期ジョブの実装を確認しておくと役立ちます。