# RAP handover — Arena change-approval BO (stage 1, 2026-09-15) Target: development tenant `my431353` (ADT destination `0M7DEJI`), package `ZARENA_PLM` (sub-package of `ZLOCAL`, no transport). The ADT MCP Server can create objects and activate them but cannot write source (PRD V-4), so every file in this folder is a **ready-to-paste source** for the VS Code ADT editor. Each file header names the target object, its `abap:` URI and says "replace entire content". Every SAP behavioral claim in these files carries a `[source: … , verified 2026-09-15]` tag; the sources are `abap-docs` (ABAP Cloud keyword docs + SAP samples), `sap-docs` (SAP Help) and `sap-released-objects` (release states). ## What exists in the tenant right now Generated by `x-ui-service` (all **active**, ATC 0 findings on 12 objects, 2026-09-15): | Object | Type | Notes | |---|---|---| | `ZZCHNGPPROVAL000` | TABL | persistent table (generator naming) | | `ZZR_CHANGEAPPROVAL000` | DDLS / BDEF / DCLS | root view entity, managed BDEF, access control | | `ZZBP_R_CHANGEAPPROVAL000` | CLAS | behavior pool of the base BDEF | | `ZZC_CHANGEAPPROVAL000` | DDLS / BDEF / DDLX / DCLS | UI projection view, projection BDEF, metadata extension, access control | | `ZZBP_C_CHANGEAPPROVAL000` | CLAS | projection behavior pool — **delete it** (step 9) | | `ZZUI_ARENA_CHANGE_APPRVL000_O4` | SRVD + SRVB | service definition and OData V4 **UI** binding (same name), **unpublished** | | `ZZARENA_CHANGE_APPROVAL000` | RONT + NONT | SAP object type / node type | Created empty via `create_object` (exist, **no source, inactive**): | Object | Type | Purpose | |---|---|---| | `ZD_CHANGEAPPROVAL_REJECTP` | DDLS | abstract entity — `reject` parameter (`RejectReason`) | | `ZD_CHANGEAPPROVAL_SYNCEDP` | DDLS | abstract entity — `markSynced` parameter (`SapChangeNumber`) | | `ZD_CHANGEAPPROVAL_FAILEDP` | DDLS | abstract entity — `markFailed` parameter (`ErrorMessage`) | | `ZC_CHANGEAPPROVAL_A2X` | DDLS + DCLS | A2X projection view (worker) and its access control | | `ZAPI_ARENA_CHANGE_APPROVAL` | SRVD | Web API service definition (worker) | Not yet creatable (the MCP validation refuses until the referenced objects are active): | Object | Type | Blocker seen 2026-09-15 | |---|---|---| | `ZC_CHANGEAPPROVAL_A2X` | BDEF (projection) | "The referenced STOB object ZC_CHANGEAPPROVAL_A2X does not exist" | | `ZAPI_ARENA_CHANGE_APPROVAL_A2X` | SRVB (OData V4 - Web API) | "An active version of the Service Definition ZAPI_ARENA_CHANGE_APPROVAL does not exist" | ## Paste-and-activate sequence Open each object in the VS Code ADT editor (or ADT Eclipse), replace the whole source with the file content, save, activate. Activation order matters — dependencies are top-down. 1. `zzchngpproval000.tabl.asddls` → table `ZZCHNGPPROVAL000`. (File name uses the abap-file-formats extension by analogy with `.ddls.asddls`; the tenant object is the same regardless.) 2. `zd_changeapproval_rejectp.ddls.asddls`, `zd_changeapproval_syncedp.ddls.asddls`, `zd_changeapproval_failedp.ddls.asddls` → the three abstract entities. 3. `zzr_changeapproval000.ddls.asddls` → root view entity. 4. `zzr_changeapproval000.bdef.asbdef` → base BDEF. Watch for a message about the unmapped elements `StatusText`, `StatusCriticality`, `IsApprovable`, `IsRetriable` (CDS-calculated, deliberately not in the mapping). A warning is acceptable; an **error** means the fallback in the file header applies. 5. `zzbp_r_changeapproval000.clas.abap` (global class) and `zzbp_r_changeapproval000.clas.locals_imp.abap` (Local Types tab) → behavior pool. 6. `zzc_changeapproval000.ddls.asddls` and `zc_changeapproval_a2x.ddls.asddls` → both projection views. 7. `zzc_changeapproval000.bdef.asbdef` → UI projection BDEF. 8. Create the A2X projection BDEF (now possible): ADT *New Behavior Definition* on `ZC_CHANGEAPPROVAL_A2X`, implementation type *Projection* — or via MCP: `abap_creation-run_validation` + `create_object` with objectType `BDEF/BDO` and `{"behaviorDefinitionType":"definition","packageName":"ZARENA_PLM","rootEntity":"ZC_CHANGEAPPROVAL_A2X","name":"ZC_CHANGEAPPROVAL_A2X","description":"Arena change approval: A2X projection behavior","implementationType":"Projection"}`, transport `""`. Then paste `zc_changeapproval_a2x.bdef.asbdef`, activate. 9. Delete the generated class `ZZBP_C_CHANGEAPPROVAL000` (no longer referenced by the projection BDEF; a projection needs a behavior pool only for new actions/functions [source: abap-docs /abap-docs-cloud/ABENBDL_BDEF_PROJECTION_HEADER, verified 2026-09-15]). 10. `zzr_changeapproval000.dcls.asdcls`, then `zzc_changeapproval000.dcls.asdcls` and `zc_changeapproval_a2x.dcls.asdcls` → access controls. 11. `zzc_changeapproval000.ddlx.asddlx` → metadata extension. 12. `zzui_arena_change_apprvl000_o4.srvd.srvdsrv` and `zapi_arena_change_approval.srvd.srvdsrv` → service definitions. 13. Create the Web API binding (now possible): ADT *New Service Binding* on `ZAPI_ARENA_CHANGE_APPROVAL`, binding type *OData V4 - Web API*, name `ZAPI_ARENA_CHANGE_APPROVAL_A2X` — or via MCP `create_object` with objectType `SRVB/SVB` and `{"packageName":"ZARENA_PLM","name":"ZAPI_ARENA_CHANGE_APPROVAL_A2X","description":"Arena change approval: OData V4 Web API binding (worker)","bindingType":"OData V4 - Web API","serviceDefinition":"ZAPI_ARENA_CHANGE_APPROVAL"}`. Activate. **Do not publish** either binding (publishing is a later brief, together with the IAM app / communication scenario). ## Activation URIs for `abap_activate_objects` (after pasting) Pattern learned live 2026-09-15: `abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM///.` with these folders/extensions (all verified by a successful activation): | Type | Folder | Extension | |---|---|---| | TABL | `Dictionary/Database%20Tables` | `.tabl.json` | | DDLS | `Core%20Data%20Services/Data%20Definitions` | `.ddls.acds` | | BDEF | `Core%20Data%20Services/Behavior%20Definitions` | `.bdef.json` (`.bdef.acds`, `.bdef.asbdef`, `.bdef.abap` all fail with "array element 0 is null") | | DDLX | `Core%20Data%20Services/Metadata%20Extensions` | `.ddlx.acds` | | DCLS | `Core%20Data%20Services/Access%20Controls` | `.dcls.acds` | | CLAS | `Source%20Code%20Library/Classes` | `.clas.abap` | | SRVD | `Business%20Services/Service%20Definitions` | `.srvd.acds` | | SRVB | `Business%20Services/Service%20Bindings` | `.srvb.json` | | RONT | `Business%20Services/SAP%20Object%20Types` | `.ront.json` | | NONT | `Business%20Services/SAP%20Object%20Node%20Types` | `.nont.json` | In sequence order (`B` = `abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM`): ``` B/Dictionary/Database%20Tables/ZZCHNGPPROVAL000/zzchngpproval000.tabl.json B/Core%20Data%20Services/Data%20Definitions/ZD_CHANGEAPPROVAL_REJECTP/zd_changeapproval_rejectp.ddls.acds B/Core%20Data%20Services/Data%20Definitions/ZD_CHANGEAPPROVAL_SYNCEDP/zd_changeapproval_syncedp.ddls.acds B/Core%20Data%20Services/Data%20Definitions/ZD_CHANGEAPPROVAL_FAILEDP/zd_changeapproval_failedp.ddls.acds B/Core%20Data%20Services/Data%20Definitions/ZZR_CHANGEAPPROVAL000/zzr_changeapproval000.ddls.acds B/Core%20Data%20Services/Behavior%20Definitions/ZZR_CHANGEAPPROVAL000/zzr_changeapproval000.bdef.json B/Source%20Code%20Library/Classes/ZZBP_R_CHANGEAPPROVAL000/zzbp_r_changeapproval000.clas.abap B/Core%20Data%20Services/Data%20Definitions/ZZC_CHANGEAPPROVAL000/zzc_changeapproval000.ddls.acds B/Core%20Data%20Services/Data%20Definitions/ZC_CHANGEAPPROVAL_A2X/zc_changeapproval_a2x.ddls.acds B/Core%20Data%20Services/Behavior%20Definitions/ZZC_CHANGEAPPROVAL000/zzc_changeapproval000.bdef.json B/Core%20Data%20Services/Behavior%20Definitions/ZC_CHANGEAPPROVAL_A2X/zc_changeapproval_a2x.bdef.json B/Core%20Data%20Services/Access%20Controls/ZZR_CHANGEAPPROVAL000/zzr_changeapproval000.dcls.acds B/Core%20Data%20Services/Access%20Controls/ZZC_CHANGEAPPROVAL000/zzc_changeapproval000.dcls.acds B/Core%20Data%20Services/Access%20Controls/ZC_CHANGEAPPROVAL_A2X/zc_changeapproval_a2x.dcls.acds B/Core%20Data%20Services/Metadata%20Extensions/ZZC_CHANGEAPPROVAL000/zzc_changeapproval000.ddlx.acds B/Business%20Services/Service%20Definitions/ZZUI_ARENA_CHANGE_APPRVL000_O4/zzui_arena_change_apprvl000_o4.srvd.acds B/Business%20Services/Service%20Definitions/ZAPI_ARENA_CHANGE_APPROVAL/zapi_arena_change_approval.srvd.acds B/Business%20Services/Service%20Bindings/ZZUI_ARENA_CHANGE_APPRVL000_O4/zzui_arena_change_apprvl000_o4.srvb.json B/Business%20Services/Service%20Bindings/ZAPI_ARENA_CHANGE_APPROVAL_A2X/zapi_arena_change_approval_a2x.srvb.json ``` Then re-run ATC on the package objects (`abap_atc_run`; omit RONT/NONT — the ATC API answers "No valid data model exists for object type RONT/ROT") and `abap_business_services-fetch_services` on both bindings. ## Design decisions baked into the files (falsifiable, dated 2026-09-15) - **Two projections, two service definitions.** The brief asked for both bindings on the generated service definition *and* for the UI to expose only approve/reject/retrySync while the worker gets create + mark*. A service definition exposes one projection, and a projection BDEF exposes exactly what it lists (no automatic inheritance [source: abap-docs /abap-docs-cloud/ABENBDL_USE_PROJECTION]). Both requirements cannot hold on one definition, so the A2X path got its own projection view/BDEF/definition and the Web API binding sits on `ZAPI_ARENA_CHANGE_APPROVAL`. The RAP-2 "read-only from the UI" requirement wins over the structural wording. - **`authorization master ( none )`** instead of the generator's `( global )`: ADR-002 makes the IAM app / business catalog the only access control and DCL governs reads; `( none )` is the documented way to declare "no RAP authorization checks" [source: abap-docs /abap-docs-cloud/ABENBDL_AUTHORIZATION]. Flip to `( global )` plus a `FOR GLOBAL AUTHORIZATION` handler when a custom authorization object exists. - **Derived fields are computed, not persisted.** `StatusText`, `StatusCriticality`, `IsApprovable`, `IsRetriable` are CASE expressions in the root view; 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 step 4. - **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]. `markSynced` and `markFailed` therefore take `SapChangeNumber` / `ErrorMessage` as parameters — the only way an action can "set" them from the worker. - **`internal update`** keeps `update` out of every OData surface while the actions and the determination still update fields `IN LOCAL MODE` [source: abap-docs /abap-docs-cloud/ABENBDL_INTERNAL]. - **RequestedBy** is the technical user of the creator (the worker's communication user in the A2X flow). Change to `mandatory : create` if the Arena requester should be shown. ## Landmines learned live (KNOWLEDGE.md candidates) - [2026-09-15] `x-ui-service` generator: every field needs `semanticType` (e.g. `custom`) or validation fails with "Builtin type of field X is invalid"; semantic-key fields pass without it. The generator prepends its own `Z` to the `prefix` (`Z` → `ZZ…`) and appends `000` to every artifact name even with `suffix: ""`; service definition and UI binding get the same name (`ZZUI_ARENA_CHANGE_APPRVL000_O4`). There is no delete tool in the ADT MCP, so a naming mistake is permanent from the agent side. - [2026-09-15] `create_object` for SRVD needs `sourceType` (`"S"` worked; omitted → "serviceDefinitionInfo.sourceType is null"). BDEF/SRVB creation validates the referenced DDLS/SRVD **active** version, so source-less objects block dependent creations. - [2026-09-15] Activation URIs: see table above; BDEF is `.bdef.json`, table `.tabl.json`, SAP object types live under `Business Services`. - [2026-09-15] The MCP session id from `get_schema` `referenceContent` is single-use in practice — fetch a fresh one before each `generate_objects` attempt.