Claude CodeでABAP Cloud移行のATC指摘を仕分ける — 置換APIとラッパーの分け方
ATCのクリーンコア指摘を、公開リポジトリのJSONで置換先ありと要ラッパーに仕分ける手順です。照合はスクリプトに任せ、Claude Codeには判断が要る箱だけを渡します。
ABAP Cloudへの移行で最初に手が止まるのは、ATC(ABAP Test Cockpit)が吐く数百〜数千件の指摘です。どれも「未公開のAPIを使っている」という同じ文言なのに、直し方は一件ずつ違います。名前を差し替えれば済むものもあれば、呼び出し方ごと書き換えるものも、ラッパーを挟むしかないものもあります。
この記事では、指摘の一覧を4つの箱に仕分ける手順を扱います。照合に使うのは、SAPが公開しているCloudification Repository(リリース済みAPIと後継の対応表)のJSONです。Claude Codeには照合スクリプトを書かせ、判断が要る箱だけを claude -p で読ませます。
ATC指摘は4つの箱に分けると進めやすい
指摘を直す順番は、置換先がどれだけはっきりしているかで決まります。次の4つに分けると、着手の順番が見えます。
指摘を分ける4つの箱
A: 公開済み
対象がリリース済みAPIとして載っている箱です。本来は指摘が出ないはずなので、ATC側の参照ファイルと手元のJSONの版がずれている可能性があります。まず参照ファイルを揃えます。
B: 後継あり
未公開または非推奨で、後継オブジェクトがJSONに載っている箱です。名前の置換で済むか、呼び出し方の書き換えが要るかをここで見分けます。
C: 要ラッパー
後継は無いが、クラシックAPIとして分類されている箱です。ABAP Cloudからは直接呼べないので、公開済みの層でラッパーを作って橋渡しします。
D: 手作業
どちらのJSONにも載っていない箱です。自作オブジェクトか、対象リリースが違う可能性があり、人が読んで決めます。
Bから先に片付けるのが現実的です。後継が決まっているので迷いが少なく、件数も減らせます。Cはラッパーの設計が要り、Dは調査が要るので後回しになります。
仕分けの材料になる公開リポジトリのJSON
照合の元になるのは、SAPが公開している abap-atc-cr-cv-s4hc リポジトリです。READMEによると、リリース済みAPIの一覧と、未公開オブジェクトの後継情報が1つのJSONにまとまっています。このJSONは、ATCチェック「Usage of Released APIs (Cloudification Repository)」の内容として使われます。
使うファイルは2つです。
| ファイル | 中身 | 仕分けでの役割 |
|---|---|---|
objectReleaseInfo_PCELatest.json | 中身公開状態と後継 | 仕分けでの役割AとBの判定 |
objectClassifications_SAP.json | 中身クラシックAPIの分類 | 仕分けでの役割Cの判定 |
READMEでは、SAP Cloud ERP Private向けのチェックにこのPCELatestを指定する例が示されています。SAP Cloud ERP向けは objectReleaseInfoLatest.json です。対象製品とリリースに合うファイルを選びます。選び違えると、AやDに誤って振り分けられます。
JSONの中を見ると、仕分けに使える項目が揃っています。PCELatestを数えると45,148件で、state の内訳は次のとおりです。
PCELatestのstate内訳
released
43,611
公開済み
notToBeReleased
619
非公開扱い
notToBeReleasedStable
608
READMEに説明なし
deprecated
310
非推奨
後継は successorClassification で表されます。値は oneObject(後継が1つ)、multipleObjects(複数)、concept(オブジェクトでなく考え方で示される)の3種類です。concept の後継は successorConceptName に文字列で入り、例えば「Automatic Job Restart in BTP」のような名前が見つかります。
クラシックAPI側の objectClassifications_SAP.json は8,601件で、classicAPI が8,128件、noAPI が473件です。labels には remote-enabled(3,960件)と transactional-consistent(2,673件)があります。種別は関数モジュール(FUNC)が5,251件と最多です。
JSONをそのままClaudeに読ませない
PCELatestは約12MBあります。READMEは、LLM向けの圧縮形式TOONでも約300万トークン(3,659,440から2,989,644へ)と書いています。会話に貼って「この指摘を分類して」と頼む使い方は成り立ちません。
照合は決まった手順の機械作業なので、スクリプトに任せます。Claude Codeの役目は、そのスクリプトを書くことと、スクリプトが振り分けられなかった箱を読むことです。
照合スクリプトを書かせて動かす
ATCの指摘は、まずCSVにして渡します。列は object_type、object_name、message の3つに絞ります。ATCのエクスポート形式そのものではなく、この記事で決めた入力形式です。実際の出力から列を取り出す部分は、環境に合わせて直します。
作業ディレクトリのCLAUDE.mdに、守ってほしい前提を書いておきます。
# ATC指摘の仕分け
- 照合の元データは objectReleaseInfo_PCELatest.json と objectClassifications_SAP.json。
どちらも数MBあるので、全文を読まず python3 か jq で引く
- 仕分けは classify.py の出力(A/B/C/D)を正とし、手で区分を書き換えない
- 後継が BDEF の指摘は、名前の置換ではなく呼び出し方の書き換えとして扱うJSONはcurlで取得します。取得はこちらで済ませ、Claude Codeからの外部通信は止めておきます。
curl -sLO https://raw.githubusercontent.com/SAP/abap-atc-cr-cv-s4hc/main/src/objectReleaseInfo_PCELatest.json
curl -sLO https://raw.githubusercontent.com/SAP/abap-atc-cr-cv-s4hc/main/src/objectClassifications_SAP.json権限は .claude/settings.json で絞ります。読み取りと、仕分けスクリプトの実行だけを許可します。
{
"permissions": {
"allow": ["Read", "Bash(python3 classify.py *)"],
"deny": ["Bash(curl *)"]
}
}広いdenyルールは、より狭いallowルールがあっても優先されます。Bash(curl *) をdenyに置くと、Claudeが指摘対象のソースを調べている最中にcurlで外部から取得させることを止められます。権限の書き方は、allowedToolsとdisallowedToolsの記事にまとめています。
照合スクリプトは次の形です。Claude Codeに「この仕様で書いて」と頼む叩き台として使えます。
import csv, json, sys
rel = {(i["objectType"], i["objectKey"]): i
for i in json.load(open("objectReleaseInfo_PCELatest.json"))["objectReleaseInfo"]}
cls = {(i["objectType"], i["objectKey"]): i
for i in json.load(open("objectClassifications_SAP.json"))["objectClassifications"]}
rows = []
for r in csv.DictReader(open(sys.argv[1])):
k = (r["object_type"], r["object_name"])
a, c = rel.get(k), cls.get(k)
if a and a["state"] == "released":
bucket, hint = "A released", ""
elif a and a.get("successors"):
bucket = "B successor"
hint = ",".join(s["objectKey"] for s in a["successors"][:3])
elif a and a.get("successorClassification") == "concept":
bucket, hint = "B concept", a.get("successorConceptName", "")
elif c and c["state"] == "classicAPI":
bucket = "C wrapper"
hint = "+".join(c.get("labels", [])) or "no-label"
else:
bucket, hint = "D manual", ""
rows.append({**r, "bucket": bucket, "hint": hint})
json.dump(rows, sys.stdout, ensure_ascii=False, indent=1)判定の順序が肝心です。先に「公開済みか」を見て、次に「後継があるか」、最後に「クラシックAPIか」を見ます。クラシックAPIの分類は、後継が見つからなかったオブジェクトにだけ当てます。
次のような7件で動かしました。
python3 classify.py findings.csv | jq -r '.[] | [.object_name,.bucket,.hint] | @tsv'結果は次のとおりです。
| オブジェクト | 箱 | ヒント |
|---|---|---|
| CL_BCS | 箱B | ヒントCL_BCS_MAIL_MESSAGE |
| MARA | 箱B | ヒントI_PRODUCT、I_PRODUCTPROCUREMENT、I_PRODUCTQM(ほか) |
| BAPI_PO_CREATE1 | 箱C | ヒントremote-enabledとtransactional-consistent |
| BAPI_SALESORDER_CREATEFROMDAT2 | 箱B | ヒントI_SALESORDERTP |
| CL_ABAP_CONTEXT_INFO | 箱A | ヒントなし |
| CL_SALV_TABLE | 箱C | ヒントラベルなし |
| ZZ_UNKNOWN_TAB | 箱D | ヒントなし |
後継の数が箱の中身を分けています。CL_BCS の後継は1つで、クラス名の差し替えに近い作業です。MARA は5つのCDSビューに分かれ、どの項目を読むかで使うビューが変わります。1対1の置換ではありません。
BAPI_SALESORDER_CREATEFROMDAT2 の後継は I_SALESORDERTP で、種別はBDEF(ビヘイビア定義)です。関数モジュールの呼び出しが、ビヘイビア定義を通すアクセスに変わります。CLAUDE.mdに書いた「BDEFは書き換え扱い」は、この種類の指摘を名前の置換に回さないための一行です。
判断が要る箱だけを claude -p に渡す
CとDは、呼び出し側のソースを読まないと方針が決まりません。この2つを抜き出して、非対話モードで読ませます。
python3 classify.py findings.csv > triage.json
jq '[.[] | select(.bucket | startswith("C") or startswith("D"))]' triage.json > needs-review.json
claude -p "needs-review.json の各オブジェクトについて、src 配下の呼び出し箇所を探し、\
ラッパーを作るか、呼び出しを書き換えるか、人が調べるかを提案して" \
--allowedTools "Read,Grep,Glob" \
--output-format json \
--json-schema '{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string"},"callSites":{"type":"array","items":{"type":"string"}},"proposal":{"type":"string","enum":["wrapper","rewrite","manual"]},"reason":{"type":"string"}},"required":["object","proposal","reason"]}}},"required":["items"]}' \
| jq '.structured_output.items[]'ここで使っているのは、非対話モードの標準的な機能です。
-pで非対話実行にする--allowedToolsで読み取り系のツールだけを事前承認する--json-schemaで出力の形を固定する。結果はstructured_outputに入る
--allowedTools に書き込み系を入れていないので、この実行でソースは変わりません。分類の提案を読んでから、手を入れる段階に進みます。
出力が有効な構造化出力にならなかった場合、structured_output フィールド自体が付きません。後続の jq に流す前に、フィールドがあるかを確かめます。
CIのように、ホスト環境のフックやCLAUDE.mdを読み込ませたくない場面では --bare を付けます。ただし --bare はサブスクリプションのログインを使わないため、ANTHROPIC_API_KEY を環境に設定しておく必要があります。この仕分けでは手元のCLAUDE.mdを読ませたいので、付けない構成です。claude -p 全般の扱いはclaude -p の解説にあります。
標準入力にログを流し込む場合は10MBの上限があります。指摘の一覧が大きいときは、パイプでなくファイルを渡します。上限の挙動はclaude -p の10MB上限の記事で扱っています。
置換APIで済むものとラッパーが要るものの境目
Bの中でも、作業の重さはさまざまです。後継の種類で見ておくと、見積もりが立てやすくなります。
| 後継の形 | 作業の中身 |
|---|---|
oneObjectで同じ種別 | 作業の中身名前の差し替えと、パラメータの見直し |
oneObjectで種別が変わる | 作業の中身呼び出し方の書き換え(例: 関数モジュールからBDEFへ) |
multipleObjects | 作業の中身使う項目から後継を選ぶ設計作業 |
concept | 作業の中身オブジェクトでなく仕組みの置き換え |
Cは、READMEが「クラシックAPIをラッパーとして使い、ABAP Cloudへ橋渡しする」と案内している領域です。READMEは、フィルタをclassic APIとラベル transactional-consistent に絞った一覧を紹介しています。ラッパーの生成には、SAPのサンプルリポジトリ tier2-rfc-proxy が使えます。
ラベルは優先順位の手がかりになります。transactional-consistent が付くクラシックAPIは、READMEの「Related projects」でラッパーの候補として絞り込み条件に挙がっています。BAPI_PO_CREATE1 のように両方のラベルが付いたものから着手すると、橋渡しの設計を最初に固められます。一方、CL_SALV_TABLE のようにラベルが無いクラシックAPIは、JSONからは分かる情報が少ない状態です。ラッパーにするか、呼び出しを別の仕組みへ置き換えるかを、画面側の使い方まで見て決めます。
仕分けがずれるときの確認先
結果が想定とずれたときは、次の順に当たります。
- Aが多い: ATCが参照しているJSONの版と、手元のJSONが違うことを疑います。READMEは、ATCチェックの属性にJSONのURLを入れる手順を示しています。URLが古い版のままになっていないかを見ます
- Dが多い: 自作の
Z名前空間オブジェクトはDに入ります。自作オブジェクトを公開扱いにする仕組みはREADMEの要件にあり、SAPノート3507814が挙がっています - ATCが外部のJSONを取れない: READMEはSAPノート3582797で、チェック「Usage of APIs」がSSL handshake failedになる場合を案内しています。S/4システムからgitへの接続を成り立たせる設定が前提です
- チェック名が見つからない: JSONの中に、旧チェックバリアントから新しいものへの後継が載っています。例えば
SAP_CP_READINESSの後継はABAP_CLOUD_READINESSです
READMEには、ATCチェックを使うための前提ノートも並んでいます。ノート3284711、3377462、3507814が挙がり、クリーンコア向けでは3449860や3565942が登場します。仕分けの前に、システム側でこれらが当たっているかをBasis担当に確かめておくと、手戻りが減ります。
まとめ
ATC指摘の仕分けは、照合と判断を分けると進みます。公開リポジトリのJSONとの突き合わせは、スクリプトで決定的に行います。Claude Codeには、そのスクリプトを書かせることと、CとDの呼び出し箇所を読ませることを任せます。
最初の一手は、Bのうち後継が1つで種別も同じものです。ここを片付けるだけで指摘の山が減り、残りがCとDに絞れます。SAP連携を別の側面から見るなら、Claude SAP連携ガイドも参考になります。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。
関連する記事
Claude Code をもっと見る →Claude Codeとは — できること・料金・始め方と使い方の全体像
Claude CodeでSalesforce Code Analyzerの指摘を直す・抑える・保留に振り分ける
Claude CodeでIAMの未使用アクセスキーを棚卸しする — credential reportで削除候補を分ける
Claude CodeでCognitoのカスタムクレームを書く — pre token generationを単体テスト
Claude CodeでYouTube Data APIの消費量を見積もり全動画を取る
ShopifyのGraphQLレート制限をClaude Codeで守る — 待ち時間の計算とbulk切替