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 — nonce
  • response.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_closecallback_name は名前に反して「close 完了通知」ではなく 「Point インスタンス準備完了通知」 である。

point-all.twig:1350:

{$callback_name}({result: point.open_result}, point);
  • 第1引数 {result: open_result}point_trans_open API の結果。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]sessionStoragepointsystem_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引数の誤解を修正した上で取り込むべき。