前提の緩和(#39 ): バックエンドを Nitro に一体化する前提は保留する。ここで今確定するのは分離の seam の位置(ジョブ・webhook 処理を、注入された Context だけに依存する関数に寄せ、ルートは薄いアダプタに保つ)。実行モデル(リトライ・冪等・多重実行防止)を決める本 issue の目的は維持し、ジョブ実行基盤の具体は運用先・トポロジ確定後に暫定とする。
背景
openspec/project.md は「バックエンドは Nitro 内にマウント(独立サービスにしない)」まで決めているが、リクエスト内で完結しない処理 — 請求書メール送信(#19 )・webhook 処理(#17 )・Stripe との突合・会員更新・定期実行 — を「どこで動かすか」は未決。
なぜ今決めるか
リトライ付きジョブやスケジュール実行をリクエストハンドラ内の await に押し込むと、タイムアウト・取りこぼし・多重実行が構造的に起きる。ここを決めずに #17 /#19 を実装すると各々が場当たりの実行経路を作り、後で統一するのが高くつく。将来 Nitro からバックエンドを分離する場合の seam も、早く引くほど安い。
論点・選択肢
ジョブ実行モデル: (a) 外部 cron が認証付きエンドポイントを叩く、(b) DB を使ったジョブキュー + 単一リーダー、(c) NeoShowcase にスケジュール機能があればそれ。複数レプリカ時の多重実行防止(デプロイ・トポロジの決定に依存)。
分離の seam: packages/api は Context 依存(db/stripe)を注入型にしてあり分離しやすい。ジョブ/webhook 処理を最初から packages/api 側の純粋関数に寄せ、Nitro ルートは薄いアダプタに保つ、という境界を今引くか。
webhook は raw body を要するため、oRPC とは別の専用ルートが要る(Stripe webhook(invoice-paid)を実装する #17 )ことを踏まえた入口設計。
受け入れ条件
非同期・定期処理の実行モデルと、バックエンド分離の seam(ジョブを純粋関数に寄せる境界)が決まっている。
cron の具体は NeoShowcase の機能次第で情報不足なら暫定とし、seam の位置は今確定する。
関連
#17 (webhook)・#19 (請求書メール)の実行基盤(親)。デプロイ・トポロジ、webhook 信頼性の決定と接続する。
背景
openspec/project.mdは「バックエンドは Nitro 内にマウント(独立サービスにしない)」まで決めているが、リクエスト内で完結しない処理 — 請求書メール送信(#19)・webhook 処理(#17)・Stripe との突合・会員更新・定期実行 — を「どこで動かすか」は未決。なぜ今決めるか
リトライ付きジョブやスケジュール実行をリクエストハンドラ内の
awaitに押し込むと、タイムアウト・取りこぼし・多重実行が構造的に起きる。ここを決めずに #17/#19 を実装すると各々が場当たりの実行経路を作り、後で統一するのが高くつく。将来 Nitro からバックエンドを分離する場合の seam も、早く引くほど安い。論点・選択肢
packages/apiは Context 依存(db/stripe)を注入型にしてあり分離しやすい。ジョブ/webhook 処理を最初からpackages/api側の純粋関数に寄せ、Nitro ルートは薄いアダプタに保つ、という境界を今引くか。受け入れ条件
関連
#17(webhook)・#19(請求書メール)の実行基盤(親)。デプロイ・トポロジ、webhook 信頼性の決定と接続する。