Qwen「callback_name の説明拡張」提案レビュー
対象: https://grav.machines.jp/ja/rewald_build_top_dir/c-callback_name-javascript-qwen レビュー日: 2026-04-12 レビュアー: Claude Opus 4.6
サマリー
方向性は正しい。callback_name の引数構造を具体化する提案は有用。 ただし、コード未確認で書いたと思われるプロパティ名の捏造が複数あり、そのまま採用すると動かないコードが仕様書に載る。
| 評価 | 件数 |
|---|---|
| 正確 | 5件 |
| 重大な誤り | 2件 |
| プロパティ名の捏造 | 5件 |
| 用語の誤用(再発) | 1件 |
重大な誤り
1. point_trans_close: 第1引数は open の結果であり、close の結果ではない
Qwen の記述:
result.result.new_point: 今回付与されたポイント数result.result.use_point: 今回消費されたポイント数result.result.total_point: 処理後の合計残高
実際のコード (point-all.twig:1350):
{$callback_name}({result: point.open_result}, point);
第1引数は {result: point.open_result} — point_trans_open の結果を包んだオブジェクト。含まれるのは:
result.result.total_price— ポイント差引後の支払金額result.result.use_point— 利用ポイント数result.result.price— 商品価格result.result.pointsystem_nonce— nonce
new_point, total_point は第1引数に含まれない。これらは point.close() の戻り値(close API のレスポンス)に含まれる。
2. point_purchase_open: コールバック引数が2つのモードで完全に異なる
Qwen の記述:
引数構造:
function(response)response.result.purchase_amount,response.result.grant_point,response.result.currency
実際のコード:
price 指定モード (point-all.twig:1509):
{$callback_name}(response);
response.result.pointsystem_nonce— nonceresponse.result.price— 購入金額(purchase_amountではない)
polling モード (point-all.twig:1633-1634):
window["{$cb_name}"](btn.dataset, pointsystem_nonce, signature);
- 第1引数:
btn.dataset(ボタンの data 属性群) - 第2引数:
pointsystem_nonce(文字列) - 第3引数:
signature(文字列)
purchase_amount, grant_point, currency はいずれもコード内に存在しないプロパティ名。
プロパティ名の捏造(5件)
| ショートコード | Qwen が記述したプロパティ | 実際 |
|---|---|---|
| point_trans_open | response.result.conv_point |
存在しない。正しくは conv_rate(還元率)または open API の実際のレスポンスフィールド |
| point_trans_detail | response.result.transaction_id |
未確認。テンプレート・llms ファイルのいずれにも使用例なし |
| point_trans_cancel | response.result.message, response.result.restored_point |
未確認。テンプレートでは response.error のみ参照。restored_point の使用例なし |
| point_purchase_open | response.result.purchase_amount, response.result.grant_point |
存在しない。正しくは response.result.price, response.result.pointsystem_nonce |
| point_purchase_close | response.result.transaction_id |
未確認。テンプレートでは response.result.point のみ使用 |
用語の誤用(再発)
Qwen の記述(point_trans_close の point.cancel() 説明):
仮確保されていたポイントを戻す(ロールバックする)非同期メソッド
問題: 前回レビューで「仮確保」という概念はシステムに存在しないと指摘済み。cancel() は確定済みトランザクションの取消であり、「仮確保の解除」ではない。
また、cancel() は async キーワードなしの通常メソッド(point-all.twig:1302)。Promise を返すが、厳密には「非同期メソッド」ではなく「Promise を返すメソッド」。
正確な記述
| ショートコード | 記述内容 | 根拠 |
|---|---|---|
| point_own | response.result.point |
point-all.twig:954 のデフォルトコールバック |
| point_setting | response.result に通貨・レート情報 |
point-all.twig:875-884 のデフォルトコールバック |
| point_trans_open | response.result.total_price, response.result.use_point |
全シナリオテンプレートで使用 |
| point_trans_close | point.close(), point.cancel(), point.url, point.data, point.pointsystem_nonce |
point-all.twig:1227-1345 の Point クラス定義 |
| 補足セクション | コールバック関数はグローバルスコープで定義が必要 | 正確 |
総括
提案の方向性(callback_name の引数構造を仕様書に明記する)は正しく、実装すべき改善。ただし、実際のコードを確認せずにプロパティ名を推測した箇所が多く、そのまま仕様書に載せるとコードとドキュメントの乖離が生まれる。 特に point_trans_close の第1引数の誤解は、開発者が result.result.new_point を参照しようとして undefined になるため実害がある。
point_trans_close コールバックの動作分析
コールバックの正体: 初期化通知であり close 完了通知ではない
point_trans_close の callback_name は名前に反して「close 完了通知」ではなく 「Point インスタンス準備完了通知」 である。
point-all.twig:1350:
{$callback_name}({result: point.open_result}, point);
- 第1引数
{result: open_result}—point_trans_openAPI の結果。UI の初期表示に使う:result.result.total_price— ポイント差引後の支払金額result.result.use_point— 利用ポイント数result.result.price— 商品価格result.result.pointsystem_nonce— nonce
- 第2引数
point— Point インスタンス。開発者はこれを保持し、後でclose()やcancel()を呼ぶ
シナリオ B の典型的な使用例:
function onTransReady(response, point) {
// ① open の結果で最終金額を表示
if (response && response.result) {
document.getElementById('final_price').textContent = response.result.total_price;
}
// ② point オブジェクトで PayPal ボタンを設定(この時点で close はまだ)
paypal.Buttons({
createOrder: function() {
return actions.order.create({
amount: { value: String(point.total_price) }
});
},
onApprove: function(data) {
triggerClosePSP(data.orderID); // ← ここで初めて close が発生
}
}).render('#paypal-button-container');
}
タイミング: open の fetch と DOMContentLoaded の競合
| ステップ | 処理 | タイミング |
|---|---|---|
| 1 | [point_trans_open] IIFE が即時実行 |
ページパース時 |
| 2 | 初期値で pointsystem_callback() 呼出(line 1192) |
即時 |
| 3 | fetch で open API を非同期呼出(line 1123-1145) | 非同期 |
| 4 | fetch 完了 → sessionStorage.setItem('pointsystem_open_result', ...) (line 1136) |
順序不定 |
| 5 | [point_trans_close] が DOMContentLoaded で Point を生成(line 1347) |
順序不定 |
ステップ 4 と 5 の順序は保証されない。5 が先に発火すると sessionStorage.getItem('pointsystem_open_result') が null になる可能性がある。
コードは null チェックで対応(line 1231-1236):
if(open_result_str == null || open_result_str == ""){
console.warn("pointsystem: open_result not yet available");
this.open_result = null;
// ...
}
テンプレートでも if (response && response.result) でガードしているため実用上は動作する。
close 結果の取得方法(3パターン)
| パターン | 方法 | 使用シナリオ | 根拠 |
|---|---|---|---|
point.close() 戻り値 |
var result = await point.close() |
シナリオ C(Stripe、同一ページ) | point-all.twig:1256-1290 |
[point_trans_detail] |
別ページで nonce ベースの結果取得 | シナリオ B, C の完了ページ | point-all.twig:1415-1473 |
| REST API GET | fetch('/wp-json/pointsystem/v1/point_trans_close/?orderId=...') |
シナリオ B(PayPal PSP 検証付き) | point-all.twig:1866-1880 |
point.close() は POST で /point_trans_close/ を呼び、戻り値に close 結果(new_point, use_point, total_point 等)を含む。[point_trans_detail] は sessionStorage の pointsystem_last_closed_nonce(close 成功時に保存: line 1284)を使って結果を再取得する。
将来のコード修正検討メモ
ショートコード名の紛らわしさ
point_trans_close の callback が初期化通知であることは直感に反する。仕様書で明記するか、将来的に別名(例: point_trans_ready)の追加を検討。既存の point_trans_close は互換性のため維持。
タイミング問題
DOMContentLoaded ではなく open の fetch 完了を待ってから Point を生成する方が安全。ただし既存動作を壊すリスクがあるため、修正する場合は全シナリオの動作確認が必要。
Qwen の提案で採用すべき部分
point オブジェクトのメソッド一覧(close(), cancel(), url, data, pointsystem_nonce)の仕様書明記は有用。プロパティ名の捏造(5件)と第1引数の誤解を修正した上で取り込むべき。