Playwright ベース帳票プラグイン設計メモ¶
このドキュメントは、Vendure 用の社内実装「帳票プラグイン(PDF生成)」の設計方針をまとめたものです。Dashboard 前提で、適格請求書を含む日本商習慣の帳票を生成・配信します。
互換性レンジ¶
- Vendure: 3.5.x(apps/vendure-server は ^3.5.2 を使用)
- Node.js: >=24.7.0(apps/vendure-server/package.json の engines に準拠)
目的¶
- invoice(請求書)は発行時に固定ファイルを保存し、連番・履歴を保持して監査可能にする。
- delivery / quote / label は都度生成を基本とし、必要に応じて短期キャッシュ。
- ユーザーがシンプルに編集できる Handlebars テンプレートで統一し、HTML+印刷CSSを使った版下を Playwright で PDF 化する。
対象帳票と保存ポリシー¶
- invoice: 注文確定時にジョブキューへ投入して事前生成し、S3/R2 へ永続保存(署名付きURLで配布)。以後は保存済みファイルを返す。未生成の既存注文だけは初回ダウンロード要求時の同期生成を救済路として使う。改訂は新ファイル+履歴・連番管理。
- delivery: 都度生成(大口バッチのみ短期TTL保存可)。
- quote: 都度生成。受注確定後は請求書に置き換え。
- label: 都度生成。ピッキング/配送向けに一括生成も想定。
見積書(quote)発行ルール¶
- 発行タイミング: カート画面で発行(Amazon方式)。
- 金額の範囲: 商品価格の割引(クーポン)適用後の金額を含める。
- 支払い方法由来の調整: ギフト券・ポイント等は見積書に含めない(支払い方法の選択であり商品価格に含めない)。
- 価格固定: 発行時点の価格で固定し、価格変更時は新しい見積書を発行する。
- 有効期限: 発行日から30日を初期値とし、Vendure
Dashboard で編集可能にする。境界は JST 日付基準とし、
quoteValidityDays=30の場合は「発行日の 30 日後の当日中まで有効」として扱う。
全体アーキテクチャ¶
- テンプレート管理: Handlebars。チャネル×帳票種別で DB 保存。初期版は
static/report-templates/*.hbsからシード。 - レンダリング:
Playwright(HTML→PDF)。Chromium はコンテナ同梱を前提。
media=printで印刷CSSを適用。 - ストレージ: S3/R2 署名付きURL。invoice は永続、その他はオプションで短期保存。
- イベント連携:
OrderPlacedEventで invoice をジョブキューに事前投入し、OrderStateTransitionEventで配送系帳票を投入する。invoice の初回要求時同期保存は、 queue 未処理・backfill 未済の注文向け救済路に限定する。 - Dashboard UI: テンプレ一覧・編集・プレビュー、発行者情報(会社名・住所・適格請求書番号・印影URL等)の設定フォーム。
GraphQL / エンティティ設計(草案)¶
- エンティティ
ReportTemplate: id,createdAt,updatedAttype(enum: invoice|delivery|quote|label)channelIdnametemplateStringpublic(publicダウンロード許可フラグ)updatedBy(管理ユーザー識別子)- Admin GraphQL:
ritsReportTemplates(options)/ritsReportTemplate(type)createRitsReportTemplate(input)/updateRitsReportTemplate(type, input)/deleteRitsReportTemplate(type)generateRitsReportPreview(type)→ base64- ヘルパー(最小セット):
yen(カンマ区切り / 小数0桁)jpDate(JST, yyyy/MM/dd または和文)percentifEq/ifNot- 追加予定:
taxRateLabel,kana(必要になれば)
テンプレート初期構成(案)¶
invoice.hbs: 適格請求書対応。登録番号・発行日・取引日・税込/税抜小計・税率別内訳・印影。delivery.hbs: 納品明細+受領印欄。quote.hbs: 有効期限・支払条件・見積番号・担当者。label.hbs: 送り先・注文コード・バーコード/QR・ピッキング情報。- 共通パーシャル:
header.hbs,footer.hbs,totals.hbs,buyer-block.hbs.
保存パスとTTL(案)¶
- invoice:
reports/<channel>/invoice/<orderCode>/<orderCode>-invoice-<serial>.pdf(永続) - delivery/quote/label:
reports/<channel>/<type>/<orderCode>/<orderCode>-<type>-<serial>.pdf(永続)
環境変数(案)¶
PDF_SIGNED_URL_TTL_SECONDS(秒): 署名付きURLの有効期限- 発行者情報:
INVOICE_ISSUER_NAME,INVOICE_ISSUER_ADDRESS1,INVOICE_ISSUER_ADDRESS2,INVOICE_ISSUER_TELINVOICE_REGISTRATION_NUMBER(適格請求書登録番号)
今後の実装手順¶
- プラグイン骨格(エンティティ・GraphQL・サービス・ジョブキュー・S3保存)を作成。
- テンプレ初期版投入マイグレーションを追加。
- Dashboard 拡張(一覧/編集/プレビュー、発行者情報フォーム)。
- ステージングで invoice 永続保存 / delivery・quote・label 都度生成を検証。
- 運用Runbookと、このドキュメントの最終化。
運用上の注意¶
- invoice は再生成時に「旧ファイルを残し新ファイルに連番を付与する」運用を徹底すること。
- テンプレ変更後はプレビューで印刷CSSと改行・禁則を必ず確認する。
- Cloudflare Browser Rendering / R2 / 署名 URL は unit test だけでは保証できない。
請求書発行の deploy 後確認は
just storefront-invoice-smoke stagingで、実 Shop API のritsOrderInvoice、署名 URL、PDF signature まで確認する。既定ではE2E_LOGIN_*顧客の直近注文を使い、必要ならSTOREFRONT_SMOKE_INVOICE_ORDER_CODE=<order-code>で対象注文を固定する。 - Playwright 実行時はブラウザ 1 + context 複数で並列化し、リソースリークを防ぐため生成後に必ず close する。