Files
arena-plm-fiori/docs/handover/rap
alexzandClaude Opus 5 ffd33f4ec0 ADR-004: back out of on-stack RAP; retarget to starter customizing tenant
Both tenants belong to the same starter system: my429480 is its
customizing tenant (client 100, key-user extensibility only, no ABAP)
and my431353 is its development tenant (client 080). This package had
recorded my429480 as "productive" and ADR-002 had assumed it offered
developer extensibility; both were wrong.

- ADR-004 withdraws the on-stack RAP route and moves the application to
  a side-by-side runtime against released OData APIs. ADR-002 marked
  superseded.
- Development tenant my431353 parked: all 19 ZARENA_PLM objects left
  active, sources kept in docs/handover/rap/ as reference, so the route
  stays reversible.
- Replacement host left open as OQ-11 (key-user extensibility vs CAP
  side-by-side); recommendation recorded as CAP. No build starts until
  OQ-11 is closed.
- RAP-dependent items V-2, V-3, OQ-5, OQ-8, OQ-9, OQ-10 parked rather
  than closed.
- Tenant references corrected across CLAUDE.md, KNOWLEDGE.md,
  app/README.md, the RAP handover README, the rap-developer agent and
  the reentrance-login helper README.

No SAP tenant was modified.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-29 10:33:29 -07:00
..

RAP handover: Arena change-approval BO, built from an empty package (rev. 2026-09-16, corrected after the UI leg went live)

Parked 2026-09-29. This handover records the client 080 build as it was carried out. The starter system's development tenant my431353 is parked as of 2026-09-29 and its objects are left in place; the working target is now the starter system's customizing tenant my429480 (client 100, key-user extensibility only — no ABAP/RAP). Keep this document as the build record and reference.

Target: the starter system's development tenant my431353 (ADT destination 0M7DEJI), package ZARENA_PLM, a sub-package of ZLOCAL with no transport. No generator is used. Every object is created empty through the ADT MCP abap_creation-create_object, filled by pasting a file from this folder into the VS Code ADT editor, saved, and activated through abap_activate_objects. The ADT MCP cannot write source (PRD V-4).

Most source files start with a header comment that names the target object, its abap: URI and its README step. The two service definition sources (U13 zui_arena_change_approval.srvd.srvdsrv, W4 zapi_arena_change_approval.srvd.srvdsrv) carry no comment at all, because a comment blocks SRVD activation on this tenant (see Landmines). Their former header content is in the U13 and W4 notes below. Where a header's abap: URI disagrees with this README, this README and the filePath returned by create_object win. The U6 and U9 BDEF headers still name the generator-era .bdef.json; they are left as they were, because those objects are already active. The W3 header, not yet pasted, names .bdef.abdl.

The entity set, properties and actions match the Fiori app contract: entity set ChangeApproval, key ID, bound actions approve, reject(RejectReason), retrySync. The UI service is published at /sap/opu/odata4/sap/zui_arena_change_appr_o4/srvd/sap/zui_arena_change_approval/0001/ (the UI binding was shortened to fit the 26-character limit, D-1). The app was reconciled to that live service on 2026-09-16 (CHANGELOG): dataSource URL, namespace com.sap.gateway.srvd.zui_arena_change_approval.v0001 (taken from the service definition, not the binding) and entity type ChangeApprovalType (no underscore), all from the live $metadata in docs/v2/zui_arena_change_appr_o4.metadata.xml (live 2026-09-16; KNOWLEDGE 2026-09-16). Text in this folder that says ChangeApproval_Type, or that the binding name sets the namespace, predates that capture and is marked where it remains.

Citations use [source: <server> <doc-id>, verified <date>]. The servers are abap-docs, sap-docs, sap-released-objects, and adt-mcp for live tool answers on 0M7DEJI. Observations made in the editor or browser, with no tool answer to cite, are marked (live <date>).

Status (2026-09-16)

  • UI leg U1–U14: ACTIVE and ATC-clean. All 14 objects answered "Activation successful." ATC over the 14 objects: 0 errors, 0 warnings, 43 infos (worklist 12ACF6BD93811FE1ACB8096AC6763BD6) [source: adt-mcp abap_activate_objects, abap_atc_get_result on 0M7DEJI, verified 2026-09-16]. The MCP returns only totals by priority, so the 43 infos are read in the ADT ATC view. Infos do not gate publishing.
  • UI binding ZUI_ARENA_CHANGE_APPR_O4: PUBLISHED 2026-09-16 04:26, with the Publish code lens in the binding's .srvb.json source editor (U15). The ADT MCP has no publish tool, and VS Code shows no confirmation beyond " published locally". The publish was therefore verified by tool: fetch_services reports isPublished: true, and fetch_service_information returns https://my431353-api.s4hana.cloud.sap/sap/opu/odata4/sap/zui_arena_change_appr_o4/srvd/sap/zui_arena_change_approval/0001/?sap-client=080 with entity set ChangeApproval [source: adt-mcp abap_business_services-fetch_services, fetch_service_information on 0M7DEJI, verified 2026-09-16].
  • Where the live service answers: on the UI host my431353.s4hana.cloud.sap. The same path on the -api host that fetch_service_information reports is refused to a business user as "Forbidden / blocked by UCON" (live 2026-09-16; KNOWLEDGE 2026-09-16). The -api host is the communication-user entry point.
  • Worker leg W1–W5: started on the tenant 2026-09-16 06:14 (PRD status). Run it exactly as in "Worker leg" below. This README records no worker-leg result.
  • Package: ZARENA_PLM exists again under ZLOCAL (recreated 2026-09-16; validation in it succeeded live at 02:27, CHANGELOG). Historical, before step 0: the package had been deleted together with its contents, and abap_creation-run_validation answered "Package 'ZARENA_PLM' does not exist." for TABL, DDLS and CLAS [source: adt-mcp on 0M7DEJI, verified 2026-09-16].

Object inventory and name limits

