From sap-gen-code
Validates DDIC objects (domains, data elements, tables) extracted from a design document. Checks naming conventions, data type validity, and cross-references between domains, data elements, and table fields. Optionally verifies existence in SAP system via RFC_READ_TABLE on DD01L/DD04L if SAP login info is provided. Input: work folder path containing {doc_name}_domains.txt, _dataElements.txt, _tables.txt Output: {work_folder}/check_result_ddic.txt
How this skill is triggered — by the user, by Claude, or both
Slash command
/sap-gen-code:sap-docs-check-ddic <work-folder-path> [<sap-logon-description>]<work-folder-path> [<sap-logon-description>]The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You validate DDIC object definitions extracted from a design document before they are created in SAP via `/sap-se11`.
You validate DDIC object definitions extracted from a design document before they are created in SAP via /sap-se11.
Task: $ARGUMENTS
| File | Token | Purpose |
|---|---|---|
sap-dev-core/shared/tables/sap_object_naming_rules.tsv | (read by helper) | DDIC naming patterns (DDIC_DOMAIN / DDIC_DATAELEMENT / DDIC_TABLE). Custom override: {custom_url}\sap_object_naming_rules.tsv |
sap-dev-core/shared/scripts/sap_check_object_name.ps1 | (helper) | Shared name validator invoked in Steps 2a / 3a / 4a |
Settings reads/writes follow <SAP_DEV_CORE_SHARED_DIR>/rules/settings_lookup.md — merge settings.local.json over settings.json per-key on the .value field; writes always go to settings.local.json. Read work_dir (default C:\sap_dev_work).
Set {WORK_TEMP} = {work_dir}\temp and ensure it exists:
cmd /c if not exist "{WORK_TEMP}" mkdir "{WORK_TEMP}"
Start a structured log run. State file: {WORK_TEMP}\sap_docs_check_ddic_run.json. Best-effort.
powershell -ExecutionPolicy Bypass -File "<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_log_helper.ps1" -Action start -StateFile "{WORK_TEMP}\sap_docs_check_ddic_run.json" -Skill sap-docs-check-ddic -ParamsJson "{\"work_folder\":\"<WORK_FOLDER>\"}"
Extract from $ARGUMENTS:
Find and read:
{doc_name}_domains.txt (optional — skip domain checks if missing){doc_name}_dataElements.txt (optional — skip DE checks if missing){doc_name}_tables.txt (optional — skip table checks if missing)For each domain in _domains.txt:
powershell -ExecutionPolicy Bypass -File "<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_check_object_name.ps1" -ObjectType DDIC_DOMAIN -ObjectName <NAME> -CustomUrl "{custom_url}"
Exit 1 → emit a Naming / Warning row in the result file with the
validator's stdout line. Exit 2 → log once and skip.Valid SAP ABAP Dictionary data types:
CHAR, NUMC, DATS, TIMS, DEC, CURR, QUAN, UNIT, LANG, CLNT, INT1, INT2, INT4, INT8, FLTP, STRING, SSTRING, RAWSTRING, RAW, ACCP, DF16_DEC, DF16_RAW, DF34_DEC, DF34_RAW
Check:
X, data type should be numeric (DEC, CURR, QUAN, FLTP)For each data element in _dataElements.txt:
-ObjectType DDIC_DATAELEMENT),
same invocation pattern as Step 2a. Violation → Naming / Warning.Offline mode (no SAP login):
DOMNAME exists in the _domains.txt listOnline mode (SAP login provided):
_domains.txt listTable: DD01L
Fields: DOMNAME
Options: DOMNAME = '{domain_name}' AND AS4LOCAL = 'A'
Use SAP.Functions COM object with 32-bit cscript:
Set oRFC = oFunctions.Add("RFC_READ_TABLE")
oRFC.Exports("QUERY_TABLE") = "DD01L"
oRFC.Exports("DELIMITER") = "|"
' Set FIELDS table
Set oFields = oRFC.Tables("FIELDS")
oFields.Rows.Add
oFields(oFields.RowCount, "FIELDNAME") = "DOMNAME"
' Set OPTIONS table
Set oOptions = oRFC.Tables("OPTIONS")
oOptions.Rows.Add
oOptions(oOptions.RowCount, "TEXT") = "DOMNAME = '" & sDomainName & "' AND AS4LOCAL = 'A'"
oRFC.Call
' Check DATA table row count
If oRFC.Tables("DATA").RowCount = 0 Then
' Domain does not exist
End If
If not found in SAP either → Error: "Domain does not exist"
For each table in _tables.txt:
-ObjectType DDIC_TABLE),
same invocation pattern as Step 2a. Violation → Naming / Warning.For each field's DATAELEMENT value:
Offline mode:
_dataElements.txt listOnline mode (SAP login provided):
_dataElements.txt listTable: DD04L
Fields: ROLLNAME
Options: ROLLNAME = '{dtel_name}' AND AS4LOCAL = 'A'
If not found → Error: "Data element does not exist"
A common spec mistake: customers write a primitive DDIC type (e.g. CHAR4,
DEC10) in the DATAELEMENT column. SE11 rejects these — only real data
elements work.
However, several primitive-shaped names ARE real SAP-shipped data
elements (e.g. NUMC1, NUMC2, NUMC3, NUMC4, DATS, TIMS, CHAR1).
A regex-only rule produces false positives for those.
Detection: regex against the DATAELEMENT value:
^(CHAR|NUMC|DATS|TIMS|DEC|CURR|QUAN|UNIT|RAW|RAWSTRING|STRING|SSTRING|FLTP|INT1|INT2|INT4|INT8|LANG|CLNT|ACCP|LCHR|LRAW|DF16_DEC|DF34_DEC)\d*$
If matched, BEFORE flagging: confirm the name is NOT a real DTEL.
Warning only, with a hint that the user
should verify the name is a real DTEL or wrap it in a project DE. Never
emit Error from this rule alone in offline mode (false-positive risk).RFC_READ_TABLE on DD04L with
ROLLNAME = '<X>' AND AS4LOCAL = 'A'. The result determines severity:
"DATAELEMENT='<X>' looks like a primitive DDIC type and does not exist as a data element. Wrap it in a project data element (e.g. ZHKDE_SEQ) using a domain (ZHKDM_NUMC3) of that primitive type."In short: rule 4b-1 is a hint to a missing-DTEL error, never a standalone fail. If the name resolves to a real DTEL via DD04L, the regex is wrong and we say nothing.
For a field of CURR type, SAP DDIC requires BOTH ReferenceTable AND
Ref.Field to be populated — including the self-referencing case where the
WAERK column lives in the same table being defined. SE11 on modern S/4HANA
(verified on 1909 and later) refuses to activate a CURR column whose
ReferenceTable is blank, even if Ref.Field is set.
NOTE: an older NetWeaver-era convention permitted leaving ReferenceTable
blank when the reference was to the same table. That convention is
deprecated; do not apply it on S/4HANA. (This rule was inverted on
2026-05-09 after a real deployment surfaced the contradiction.)
Detection: field underlying type is CURR (lookup via _dataElements.txt
→ _domains.txt → DATATYPE) AND (ReferenceTable is blank OR Ref.Field
is blank).
If matched → Error: "CURR field '<F>' is missing ReferenceTable or Ref.Field. SE11 requires both to be populated, including for self-referencing currency fields. Set ReferenceTable=<the table containing the WAERK column> and Ref.Field=<the WAERK column name>."
Walk every data element in _dataElements.txt and look up its DOMNAME in
_domains.txt. Catches the most common typo: a missing/extra digit on the
suffix (e.g. DTEL points at ZHKDM_KEY13 but the spec only defines
ZHKDM_KEY131).
Detection: DTEL.DOMNAME is in Z* / Y* namespace AND not present in
_domains.txt AND (offline) or (not found in DD01L online).
If matched → Error: "DTEL '<DE>' points at DOMNAME='<DOM>' which is not in _domains.txt and not a standard SAP domain. Likely typo — _domains.txt has these similar names: <fuzzy-match-suggestions>". Suggest the closest names by Levenshtein distance ≤ 2.
Detect when domain/DTEL/table names in the same spec use different suffix
conventions (e.g. some end in 13, some in 131). Group all Z-namespace
names by their leading 3 chars (project sub-prefix) and inspect the
trailing numeric segment. If two distinct trailing segments appear within
the same spec → flag as Warning: "Naming convention drift: spec uses both '<suffix-A>' and '<suffix-B>' on Z-namespace objects. Pick one and apply consistently."
For every field in _tables.txt with a non-blank ReferenceTable that
is a STANDARD SAP table (not in the spec's own _tables.txt), verify
via RFC that the table exists AND its Ref.Field exists on it. Catches:
T100 vs T001).T001-WAERK where the actual currency field
might be T001-WAERS).Self-referencing CURR/QUAN fields (ReferenceTable = the same Z* table
defined in this spec) are already covered by Step 4b-2 and the spec's
own field list — no live lookup needed for those.
Detection: walk _tables.txt. For each row with ReferenceTable
matching a standard table (uppercase, doesn't appear in spec's
_tables.txt):
<ReferenceTable>\t<Ref.Field>\tTable <T> field <F> ReferenceTable\tCross-reference
into {WORK_TEMP}\spec_refs_request.txt.<ReferenceTable> names into {WORK_TEMP}\struct_request.txt.<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_rfc_lookup_struct.ps1
to populate {work_folder}\_struct_signatures.txt (same cache
/sap-gen-abap Step 1.5e uses — gen-abap will reuse what this
check populated).<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_check_spec_refs.ps1
to validate. The validator appends rows to
{work_folder}/check_result_ddic.txt in the same TSV format the
rest of this skill uses.If matched → Error: "ReferenceTable <T>.<F> referenced by field <X> does not exist (per live DDIF_FIELDINFO_GET)." — fix advice
points at SE11 lookup for the correct table+field.
When RFC is unavailable, downgrade to Warning with hint to verify manually post-deploy.
Write only problems (errors and warnings) to {work_folder}/check_result_ddic.txt in TAB-separated format (so the user can open it in Excel to review and update):
No Object Type Object Name Check Description Severity Status
1 Domain ZHKDM_AMT9 DataType CURR type should have DECIMALS defined Warning Open
2 Table ZHKFIXEDVALS9 Field Data element NUMC3 not in design document and not verified in SAP Warning Open
3 DataElement ZHKDE_KEY1 Domain DOMNAME='ZHKDM_KEY13' not in _domains.txt. Closest match: ZHKDM_KEY131 (typo?) Error Open
4 Table ZHKFIXEDVALS Field DATAELEMENT='NUMC3' looks like a primitive DDIC type, not a data element. Wrap in ZHKDE_SEQ. Error Open
Columns:
Domain, DataElement, TableName, DataType, Domain, Field, Key, Naming)Error (blocks SE11 creation) or Warning (proceeds with assumption)Open (user updates to Fixed or Ignored after review)Do NOT include items that passed checks — only record problems.
Report to the user:
/sap-se11 to create DDIC objects in SAPLog the run-end record. Best-effort.
On success:
powershell -ExecutionPolicy Bypass -File "<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_log_helper.ps1" -Action end -StateFile "{WORK_TEMP}\sap_docs_check_ddic_run.json" -Status SUCCESS -ExitCode 0
On failure:
powershell -ExecutionPolicy Bypass -File "<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_log_helper.ps1" -Action end -StateFile "{WORK_TEMP}\sap_docs_check_ddic_run.json" -Status FAILED -ExitCode 1 -ErrorClass <CLASS> -ErrorMsg "<short>"
Suggested <CLASS>: DDIC_CHECK_FAILED, INPUT_NOT_FOUND.
npx claudepluginhub sapdev-ai/sap-dev --plugin sap-gen-codeSearches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.