Working-tree state as of 2026-09-29, uncommitted since the initial "upload current sources" commit: - docs/handover/rap/: renamed the 11 generator-suffixed sources (zz*000) to the clean object names built on the tenant, plus the A2X leg and parameter-entity edits. - app/: manifest, annotations, i18n, mock data and local/mock ui5 configs updated to the live service shape. - PRD.md, CHANGELOG.md, KNOWLEDGE.md: build record through 2026-09-19, including the rejected reentrance-ticket path. - tools/adt-reentrance-login/: retained login helper (new). - docs/v2/zui_arena_change_appr_o4.metadata.xml: captured live $metadata (new). - Dropped a stray 0.3GB-class Eclipse installer that the initial commit had tracked under a URL-mangled filename, and the machine-specific 0M7DEJI.code-workspace. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
633 lines
52 KiB
Markdown
633 lines
52 KiB
Markdown
# RAP handover: Arena change-approval BO, built from an empty package (rev. 2026-09-16, corrected after the UI leg went live)
|
||
|
||
Target: 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 "<binding> 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 "<binding> 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.**
|
||
|
||
4. 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`.
|
||
5. Paste W3 into that `.bdef.abdl` file and save.
|
||
6. Activate W3, then W4.
|
||
|
||
**Binding: W5 created and activated, not published.**
|
||
|
||
7. **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].
|
||
8. Create W5 `ZAPI_ARENA_CHANGE_APPR_A2X` (needs W4 active). Activate it through its returned
|
||
`filePath` (`.srvb.json` expected, as U14).
|
||
9. 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 "<binding> 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 '<name>' 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.
|