Step Object Type (create code) Source file(s) Length / limit
U1 ZCHANGEAPPROVAL TABL (TABL/DT) zchangeapproval.tabl.asddls 15 / 16
U2 ZD_CHANGEAPPROVAL_REJECTP DDLS (DDLS/DF) zd_changeapproval_rejectp.ddls.asddls 25 / 30
U3 ZD_CHANGEAPPROVAL_SYNCEDP DDLS (DDLS/DF) zd_changeapproval_syncedp.ddls.asddls 25 / 30
U4 ZD_CHANGEAPPROVAL_FAILEDP DDLS (DDLS/DF) zd_changeapproval_failedp.ddls.asddls 25 / 30
U5 ZR_CHANGEAPPROVAL DDLS (DDLS/DF) zr_changeapproval.ddls.asddls 17 / 30
U6 ZR_CHANGEAPPROVAL BDEF (BDEF/BDO) zr_changeapproval.bdef.asbdef 17 / 30
U7 ZBP_R_CHANGEAPPROVAL CLAS (CLAS/OC) zbp_r_changeapproval.clas.abap + .clas.locals_imp.abap 20 / 30
U8 ZC_CHANGEAPPROVAL DDLS (DDLS/DF) zc_changeapproval.ddls.asddls 17 / 30
U9 ZC_CHANGEAPPROVAL BDEF (BDEF/BDO) zc_changeapproval.bdef.asbdef 17 / 30
U10 ZR_CHANGEAPPROVAL DCLS (DCLS/DL) zr_changeapproval.dcls.asdcls 17 / 30
U11 ZC_CHANGEAPPROVAL DCLS (DCLS/DL) zc_changeapproval.dcls.asdcls 17 / 30
U12 ZC_CHANGEAPPROVAL DDLX (DDLX/EX) zc_changeapproval.ddlx.asddlx 17 / 40
U13 ZUI_ARENA_CHANGE_APPROVAL SRVD (SRVD/SRV) zui_arena_change_approval.srvd.srvdsrv (no comments) 25 / 30
U14 ZUI_ARENA_CHANGE_APPR_O4 SRVB (SRVB/SVB), OData V4 - UI none in this folder; create_object returns .srvb.json 24 / 26 (D-1)
W1 ZC_CHANGEAPPROVAL_A2X DDLS (DDLS/DF) zc_changeapproval_a2x.ddls.asddls 21 / 30
W2 ZC_CHANGEAPPROVAL_A2X DCLS (DCLS/DL) zc_changeapproval_a2x.dcls.asdcls 21 / 30
W3 ZC_CHANGEAPPROVAL_A2X BDEF (BDEF/BDO) zc_changeapproval_a2x.bdef.asbdef 21 / 30
W4 ZAPI_ARENA_CHANGE_APPROVAL SRVD (SRVD/SRV) zapi_arena_change_approval.srvd.srvdsrv (no comments) 26 / 30
W5 ZAPI_ARENA_CHANGE_APPR_A2X SRVB (SRVB/SVB), Web API (see W5 for the exact bindingType value) none in this folder; .srvb.json expected, as U14 26 / 26 (D-1)

Limits: TABL/DT 16; DDLS/DF, BDEF/BDO and SRVD/SRV 30 [source: adt-mcp abap_creation-get_object_type_details on 0M7DEJI, verified 2026-09-16]. Service bindings: 26 per SAP Help. The ADT MCP accepts 30 for SRVB/SVB, but that is undocumented and not used here (D-1). The documentation agrees for tables ("maximum of 16 characters") [source: abap-docs /abap-docs-cloud/ABENDDIC_DBTAB_NAMES, verified 2026-09-16] and for CDS view entities ("maximum of 30 characters"; the DDL source and the CDS entity must have the same name) [source: abap-docs /abap-docs-cloud/ABENCDS_DEFINE_VIEW_ENTITY, verified 2026-09-16]. CLAS/OC and DCLS/DL allow 30 and DDLX/EX allows 40 [source: adt-mcp abap_creation-get_object_type_details on 0M7DEJI, verified 2026-09-16] (KNOWLEDGE 2026-09-16; these were "not recorded" in the pre-build revision).

Not created: a projection behavior pool (see design decisions) and an SAP object type or node type. No documentation found makes an SAP object type mandatory for a RAP BO. SAP Help lists it only as one of the objects the "OData UI Service from Scratch" wizard generates [source: sap-docs sap-help loio d3f5e90a306a44b6b37b8b05f04d2c10, verified 2026-09-16]. Business events are the case that requires @ObjectModel.sapObjectNodeType.name [source: sap-docs /btp-cloud-platform/30-development/log-custom-business-events-6ecc451, verified 2026-09-16]. Add one if the BO later raises business events.

Split: the UI leg has 14 source files (13 objects with source + the U14 binding). The worker leg has 4 source files (+ the W5 binding). The markSynced/markFailed parameter entities (U3, U4) belong to the UI leg because the base BDEF (U6) names them. They must be active before U6 activates.

Resolved decisions

  • D-1: service binding names stay within 26 characters (resolved 2026-09-16). SAP Help gives 26 characters as the maximum length for a service binding name in every version checked: ABAP Cloud [source: sap-docs sap-help loio 4bad0d7280b742a68dd2d42b1441f09a, verified 2026-09-16], SAP Cloud Platform [source: sap-docs sap-help loio f3e608ace2a64aada33bdd3e2419113a and 6709cab6cb5b4c01b28463d760429a9a, verified 2026-09-16], and ABAP Platform 2021 [source: sap-docs sap-help loio 777e027f61c3490dba0433443d9143a6, verified 2026-09-16]. The ADT MCP's 30 is undocumented. The bindings are therefore:

    • UI binding ZUI_ARENA_CHANGE_APPR_O4 (24), replacing the 28-character long form.
    • Web API binding ZAPI_ARENA_CHANGE_APPR_A2X (26), replacing the 30-character long form.

    The service definitions ZUI_ARENA_CHANGE_APPROVAL (25) and ZAPI_ARENA_CHANGE_APPROVAL (26) and every other object name are unchanged. Consequence: the binding name is the first URL segment, so the app's dataSource URL had to change. Live correction (2026-09-16): the pre-build text here also said the binding name sets the schema namespace. It does not; the live namespace com.sap.gateway.srvd.zui_arena_change_approval.v0001 comes from the service definition (live 2026-09-16, docs/v2/zui_arena_change_appr_o4.metadata.xml; KNOWLEDGE 2026-09-16). The app was reconciled to the live service on 2026-09-16 (CHANGELOG). The PRD worker contract row now names ZAPI_ARENA_CHANGE_APPR_A2X (PRD read 2026-09-16), so that governance item is closed. U14 published under its 24-character name, so a name within 26 is proven to publish. Whether publishing accepts more than 26 is still unknown (KNOWLEDGE 2026-09-16).

Preconditions

  1. VS Code with ADT (sapse.adt-vscode) is running, destination 0M7DEJI is logged on, and the ADT MCP answers on http://127.0.0.1:2236/mcp. After a VS Code reload, refresh the bearer token in .mcp.json (CLAUDE.md). A Claude Code session exposes the adt-mcp tools only if the server was up when the session started (KNOWLEDGE 2026-09-16).
  2. abap_list_destinations lists 0M7DEJI.

Step 0: recreate the package (done 2026-09-16)

Done: ZARENA_PLM exists again under ZLOCAL, validation in it succeeded live at 02:27, and abap_transport-get answered isRecordingRequired: false (CHANGELOG 2026-09-16). The steps below are kept as the record.

In ADT (VS Code or Eclipse), create development package ZARENA_PLM with super-package ZLOCAL, no transport. The ADT MCP has no package tool. Use a ZLOCAL sub-package because ZLOCAL itself is a structure package, $TMP fails the language-version authorization, and sub-packages of ZLOCAL created from release 2508 need no workbench request [source: sap-docs sap-help loio a0d80f14fcb74cb1ac8fb6f3d9ad48cc (2608), verified 2026-09-15; refusals live 2026-09-15, KNOWLEDGE].

Check it read-only: abap_creation-run_validation for TABL/DT with the U1 JSON must no longer answer "Package 'ZARENA_PLM' does not exist". Then call abap_transport-get once for U1 (objectType TABL/DT, developmentPackage ZARENA_PLM, isCreation true) and expect "recording not required". Every create_object below uses "transportRequestNumber": "".

Per-object routine

For every step:

  1. abap_creation-get_object_type_details (objectType, name, description). It lists the required fields and limits. If it names a required field that the JSON below lacks, add it and note it.
  2. abap_creation-run_validation with the JSON.
  3. abap_creation-create_object with the same JSON, destination 0M7DEJI, transport "". Record the filePath it returns. That path is both the paste target and the activation URI.
  4. Open that source file in the VS Code ADT editor, replace the whole content with the handover file (its header comment included where it has one; the SRVD files have none and must stay comment-free), and save. A DDIC database table is edited as Dictionary DDL source generated from its metadata [source: abap-docs /abap-docs-cloud/ABENDDIC_DEFINE_TABLE, verified 2026-09-16].
  5. abap_activate_objects with the returned filePath (URL-encoded, spaces as %20). The activation table below is a cross-check, not a substitute. Fix errors before the next step.

General rule (live 2026-09-16): in the VS Code ADT workspace, the .json file in an object folder is header metadata and never receives pasted source. Always use the filePath returned by create_object. For example, zchangeapproval.tabl.json holds only formatVersion, description, originalLanguage and abapLanguageVersion, and the table source lives in zchangeapproval.tabl.ddic [source: adt-mcp abap_creation-create_object / abap_activate_objects on 0M7DEJI, verified 2026-09-16]. The returned source files are TABL .tabl.ddic, DDLS .ddls.acds, DCLS .dcls.acds, DDLX .ddlx.acds, BDEF .bdef.abdl, CLAS .clas.abap and SRVD .srvd.acds. Among the types in this build, the one returned filePath that is a .json is the service binding's .srvb.json. Nothing is pasted into it, the binding is activated through it (U14), and its editor carries the Publish code lens (U15).

Create-metadata tags per type [source: adt-mcp abap_creation-get_object_type_details on 0M7DEJI, verified 2026-09-16]:

  • TABL/DT: packageName, name, description.
  • DDLS/DF: packageName, name, description, optional referencedObject (omitted here).
  • SRVD/SRV: packageName, name, description, sourceType (S | X | none). Use "S": it worked live, and omitting it fails with "serviceDefinitionInfo.sourceType is null" (live 2026-09-15). SRVD/SRV also offers an optional referencedObject (omitted here) [source: adt-mcp get_object_type_details on 0M7DEJI, verified 2026-09-16].
  • SRVB/SVB: packageName, name, description, bindingType, serviceDefinition. Proven bindingType value: OData V4 - UI (U14, 2026-09-16). The Web API value is not proven; see W5.
  • BDEF/BDO: behaviorDefinitionType, packageName, rootEntity, name, description, implementationType (Managed | Unmanaged | Projection | Abstract | Interface).
  • CLAS/OC: packageName, name (≤30), description, optional superclass and interfaces (none needed here). DCLS/DL: packageName, name (≤30), description, optional protectedEntity. DDLX/EX: packageName, name (≤40), description, optional extendedEntity [source: adt-mcp abap_creation-get_object_type_details on 0M7DEJI, verified 2026-09-16]. The pre-build revision marked these three "tags not recorded"; the JSON in the UI-leg table below still carries that marker as the record.

Descriptions are kept at 40 characters or fewer. The per-type description limit was not recorded.

BDEF and SRVB creation validates the referenced DDLS/SRVD's active version (live 2026-09-15: "The referenced STOB object … does not exist"; "An active version of the Service Definition … does not exist"). The sequence below always activates the referenced object first.

UI leg (first; done 2026-09-16)

Done: U1–U14 are active, ATC-clean, and the U14 binding is published (see Status). Do not re-run this table. It is kept as the build record. The JSON column is the pre-build plan: the (tags unconfirmed) markers were settled on 2026-09-16 (per-object routine), and U10 was created with protectedEntity added (CHANGELOG 2026-09-16).

Step create_object JSON (objectType) Paste Depends on (active)
U1 TABL/DT {"packageName":"ZARENA_PLM","name":"ZCHANGEAPPROVAL","description":"Arena change approval"} zchangeapproval.tabl.asddls none
U2 DDLS/DF {"packageName":"ZARENA_PLM","name":"ZD_CHANGEAPPROVAL_REJECTP","description":"Arena approval: reject parameter"} zd_changeapproval_rejectp.ddls.asddls none
U3 DDLS/DF {"packageName":"ZARENA_PLM","name":"ZD_CHANGEAPPROVAL_SYNCEDP","description":"Arena approval: markSynced parameter"} zd_changeapproval_syncedp.ddls.asddls none
U4 DDLS/DF {"packageName":"ZARENA_PLM","name":"ZD_CHANGEAPPROVAL_FAILEDP","description":"Arena approval: markFailed parameter"} zd_changeapproval_failedp.ddls.asddls none
U5 DDLS/DF {"packageName":"ZARENA_PLM","name":"ZR_CHANGEAPPROVAL","description":"Arena change approval"} zr_changeapproval.ddls.asddls U1
U6 BDEF/BDO {"behaviorDefinitionType":"definition","packageName":"ZARENA_PLM","rootEntity":"ZR_CHANGEAPPROVAL","name":"ZR_CHANGEAPPROVAL","description":"Arena change approval behavior","implementationType":"Managed"} zr_changeapproval.bdef.asbdef U2, U3, U4, U5
U7 CLAS/OC {"packageName":"ZARENA_PLM","name":"ZBP_R_CHANGEAPPROVAL","description":"Arena change approval behavior pool"} (tags unconfirmed) zbp_r_changeapproval.clas.abap (global class) + zbp_r_changeapproval.clas.locals_imp.abap (Local Types) U6
U8 DDLS/DF {"packageName":"ZARENA_PLM","name":"ZC_CHANGEAPPROVAL","description":"Arena change approval UI projection"} zc_changeapproval.ddls.asddls U5 (U6/U7 done)
U9 BDEF/BDO {"behaviorDefinitionType":"definition","packageName":"ZARENA_PLM","rootEntity":"ZC_CHANGEAPPROVAL","name":"ZC_CHANGEAPPROVAL","description":"Arena approval UI projection behavior","implementationType":"Projection"} zc_changeapproval.bdef.asbdef U6, U7, U8
U10 DCLS/DL {"packageName":"ZARENA_PLM","name":"ZR_CHANGEAPPROVAL","description":"Arena change approval access"} (tags unconfirmed) zr_changeapproval.dcls.asdcls U5
U11 DCLS/DL {"packageName":"ZARENA_PLM","name":"ZC_CHANGEAPPROVAL","description":"Arena approval UI projection access"} (tags unconfirmed) zc_changeapproval.dcls.asdcls U8, U10
U12 DDLX/EX {"packageName":"ZARENA_PLM","name":"ZC_CHANGEAPPROVAL","description":"Arena approval UI annotations"} (tags unconfirmed) zc_changeapproval.ddlx.asddlx U8
U13 SRVD/SRV {"packageName":"ZARENA_PLM","name":"ZUI_ARENA_CHANGE_APPROVAL","description":"Arena change approval UI service","sourceType":"S"} zui_arena_change_approval.srvd.srvdsrv U8, U9
U14 SRVB/SVB {"packageName":"ZARENA_PLM","name":"ZUI_ARENA_CHANGE_APPR_O4","description":"Arena change approval UI binding","bindingType":"OData V4 - UI","serviceDefinition":"ZUI_ARENA_CHANGE_APPROVAL"} none U13

Notes per step:

  • U1: paste zchangeapproval.tabl.asddls into zchangeapproval.tabl.ddic, never into zchangeapproval.tabl.json (metadata only, see the per-object routine). Proven: U1 activated through .tabl.ddic [source: adt-mcp abap_activate_objects on 0M7DEJI, verified 2026-09-16].
  • U6 then U7 (order matters). Resolved live 2026-09-16: U6 activated through .bdef.abdl on the first attempt, before class ZBP_R_CHANGEAPPROVAL existed, so the fallback below was not needed. U6 and U7 were then activated together in one call [source: adt-mcp abap_activate_objects on 0M7DEJI, verified 2026-09-16]. The pre-build instruction follows as the record. Activate the base BDEF before the behavior pool class exists, then create the class. SAP's RAP exercise does it that way [source: abap-docs /abap-platform-rap-opensap/week4/unit3#step-3-create-and-implement-the-behavior-implementation-bil-class-for-the-travel-entity, verified 2026-09-16]. That exercise is an unmanaged, non-strict BDEF. If U6 activation fails with an error saying class ZBP_R_CHANGEAPPROVAL does not exist, run U7's create and paste, then activate U6 and U7 together in one abap_activate_objects call. Also watch U6 for messages about the unmapped CDS-calculated elements StatusText, StatusCriticality, IsApprovable and IsRetriable. A warning is acceptable. An error triggers the fallback in the BDEF file header.
  • U7: paste the global class, then switch to the Local Types include and paste the handlers. Save both. Activate through the .clas.abap URI. The Local Types include also implements the checkDuplicate validation. Its duplicate query uses OPTIONS PRIVILEGED ACCESS. If the syntax check refuses that form, the documented fallback is in the include header. create_object for the class returned only the global .clas.abap path, no Local Types path (KNOWLEDGE 2026-09-16).
  • U9: no behavior pool is created for the projection (see design decisions). use etag is in the entity header, not the body (design decisions). create_object returned .bdef.abdl, and U9 activated through it [source: adt-mcp abap_creation-create_object, abap_activate_objects on 0M7DEJI, verified 2026-09-16].
  • U13: service definition ZUI_ARENA_CHANGE_APPROVAL (UI service). This note holds what the source file's header comment used to say. The header is gone, because it blocked activation.
    • abap: URI: abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Business%20Services/Service%20Definitions/ZUI_ARENA_CHANGE_APPROVAL/zui_arena_change_approval.srvd.acds
    • Action: create empty through the ADT MCP (SRVD/SRV, sourceType "S"), replace the entire content with zui_arena_change_approval.srvd.srvdsrv, save, and activate after the ZC_CHANGEAPPROVAL view (U8) and BDEF (U9). Then create the OData V4 UI binding ZUI_ARENA_CHANGE_APPR_O4 on it (U14).
    • What happened live (2026-09-16): the first activation failed with "Comments are not supported and will be deleted on save" (Ln 1, the header block comment) and "oData V4 services with no draft capability will be primarily READ-ONLY" (Ln 21). The same definition, re-saved without the comment, activated. The comment was the blocker; the draft message was not (the BO has no draft, by design) (live 2026-09-16; CHANGELOG 2026-09-16).
    • Contract: exposes exactly one entity set, ChangeApproval. The service URL (live, published) is /sap/opu/odata4/sap/zui_arena_change_appr_o4/srvd/sap/zui_arena_change_approval/0001/. The first segment is the binding (service group ZUI_ARENA_CHANGE_APPR_O4, 24 characters, within SAP Help's 26-character binding limit, D-1). The segment after srvd/sap/ is the binding's service alias (the service name in the binding editor), which can differ from this definition's name and can be renamed only while the binding is unpublished [source: sap-docs community-14433266 "How to rename an OData V4 service?" (SAP, 2026-07-04), verified 2026-09-16]. The former header called the app reconciliation pending. It was done on 2026-09-16 (CHANGELOG).
    • expose … as <alias>: the alias becomes the entity set (ChangeApproval) and the entity type (ChangeApproval_Type) [source: abap-docs /abap-fiori-showcase/06_object_page_content (Service Definition), verified 2026-09-15]. Live correction: the entity set is ChangeApproval, but the entity type is ChangeApprovalType, with no underscore (live 2026-09-16, docs/v2/zui_arena_change_appr_o4.metadata.xml; KNOWLEDGE 2026-09-16).
    • provider contracts odata_v4_ui switches on the UI-binding syntax checks and must match the binding type [source: abap-docs /abap-docs-cloud/ABENSRVD_PROVIDER_CONTRACT, verified 2026-09-15].
  • U14: Obsolete, removed: the pre-build instruction to open the binding in the editor before activating to check the alias. What was done and proven on 2026-09-16: create_object returned .srvb.json, U14 was activated through that filePath, and the alias was verified after activation with fetch_services: service ZUI_ARENA_CHANGE_APPROVAL, version 0001, OData V4, unpublished [source: adt-mcp abap_creation-create_object, abap_activate_objects, abap_business_services-fetch_services on 0M7DEJI, verified 2026-09-16]. The alias check must come before publishing, not before activating. The URL segment after srvd/sap/ is that alias, not necessarily the definition name, and it can be renamed only while the binding is unpublished [source: sap-docs community-14433266 "How to rename an OData V4 service?", verified 2026-09-16]. The binding name ZUI_ARENA_CHANGE_APPR_O4 (24) is within SAP Help's 26-character limit (D-1).

U15: checks and publish of the UI binding (done 2026-09-16)

  1. abap_atc_run on all 14 UI-leg objects: ZCHANGEAPPROVAL TABL; ZD_CHANGEAPPROVAL_REJECTP, ZD_CHANGEAPPROVAL_SYNCEDP, ZD_CHANGEAPPROVAL_FAILEDP, ZR_CHANGEAPPROVAL, ZC_CHANGEAPPROVAL DDLS; ZR_CHANGEAPPROVAL, ZC_CHANGEAPPROVAL BDEF; ZBP_R_CHANGEAPPROVAL CLAS; ZR_CHANGEAPPROVAL, ZC_CHANGEAPPROVAL DCLS; ZC_CHANGEAPPROVAL DDLX; ZUI_ARENA_CHANGE_APPROVAL SRVD; ZUI_ARENA_CHANGE_APPR_O4 SRVB. Then abap_atc_get_result. Result: 0 errors, 0 warnings, 43 infos (worklist 12ACF6BD93811FE1ACB8096AC6763BD6) [source: adt-mcp abap_atc_get_result on 0M7DEJI, verified 2026-09-16].
  2. abap_business_services-fetch_services on ZUI_ARENA_CHANGE_APPR_O4. Result: isPublished: false, service ZUI_ARENA_CHANGE_APPROVAL, version 0001, OData V4.
  3. Publish with the Publish code lens, not a button. Open the binding's .srvb.json source in the VS Code ADT editor and choose the Publish code lens in the source. In ADT for VS Code a service binding is a source-based editor, and publish, unpublish and preview are code lenses [source: sap-docs sap-help loio dd6f5de63e7245a7abe7e39389841596 "ABAP RAP Tools", verified 2026-09-16]. (Superseded wording: "the Publish button in the ADT service binding editor" describes the Eclipse form-based editor.) The binding must be active first [source: sap-docs sap-help loio b58a3c27df4e406f9335d4b346f6be04, verified 2026-09-16]. The ADT MCP has no publish tool. VS Code shows no confirmation beyond " published locally", so step 4 is the proof. Done 2026-09-16 04:26.
  4. fetch_services again (expect isPublished: true), then abap_business_services-fetch_service_information. The service URL path must equal /sap/opu/odata4/sap/zui_arena_change_appr_o4/srvd/sap/zui_arena_change_approval/0001/ exactly, and the entity set must be ChangeApproval. Result: both hold, on host my431353-api.s4hana.cloud.sap with sap-client=080 [source: adt-mcp abap_business_services-fetch_services, fetch_service_information on 0M7DEJI, verified 2026-09-16]. Business users and browser checks use the UI host my431353.s4hana.cloud.sap instead; -api refuses them (Landmines).
  5. Hand back the live $metadata for PRD V-2. Done: it is captured in docs/v2/zui_arena_change_appr_o4.metadata.xml, and the app was reconciled to it on 2026-09-16 (CHANGELOG). The pre-build expectation ChangeApproval_Type was wrong; the live entity type is ChangeApprovalType. See "App contract check" for the settled types.

Worker leg (second; run exactly this sequence)

Prerequisites, all met on 2026-09-16: the U5 root view, U6 base BDEF, U7 behavior pool and U10 root access control are active. Every step uses the per-object routine (details → validation → create → paste into the returned filePath → activate through the same filePath).

Step create_object JSON (objectType) Paste Needs (active)
W1 DDLS/DF {"packageName":"ZARENA_PLM","name":"ZC_CHANGEAPPROVAL_A2X","description":"Arena approval A2X projection"} zc_changeapproval_a2x.ddls.asddls into .ddls.acds activation: U5 (U6, U7 done)
W2 DCLS/DL {"packageName":"ZARENA_PLM","name":"ZC_CHANGEAPPROVAL_A2X","description":"Arena approval A2X projection access"} (no protectedEntity, see round 1) zc_changeapproval_a2x.dcls.asdcls into .dcls.acds activation: W1, U10
W3 BDEF/BDO {"behaviorDefinitionType":"definition","packageName":"ZARENA_PLM","rootEntity":"ZC_CHANGEAPPROVAL_A2X","name":"ZC_CHANGEAPPROVAL_A2X","description":"Arena approval A2X behavior","implementationType":"Projection"} zc_changeapproval_a2x.bdef.asbdef into .bdef.abdl creation: W1; activation: W1, U6, U7
W4 SRVD/SRV {"packageName":"ZARENA_PLM","name":"ZAPI_ARENA_CHANGE_APPROVAL","description":"Arena change approval Web API","sourceType":"S"} zapi_arena_change_approval.srvd.srvdsrv (no comments) into .srvd.acds activation: W1, W3
W5 SRVB/SVB {"packageName":"ZARENA_PLM","name":"ZAPI_ARENA_CHANGE_APPR_A2X","description":"Arena change approval Web API binding","bindingType":"OData V4 - Web API","serviceDefinition":"ZAPI_ARENA_CHANGE_APPROVAL"} (check bindingType, step 7) none creation: W4; activation: W4

Round 1: W1, W2 and W4 created empty and pasted; W1 and W2 activated.

  1. Create W1 (DDLS), W2 (DCLS) and W4 (SRVD) empty. Record each returned filePath.
    • W2: leave out the optional protectedEntity. W1 has no active version yet. BDEF creation is known to validate its referenced entity's active version; whether DCLS creation does the same for protectedEntity is untested. The pasted source replaces the skeleton anyway.
    • W4: "sourceType":"S" is required. Leave out the optional referencedObject.
  2. Paste W1, W2 and W4 into their returned source files and save all three. Never paste into a .json. W4 is pasted now but activated in round 2.
  3. Activate W1, then W2, in that order.

Round 2: W3 created and pasted; W3 then W4 activated.

  1. Create W3 (BDEF, Projection). This needs W1 active, because BDEF creation validates the referenced entity's active version (live 2026-09-15). Expect a filePath ending in .bdef.abdl.
  2. Paste W3 into that .bdef.abdl file and save.
  3. Activate W3, then W4.

Binding: W5 created and activated, not published.

  1. Check the bindingType string before creating. OData V4 - UI is proven (U14). The Web API value has not been seen live. SAP Help names the type OData V4 - Web API [source: sap-docs /btp-cloud-platform/30-development/service-bindings-c6dee8e, verified 2026-09-16], but the 2608 release note for ADT for VS Code calls it "OData V4 – API" [source: sap-docs sap-help loio 7f674e6190564228a5bb217ebf382611 (APPL-VSC-0011), verified 2026-09-16]. Take the exact value from get_object_type_details for SRVB/SVB if it lists one; otherwise run_validation with OData V4 - Web API settles it. If validation refuses the value and no allowed value is listed, stop and report the message rather than trying label variants. The type must be the Web API one: the provider contract odata_v4_webapi and the binding type must match, or an error occurs [source: abap-docs /abap-docs-cloud/ABENSRVD_PROVIDER_CONTRACT, verified 2026-09-16].
  2. Create W5 ZAPI_ARENA_CHANGE_APPR_A2X (needs W4 active). Activate it through its returned filePath (.srvb.json expected, as U14).
  3. Verify with abap_business_services-fetch_services on ZAPI_ARENA_CHANGE_APPR_A2X. Expect service ZAPI_ARENA_CHANGE_APPROVAL, version 0001, OData V4, and isPublished: false. That unpublished state is the intended end state of this handover. Do not follow the tool's prompt to have it published, and do not call fetch_service_information for W5.

W5 is NOT published in this handover. Web API exposure to the worker's communication user goes through a custom communication scenario (PRD V-2), together with the IAM app. That is a separate brief. The communication user will reach it on the -api host, the communication-user entry point (KNOWLEDGE 2026-09-16). The W5 name ZAPI_ARENA_CHANGE_APPR_A2X is 26 characters, exactly SAP Help's limit (D-1), and the PRD worker contract row names it.

Follow-up, not part of the sequence above: abap_atc_run on W1–W5 (DDLS, DCLS, BDEF, SRVD, SRVB), as U15 step 1 did for the UI leg.

Notes per step:

  • W3: the source header's abap: URI line was corrected from .bdef.json to .bdef.abdl on 2026-09-16 (comment only; no BDL change). Still use the returned filePath.
  • W4: service definition ZAPI_ARENA_CHANGE_APPROVAL (Web API service for the worker). This note holds what the source file's header comment used to say. The header is gone, for the U13 reason.
    • abap: URI: abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Business%20Services/Service%20Definitions/ZAPI_ARENA_CHANGE_APPROVAL/zapi_arena_change_approval.srvd.acds
    • Action: create empty through the ADT MCP (SRVD/SRV, sourceType "S"), replace the entire content with zapi_arena_change_approval.srvd.srvdsrv, save, and activate after the ZC_CHANGEAPPROVAL_A2X view (W1) and BDEF (W3). Then create the Web API binding ZAPI_ARENA_CHANGE_APPR_A2X on it (W5), and do not publish it.
    • Keep the source comment-free. A leading comment blocked U13's activation (U13 note). On U13 the "no draft capability … READ-ONLY" message did not block. If W4 activation fails and lists only that message, read its severity in the editor's Problems view before changing anything; the BO has no draft by design (CHANGELOG 2026-09-16).
    • Sources: as ZUI_ARENA_CHANGE_APPROVAL (U13 note); odata_v4_webapi is the Web API contract [ABENSRVD_PROVIDER_CONTRACT], re-read as [source: abap-docs /abap-docs-cloud/ABENSRVD_PROVIDER_CONTRACT, verified 2026-09-16].

Activation URIs for abap_activate_objects

Rule: activate through the filePath that create_object returned for the object (per-object routine). The table below is a cross-check. Pattern, learned live 2026-09-15 and unchanged for every object built on 2026-09-16: abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/<folder>/<NAME>/<name>.<ext>. In the VS Code workspace the .json file in an object folder is header metadata and never receives pasted source. Among the types in this build, SRVB is the one whose returned filePath is the .json (nothing is pasted there).

Extensions as returned by create_object for this build and proven by activation on 2026-09-16 [source: adt-mcp abap_creation-create_object, abap_activate_objects on 0M7DEJI, verified 2026-09-16]:

Type Folder Extension Proven by
TABL Dictionary/Database%20Tables .tabl.ddic U1. .tabl.json is header metadata only; it activated a generator-era table on 2026-09-15 and is not used
DDLS Core%20Data%20Services/Data%20Definitions .ddls.acds U2–U5, U8
BDEF Core%20Data%20Services/Behavior%20Definitions .bdef.abdl U6, U9. Generator-era record (2026-09-15, not for this build): .bdef.json activated a generator BDEF, and .bdef.acds, .bdef.asbdef and .bdef.abap failed with "array element 0 is null"
DDLX Core%20Data%20Services/Metadata%20Extensions .ddlx.acds U12
DCLS Core%20Data%20Services/Access%20Controls .dcls.acds U10, U11
CLAS Source%20Code%20Library/Classes .clas.abap U7 (no Local Types path is returned)
SRVD Business%20Services/Service%20Definitions .srvd.acds U13 (after the comment-free re-save)
SRVB Business%20Services/Service%20Bindings .srvb.json U14 (returned by create_object, activated through it)

In step order. The U lines are the URIs of the active objects. The W lines follow the proven pattern; confirm each against the returned filePath.

U1  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Dictionary/Database%20Tables/ZCHANGEAPPROVAL/zchangeapproval.tabl.ddic
U2  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Data%20Definitions/ZD_CHANGEAPPROVAL_REJECTP/zd_changeapproval_rejectp.ddls.acds
U3  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Data%20Definitions/ZD_CHANGEAPPROVAL_SYNCEDP/zd_changeapproval_syncedp.ddls.acds
U4  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Data%20Definitions/ZD_CHANGEAPPROVAL_FAILEDP/zd_changeapproval_failedp.ddls.acds
U5  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Data%20Definitions/ZR_CHANGEAPPROVAL/zr_changeapproval.ddls.acds
U6  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Behavior%20Definitions/ZR_CHANGEAPPROVAL/zr_changeapproval.bdef.abdl
U7  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Source%20Code%20Library/Classes/ZBP_R_CHANGEAPPROVAL/zbp_r_changeapproval.clas.abap
U8  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Data%20Definitions/ZC_CHANGEAPPROVAL/zc_changeapproval.ddls.acds
U9  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Behavior%20Definitions/ZC_CHANGEAPPROVAL/zc_changeapproval.bdef.abdl
U10 abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Access%20Controls/ZR_CHANGEAPPROVAL/zr_changeapproval.dcls.acds
U11 abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Access%20Controls/ZC_CHANGEAPPROVAL/zc_changeapproval.dcls.acds
U12 abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Metadata%20Extensions/ZC_CHANGEAPPROVAL/zc_changeapproval.ddlx.acds
U13 abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Business%20Services/Service%20Definitions/ZUI_ARENA_CHANGE_APPROVAL/zui_arena_change_approval.srvd.acds
U14 abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Business%20Services/Service%20Bindings/ZUI_ARENA_CHANGE_APPR_O4/zui_arena_change_appr_o4.srvb.json
W1  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Data%20Definitions/ZC_CHANGEAPPROVAL_A2X/zc_changeapproval_a2x.ddls.acds
W2  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Access%20Controls/ZC_CHANGEAPPROVAL_A2X/zc_changeapproval_a2x.dcls.acds
W3  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Behavior%20Definitions/ZC_CHANGEAPPROVAL_A2X/zc_changeapproval_a2x.bdef.abdl
W4  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Business%20Services/Service%20Definitions/ZAPI_ARENA_CHANGE_APPROVAL/zapi_arena_change_approval.srvd.acds
W5  abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Business%20Services/Service%20Bindings/ZAPI_ARENA_CHANGE_APPR_A2X/zapi_arena_change_appr_a2x.srvb.json

App contract check (source vs app/webapp/localService/mainService/metadata.xml, 2026-09-16)

Settled by the live $metadata (2026-09-16). The table below is the pre-activation comparison, kept as the record. The live capture docs/v2/zui_arena_change_appr_o4.metadata.xml (live 2026-09-16; read for this revision) settles every open row:

  • Namespace com.sap.gateway.srvd.zui_arena_change_approval.v0001. Entity type ChangeApprovalType, not ChangeApproval_Type. Entity set ChangeApproval.
  • ID Edm.Guid. StatusText Edm.String MaxLength 29. StatusCriticality Edm.Byte. IsApprovable/IsRetriable Edm.Boolean. RequestedOn/DecidedOn Edm.DateTimeOffset Precision 7. SapPreview Edm.String without MaxLength.
  • reject parameter RejectReason Edm.String Nullable="false" MaxLength 255, the same as the app.
  • Action enablement Core.OperationAvailable Path="_it/__OperationControl/<action>" for approve, reject and retrySync.
  • Insertable, Updatable and Deletable are all false.

The app was reconciled to this metadata on 2026-09-16, including backend-owned action enablement (CHANGELOG). Rows below marked UNVERIFIED, "unknown until live" or "intended difference" are resolved by this list.

All 17 app properties exist in ZC_CHANGEAPPROVAL with the same names and case. The three actions approve/reject/retrySync are in ZC_CHANGEAPPROVAL (projection BDEF), and ZUI_ARENA_CHANGE_APPROVAL exposes exactly ZC_CHANGEAPPROVAL as ChangeApproval. expose … as sets the entity set name and <alias>_Type [source: abap-docs /abap-fiori-showcase/06_object_page_content, verified 2026-09-15] (live: <alias>Type, see above). The source is not changed for the open items below. Decisions sit with the coordinator and are confirmed at U15 / V-2.

Item App mock Source Status
Service URL / schema namespace manifest.json dataSource /sap/opu/odata4/sap/<UI binding, 28-character long form>/srvd/sap/zui_arena_change_approval/0001/; namespace com.sap.gateway.srvd.<same long form>.v0001 binding ZUI_ARENA_CHANGE_APPR_O4 (D-1): intended /sap/opu/odata4/sap/zui_arena_change_appr_o4/srvd/sap/zui_arena_change_approval/0001/ intended difference; the app's dataSource URL, mock namespace and annotation targets are reconciled at V-2 from the live $metadata (separate Fiori brief)
Entity set / entity type / key ChangeApproval / ChangeApproval_Type / ID expose ZC_CHANGEAPPROVAL as ChangeApproval match
String lengths (ItemNumber 18, ItemName 40, ChangeType 15, Status 10, ArenaEcoId 20, RequestedBy/DecidedBy 12, SapChangeNumber 12, ErrorMessage/RejectReason 255) as listed same CHAR lengths in ZCHANGEAPPROVAL match
SapPreview Edm.String, no MaxLength abap.string(0) (RAP-7) match expected
StatusText absent CASE result, CHAR(29) by the max-type rule [source: abap-docs /abap-docs-cloud/ABENCDS_CASE_EXPRESSION_V2, verified 2026-09-16]; RAP-3 text element extra; keep
LocalLastChangedAt absent etag field for use etag extra; keep
StatusCriticality Edm.Byte integer literals typed INT1..INT8 by value [source: abap-docs /abap-docs-cloud/ABENCDS_UNTYPED_LITERAL_V2, verified 2026-09-16] INT1 → Edm.Byte UNVERIFIED
IsApprovable, IsRetriable Edm.Boolean cast(… as abap_boolean) ABAP_BOOLEAN → Edm.Boolean UNVERIFIED
RequestedOn, DecidedOn Edm.DateTimeOffset Precision 7 abap.utclong UTCLONG mapping UNVERIFIED
ID Edm.Guid, Core.Computed sysuuid_x16, readonly, numbering : managed expected, UNVERIFIED
reject parameter RejectReason Nullable="false", MaxLength 255 ZD_CHANGEAPPROVAL_REJECTP CHAR(255), not declared mandatory; the handler rejects an empty reason differs in metadata, behavior meets RAP-2
Action enablement Core.OperationAvailable Path="IsApprovable"/"IsRetriable" (mock only) RAP generates it from ( features : instance ) path form unknown until live
Insert/Update/Delete restrictions all false UI projection BDEF exposes no create/update/delete expected

Design decisions baked into the files (falsifiable, dated 2026-09-15 unless noted)

  • State machine (PRD ARN-002; retrySync target decided 2026-09-16):

    Action From To Caller
    create (determination setInitialStatus) none PENDING worker (A2X)
    approve PENDING APPROVED business user (UI)
    reject(RejectReason) PENDING REJECTED (terminal) business user (UI)
    markExecuting APPROVED EXECUTING worker (A2X)
    markSynced(SapChangeNumber) EXECUTING SYNCED (terminal) worker (A2X)
    markFailed(ErrorMessage) EXECUTING FAILED worker (A2X)
    retrySync FAILED APPROVED (clears ErrorMessage, keeps DecidedBy/DecidedOn) business user (UI)

    Only markExecuting writes EXECUTING. A retried record goes back through markExecuting, so the worker re-claims it the same way as a first approval. Feature control is unchanged: retrySync is enabled only for FAILED. Each action re-checks the status in the handler as well.

  • RAP action implementation contract (2026-09-16). Every action handler returns failed rows with %fail-cause (not_found or unspecific; locked is mapped to unspecific) and %op-%action-<name>. Reported messages carry %op-%action-<name>. Failures and messages of the internal UPDATE are merged into failed/reported, and result holds only keys that did not fail [source: sap-docs sap-help loio de6569d4b92e40a0911c926170140beb (Action contract), 1040b81372d44ed38b07a409fa0e1769 (General contract), abaprap_impl_rules (allowed fail causes), verified 2026-09-16]. Under strict(2), contract violations are runtime errors [source: abap-docs /abap-docs-cloud/ABENBDL_STRICT_2, verified 2026-09-16].

  • Semantic key enforced on create (2026-09-16). validation checkDuplicate on save { create; } fails a create when another record with the same ItemNumber + ChangeType + ArenaEcoId exists and is not REJECTED, or when the same request contains that key twice. Validation syntax, handler signature and effect (the whole transactional buffer is rejected) [source: abap-docs /abap-docs-cloud/ABENBDL_VALIDATIONS, ABAPHANDLER_METH_VALIDATE, verified 2026-09-16].

    • Fail cause: validations may only use cause-unspecific.
    • Messages are state messages with %state_area and %element.
    • Persisted rows are read from ZR_CHANGEAPPROVAL with OPTIONS PRIVILEGED ACCESS, because a handler SELECT on an access-controlled view without it violates the RAP BO contract [source: sap-docs sap-help abaprap_impl_rules; abap-docs /abap-docs-cloud/ABAPSELECT_PRIVILEGED_ACCESS, ABAPDERIVED_TYPES_STATE_AREA, verified 2026-09-16].
    • A validation is not something a projection lists [source: abap-docs /abap-docs-cloud/ABENBDL_USE_PROJECTION, verified 2026-09-16], so both projections are unchanged.
  • use etag in the entity header (2026-09-16). In both projection BDEFs use etag sits between define behavior for … alias ChangeApproval and {, without a semicolon. It is an entity behavior characteristic, not a body statement [source: abap-docs /abap-docs-cloud/ABENBDL_CHARACTER_PROJECTION, ABENBDL_DEFINE_BEH_PROJECTION, verified 2026-09-16].

  • Two projections, two service definitions. The UI projection ZC_CHANGEAPPROVAL exposes only approve/reject/retrySync on ZUI_ARENA_CHANGE_APPROVAL. The worker's ZC_CHANGEAPPROVAL_A2X exposes create + markExecuting/markSynced/markFailed on ZAPI_ARENA_CHANGE_APPROVAL. A projection BDEF exposes exactly what it lists, with no automatic inheritance [source: abap-docs /abap-docs-cloud/ABENBDL_USE_PROJECTION]. PRD RAP-5's wording (two bindings on one definition) is superseded by this design and is a governance item. (Closed: PRD RAP-5 was amended to this design on 2026-09-16; PRD read 2026-09-16.)

  • No projection behavior pool (2026-09-16: never created). A projection BDEF needs one only for new actions/functions [source: abap-docs /abap-docs-cloud/ABENBDL_BDEF_PROJECTION_HEADER].

  • authorization master ( none ): ADR-002 makes the IAM app / business catalog the only access control, and DCL governs reads [source: abap-docs /abap-docs-cloud/ABENBDL_AUTHORIZATION]. Switch to ( global ) plus a FOR GLOBAL AUTHORIZATION handler when a custom authorization object exists. Not final: ( none ) versus global authorization is open question PRD OQ-8, to be decided before business roles are assigned.

  • Derived fields are computed, not persisted. StatusText, StatusCriticality, IsApprovable and IsRetriable are CASE expressions in ZR_CHANGEAPPROVAL, because a transactional query projection cannot hold expressions [source: abap-docs /abap-docs-cloud/ABENCDS_DEFINE_VIEW_AS_PROJECTION]. They are field ( readonly ) and absent from the mapping (see U6).

  • Action parameters are abstract entities (ZD_*, one element each), because action input must be an abstract entity or DDIC type [source: abap-docs /abap-docs-cloud/ABENBDL_ACTION_INPUT_PARAM].

  • internal update keeps update off every OData surface. Actions and the determination still update fields IN LOCAL MODE [source: abap-docs /abap-docs-cloud/ABENBDL_INTERNAL].

  • RequestedBy holds the technical user of the creator (the worker's communication user in the A2X flow). Change it to mandatory : create if the Arena requester should be shown.

  • No SAP object type (2026-09-16), see the inventory section.

  • Released objects used (all level A, public_cloud): SYSUUID_X16, ABP_CREATION_USER, ABP_CREATION_TSTMPL, ABP_LASTCHANGE_USER, ABP_LASTCHANGE_TSTMPL, ABP_LOCINST_LASTCHANGE_TSTMPL, ABAP_BOOLEAN, CL_ABAP_BEHAVIOR_HANDLER, CL_ABAP_CONTEXT_INFO, IF_ABAP_BEHV, IF_ABAP_BEHV_MESSAGE [source: sap-released-objects sap_check_clean_core_compliance, verified 2026-09-16].

Landmines (live-learned, dated)

  • [2026-09-15] create_object for SRVD needs sourceType ("S" worked; omitting it fails with "serviceDefinitionInfo.sourceType is null"). BDEF/SRVB creation validates the referenced DDLS/SRVD's active version, so source-less objects block dependent creations.
  • [2026-09-15, superseded 2026-09-16] Activation URIs recorded on 2026-09-15 came from generator objects: BDEF .bdef.json and TABL .tabl.json (both generator-era). They are wrong for objects created with create_object; see the per-type entry below.
  • [2026-09-16] Per-type file extensions: use the filePath returned by create_object. Returned and proven by activation: TABL .tabl.ddic (U1), DDLS .ddls.acds, DCLS .dcls.acds, DDLX .ddlx.acds, BDEF .bdef.abdl (U6, U9), CLAS .clas.abap (global class only; no Local Types path is returned), SRVD .srvd.acds (U13), SRVB .srvb.json (U14) [source: adt-mcp abap_creation-create_object / abap_activate_objects on 0M7DEJI, verified 2026-09-16].
  • [2026-09-16] A .json file in an object folder of the VS Code ADT workspace is metadata only (zchangeapproval.tabl.json: formatVersion, description, originalLanguage, abapLanguageVersion: cloudDevelopment). Never paste source into it. The table source goes into .tabl.ddic (live observation 2026-09-16). The binding's .srvb.json is the exception by type: it is the returned filePath, nothing is pasted into it, and activation and publish go through it (U14, U15).
  • [2026-09-16] Service definition sources must carry no comments. A leading /* … */ header made U13's activation fail with "Comments are not supported and will be deleted on save" (Ln 1), and the same definition without it activated (live 2026-09-16). The DCLS, DDLX and BDEF headers did not block. CDS SDL follows the general CDS syntax rules, which allow comments [source: abap-docs /abap-docs-cloud/ABENCDS_F1_SDL_SYNTAX, ABENCDS_GENERAL_SYNTAX_RULES, verified 2026-09-16], so this is the tooling, not the language. Both SRVD files in this folder are comment-free; keep them so.
  • [2026-09-16] abap_activate_objects output is thin. Success returns only "Activation successful.", with no warnings. Failure lists messages with line and column but no severity, so read severity in the editor [source: adt-mcp abap_activate_objects on 0M7DEJI, verified 2026-09-16].
  • [2026-09-16] Publishing a binding in ADT for VS Code is a code lens. Open the binding's .srvb.json source and choose the Publish code lens; Unpublish and Preview… work the same way [source: sap-docs sap-help loio dd6f5de63e7245a7abe7e39389841596 "ABAP RAP Tools", verified 2026-09-16]. The extension contributes no publish command, the SAP ADT MCP has no publish tool, and the only visible feedback is " published locally". Verify with fetch_services (isPublished: true) (KNOWLEDGE 2026-09-16; U14 published 2026-09-16 04:26).
  • [2026-09-16] UI host vs -api host. fetch_service_information reports the service URL on my431353-api.s4hana.cloud.sap with sap-client=080 [source: adt-mcp abap_business_services-fetch_service_information on 0M7DEJI, verified 2026-09-16]. A business user calling that host from the browser is refused as "Forbidden / blocked by UCON". The same path on my431353.s4hana.cloud.sap returns $metadata (live 2026-09-16; KNOWLEDGE 2026-09-16). The UI service and the Fiori app use the UI host. The -api host is the communication-user entry point, so the worker's Web API (W5) is reached there only through a custom communication scenario (PRD V-2), never through the UI service.
  • [2026-09-15] The ADT MCP has no delete tool and no package tool. A wrong name is permanent from the agent side, and a missing package must be created in ADT.
  • [2026-09-15] ATC via MCP rejects RONT/NONT ("No valid data model exists for object type RONT/ROT"). Not relevant here because no SAP object type is created.
  • [2026-09-16] A missing package shows up read-only as "Package '' does not exist" from abap_creation-run_validation [source: adt-mcp on 0M7DEJI, verified 2026-09-16].
  • [2026-09-16] Service binding name limit: SAP Help says 26 in every version checked, while the ADT MCP validation accepts 30 (undocumented). The 26 limit is used here (D-1, resolved). U14 (24 characters) published on 2026-09-16.
  • [2026-09-16] The V4 URL's second segment is the binding's service alias, renamable only while unpublished (U14). For U14 it was verified after activation with fetch_services, before publishing; opening the binding before activation is not needed. U14 is now published, so its alias is fixed.