Files
arena-plm-fiori/PRD.md
T
alexzandClaude Opus 5 468729eb4e Sync current sources: clean RAP handover names, app rebind, tooling
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>
2026-09-29 10:22:52 -07:00

138 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PRD — arena-plm (standalone rebuild)
## Vision & scope
I am rebuilding the Arena PLM → SAP S/4HANA integration as a **proper SAP
application that lives in the tenant**. The predecessor (Express.js,
`~/projects/sap-apps/arena-plm`) works as a demo but fails the test that
matters: a business user inside S/4HANA cannot find it — not in the Fiori
launchpad, not in the Custom CDS Views app — because everything was built
side-by-side behind standalone URLs with ad-hoc access control.
The acceptance test I hold this rebuild to: **a business user finds the
application in the S/4HANA Fiori launchpad, finds its data in the Custom CDS
Views app, and access is governed by business roles** — with the side-by-side
footprint reduced to the one thing that cannot run in the tenant: Arena
connectivity.
In scope: material, BOM, change-master, and document sync from Arena to
S/4HANA, gated by a human approval workflow. Out of scope: every other package
of the old estate — one package at a time.
## Target architecture (ADR-002, 2026-09-04)
```
Arena PLM ──webhook + delta poll──▶ Connectivity worker (BTP CF, hardened TS)
│ no UI, no user URLs; technical user
reads approved / │ writes staged changes
executes sync ▼ ▼ via approval BO service binding
┌─ SAP S/4HANA Cloud Public (my429480) ─────────────────────────────────────┐
│ Z RAP BO "Arena Change Approval" ← staging + state machine + audit │
│ Fiori Elements List Report / Object Page ← in the tenant LAUNCHPAD │
│ IAM app → business catalog → business roles ← the only access control │
│ Custom CDS views over the BO (join I_Product, …) ← Custom CDS Views app │
│ Released OData APIs (Product/BOM/ChangeMaster/Attachment) ← sync targets │
└───────────────────────────────────────────────────────────────────────────┘
```
**Build state (2026-09-14):** the Fiori Elements UI layer is scaffolded as
`com.minicircuits.arenaplm` (List Report / Object Page, TS) in the structural `app/` subfolder
(sibling to `worker/`), running on a **mock** OData V4 service — an interim, generator-iterable
stand-in. The real on-stack RAP BO + service binding (ARN-002, V-2) and
launchpad deployment (ARN-007) remain gated on developer extensibility (V-1).
The predecessor `arena-plm` on CF is verified live (`/api/health` 200) and is
the base of record for the domain/field shape until the RAP service exists.
## Systems & boundaries
| System | Role | Boundary |
|---|---|---|
| SAP S/4HANA Cloud Public (`my429480`) | **Application host** (RAP BO, Fiori app, CDS views) and sync target | Developer extensibility (ABAP Cloud via ADT); released APIs only |
| Arena PLM (`api.arenasolutions.com/v1`) | Source of items, BOMs, changes, files | REST; webhook + delta poll, handled by the worker |
| Connectivity worker (BTP CF) | Arena connectivity + initial sync executor | Machine-to-machine only; technical user via communication arrangement |
## Interface contracts
Carried from the predecessor, in live use (2026-09-04); re-verify on first POC
touch. The worker keeps calling these on approval, so every KNOWLEDGE.md
tombstone remains valid.
| API | OData | Path | Notes |
|---|---|---|---|
| Product | V4 | `/sap/opu/odata4/sap/api_product/srvd_a2x/sap/product/0002` | deep insert for plant extensions |
| Product (plant fix) | V2 | `/sap/opu/odata/sap/API_PRODUCT_SRV` | `AvailabilityCheckType` is V2-only |
| BOM (write) | V2 | `/sap/opu/odata/sap/API_BILL_OF_MATERIAL_SRV;v=0002` | header first, then sequential items |
| BOM (read) | V2 | `/sap/opu/odata/sap/API_BILL_OF_MATERIAL_SRV` | v1 only; v2 rejects guid keys |
| Change Master | V2 | `/sap/opu/odata/sap/API_CHANGEMASTER;v=0002` | object-type assignments, material linking |
| Attachment | V2 | `/sap/opu/odata/sap/API_CV_ATTACHMENT_SRV` | function import for URL creation |
| Approval BO — UI binding (Fiori app) | V4 UI | `/sap/opu/odata4/sap/zui_arena_change_appr_o4/srvd/sap/zui_arena_change_approval/0001/` (binding `ZUI_ARENA_CHANGE_APPR_O4` on definition `ZUI_ARENA_CHANGE_APPROVAL`; designed 2026-09-16, not yet created) | entity set `ChangeApproval` / type `ChangeApproval_Type`, actions `approve`, `reject(RejectReason)`, `retrySync`; namespace, EDM types and the URL's service alias segment are confirmed from live `$metadata` after publish (V-2). The Fiori app still points at `zui_arena_change_approval_o4`, and V-2 reconciliation moves it |
| Approval BO — Web API (A2X) binding (worker) | V4 Web API | binding `ZAPI_ARENA_CHANGE_APPR_A2X` on definition `ZAPI_ARENA_CHANGE_APPROVAL` (designed 2026-09-16; created after the A2X projection is active) | custom communication scenario, technical user; namespace from live `$metadata`; exposes create + read + `markExecuting` / `markSynced(SapChangeNumber)` / `markFailed(ErrorMessage)` (RAP-6) |
| Worker inbound surface | REST (OpenAPI 3.1) | `docs/api/worker.openapi.json` | webhook intake (503 when buffer full), health (`ok`/`degraded`, session `none/active/expired/refreshing`), sync-run admin (strict request schema); contract v0.2.0 (2026-09-14 wave); auth scheme pending OQ-6 (ARN-009) |
## Requirements
Capability level — field mappings deferred to the POC per my POC-before-spec rule.
| ID | Requirement | Status |
|---|---|---|
| ARN-001 | Sync chain PRODUCT → CHANGE_MASTER → BOM → DOCUMENTS in config-driven order, executed by the worker on approval | Planned |
| ARN-002 | Approval domain as an on-stack RAP BO: staging fields, state machine PENDING → APPROVED → EXECUTING → SYNCED \| FAILED, REJECTED terminal, FAILED → retrySync → APPROVED (amended 2026-09-14: a terminal success state is required so an approved record is never executed twice; amended 2026-09-16: retry returns the record to APPROVED so the worker re-claims it through `markExecuting`, the only way into EXECUTING. A retry that jumped straight to EXECUTING was never picked up, or it risked a second concurrent execution); duplicate staging of the same `ItemNumber`+`ChangeType`+`ArenaEcoId` is refused on create while a non-REJECTED record exists (2026-09-16); approve/reject/retrySync as RAP actions with instance feature control; audit fields (`RequestedBy`/`RequestedOn`/`DecidedBy`/`DecidedOn`); execution failure is a distinct state, never overloaded onto rejection (predecessor defect, `docs/predecessor-flow.md` §2) | Planned |
| ARN-003 | Durable persistence & audit — satisfied structurally by in-tenant RAP persistence (the predecessor lost its queue on every restart) | Planned (by design) |
| ARN-004 | Business mappings maintained in-tenant — evaluate Business Configuration maintenance objects (Custom Business Configurations app) before any file-based config | Planned |
| ARN-005 | Arena ingestion via webhook + delta poll in the connectivity worker | Planned |
| ARN-006 | Idempotent SAP writes, SAP-as-ledger (see `KNOWLEDGE.md`) — predecessor BOM/document syncs were non-idempotent; executors must check existence first | Planned |
| ARN-007 | Access exclusively via the Fiori launchpad with IAM app / business catalog / business roles; no user-facing standalone URLs | Planned |
| ARN-008 | Approval data discoverable via custom CDS views, joinable to released views (the discoverability test); look up join targets with `object_type=CDS_STOB` in `sap-released-objects` (no `DDLS` type in the public_cloud dataset, KNOWLEDGE 2026-09-14) | Planned |
| ARN-009 | API-first: every interface this package owns carries an OpenAPI 3.1 JSON contract under `docs/api/`, authored before or with the change; implementation conforms to the contract | Adopted (2026-09-10) |
| ARN-010 | The approved payload is the executed payload: the executor writes the staged data the approver saw — never re-fetch-and-recompute at execution time (the predecessor discarded the preview, making approval decorative; `docs/predecessor-flow.md` §2) | Adopted (2026-09-10) |
### RAP-track requirements harvested from the UI (2026-09-14)
Derived while binding the Fiori app; each becomes a `rap-developer` brief
once V-1 opens the development tenant.
| ID | Requirement | Source |
|---|---|---|
| RAP-1 | Behavior definition declares `approve`, `reject`, `retrySync` with `( features : instance )` and implements `get_instance_features` so the UI service emits `Core.OperationAvailable`; approve/reject only for PENDING, retrySync only for FAILED. `approve` writes no `SapChangeNumber` (execution does). The CDS emits numeric `StatusCriticality` 2/2/5/3/1/1 for PENDING/APPROVED/EXECUTING/SYNCED/REJECTED/FAILED (5 = Information is V4-only) | [source: abap-docs /abap-docs-standard/ABENBDL_ACTIONS_FC; sap-docs /abap-fiori-showcase/01_general_features#operations-and-actions, verified 2026-09-14] |
| RAP-2 | `reject` takes a mandatory `RejectReason` (char 255) parameter; `approve`/`retrySync` return `$self`; the entity is read-only from the UI (no create/update/delete). **Partly met for the POC (2026-09-16):** the handler refuses an empty reason server-side. A metadata-level mandatory marker needs a root abstract entity, an abstract BDEF with `field ( mandatory : execute )` and a `deep parameter`, and is deferred until after the UI POC [source: abap-docs /abap-fiori-showcase/01_general_features #MandatoryParameter; /abap-docs-cloud/ABENBDL_ACTION_INPUT_PARAM, verified 2026-09-16 by my review] | UI contract (annotation.xml, mock metadata) |
| RAP-3 | `Status` carries a text element (`@ObjectModel.text.element`, `@UI.textArrangement: #TEXT_ONLY`) so the UI shows text, not codes | [source: fiori-mcp-server "Text and Text Arrangement", verified 2026-09-14] |
| RAP-4 | Semantic key `ItemNumber` (`@ObjectModel.semanticKey`); `Status` and `RequestedOn` sortable/filterable | UI default variant |
| RAP-5 | (Amended 2026-09-16.) Two service definitions, one binding each. `ZUI_ARENA_CHANGE_APPROVAL` exposes the UI projection as `ChangeApproval` through the OData V4 **UI** binding `ZUI_ARENA_CHANGE_APPR_O4`. `ZAPI_ARENA_CHANGE_APPROVAL` exposes the A2X projection through the OData V4 **Web API** binding `ZAPI_ARENA_CHANGE_APPR_A2X`. Binding names are 26 characters or fewer. The binding name sets the URL's first segment; hand back the UI binding's live `$metadata` to reconcile (V-2). The single-definition wording of 2026-09-14 could not hold, because a projection BDEF exposes only what it lists | [source: sap-docs sap-help loio 5717c0a1dafc4335add0207b81c39cef, 5f45f125dfe84c20beb18f5de1512f5a, verified 2026-09-14; binding-name limit: sap-docs sap-help loio 4bad0d7280b742a68dd2d42b1441f09a, verified 2026-09-16; abap-docs /abap-docs-cloud/ABENBDL_USE_PROJECTION, verified 2026-09-15] |
| RAP-6 | Worker-callable execution-state actions on the A2X binding — `markExecuting`, `markSynced` (sets `SapChangeNumber`), `markFailed` (sets `ErrorMessage`) — with instance feature control so the UI never offers Approve on an executing record | [source: abap-docs /abap-docs-cloud/ABENBDL_ACTIONS_FC, verified 2026-09-14] |
| RAP-7 | Staged payload (`SapPreview`) is `abap.string` — CDS char elements are capped at 1333 characters and truncation would break ARN-010 | [source: abap-docs /abap-docs-cloud/ABENCDS_SELECT_LIST_ENTRY_V2, verified 2026-09-14] |
| RAP-8 | Field `DecidedBy` (not `ApprovedBy`) holds approver or rejecter; semantic key `ItemNumber, ChangeType, ArenaEcoId` | UI contract |
## Architecture decisions
- ADR-001 — toolchain-must-engage rebuild; Express predecessor reference-only. **Amended by ADR-002.**
- ADR-002 — on-stack first: RAP + Fiori Elements in the tenant; side-by-side reduced to a connectivity worker; CAP exits the architecture.
## Verification items & open questions
| ID | Item | Status |
|---|---|---|
| V-1 | Developer-extensibility access on the development tenant | **Closed 2026-09-15** — `my431353.s4hana.cloud.sap`: business user AZAW holds `ZBR_DEVELOPER` (SAP_BR_DEVELOPER template), `ZBR_ADMINISTRATOR_SW_DEV`, `ZBR_DEVELOPMENT_MANAGER_DIN` and five more (live: `sap-api users getRoles`, verified 2026-09-15). V-1b done 2026-09-15 (destination `0M7DEJI`, MCP lists it). Role correct (A4C catalogs). V-1b **closed 2026-09-15**: package `ZARENA_PLM` under `ZLOCAL`; probe class created and activated via ADT MCP |
| V-2 | Custom communication scenario can expose the approval BO's A2X service to the worker's technical user; and the Fiori app's annotation namespace, `_Type` entity-type suffix and UI-binding URL segment are reconciled from the live `$metadata` of the UI binding (decided 2026-09-14; the mock cannot verify this) | Open. **UI half in progress 2026-09-16:** live `$metadata` is captured in `docs/v2/zui_arena_change_appr_o4.metadata.xml`, and the UI host serves it to the developer user. The contract holds: all 17 property types, key, entity set, the three actions, and `RejectReason` non-nullable. Identity differs from the mock: namespace `com.sap.gateway.srvd.zui_arena_change_approval.v0001`, entity type `ChangeApprovalType`, URL segment `zui_arena_change_appr_o4`, and backend operation control via `__OperationControl`. **The app was reconciled 2026-09-16:** the dataSource targets `zui_arena_change_appr_o4`; the mock serves the live `$metadata` byte-for-byte; annotation targets use the live namespace and entity type; enablement is backend-owned; no old identity strings remain; lint, typecheck and `@ui5/linter` are clean; the mock server serves the service. Unverified until a live preview: the `DataFieldForAction` action-string form versus the backend's overload-specific `OperationAvailable` target. The A2X half (custom communication scenario, `-api` host) is still open. The service URL reported on `-api` carries `sap-client=080` |
| V-3 | On-stack Application Jobs vs worker-side polling for the Arena delta | Open — flow findings 2026-09-10: Arena's outbound-integration queue holds the cursor (`reconciled` flag) and is the clean delta mechanism; `/changes`-feed polling needs client-side date filtering (`docs/predecessor-flow.md` §1) |
| V-4 | Can a Claude Code agent outside the VS Code editor author ABAP source through the ADT MCP Server? | **Answered 2026-09-15: no.** `create_object` and the generators take structure, not source (live probe); SAP's editing MCP tool is planned for Public Edition 2702 [source: sap-docs loio 7f716223a88c40e0992777c8d9febccf, verified 2026-09-15]. Build plan: `x-ui-service` generator for the BO skeleton, source edits handed over as files for the VS Code editor until 2702 |
| OQ-5 | Long-term: move the sync executor on-stack (released ABAP APIs) vs keep it in the worker — worker initially | Open |
| OQ-6 | Webhook receiver hosting and auth for the worker on CF | Open |
| OQ-9 | Agent-side ABAP source read/write through the community `abap-adt-mcp` server (npm 2.1.0, a single maintainer, published 2026-09-16 01:04Z, SLSA provenance attested). It lists `getObjectSource`, `setObjectSource` and `activateObjects` next to 170 other tools, enforces `readOnly` / `allowedPackages` policy server-side, and signs in to Public Cloud through a one-time browser SSO. It would remove the manual paste step that SAP's ADT MCP forces (V-4). Checked 2026-09-16: a read-only smoke run with no login and no SAP call listed 173 tools and enforced a `ZARENA_PLM`-only read-only policy; nothing is registered. Adoption needs, in order: a source review of the package, because it would hold an SSO session into the tenant; a version pin; the development tenant only, never `my429480`; `allowedPackages: ["ZARENA_PLM"]`; read-only first; then a CLAUDE.md routing change | Open (2026-09-16), not blocking. I want it as the replacement for manual pasting; the read-only source review of the cached package (03:15) cleared every check it ran, observed as it ran. It stalled while collecting line citations for its report and was stopped at ~03:28, so no written report with file:line evidence exists. I accept it for the development tenant under the read-only-first configuration. Registered by hand in project scope at 03:37: stdio `npx -y abap-adt-mcp@2.1.0`, `MCP_READ_ONLY=1`, audit file on, `~/.abap-adt-mcp/systems.json` (development tenant `my431353`, client 100, SSO, `readOnly: true`, `allowedPackages: ["ZARENA_PLM"]`, mode 600). The other six project servers are intact. It connected after the restart, and its policy checked out live. **Parked 2026-09-16 03:49:** SSO needs an interactive sign-in inside the server's own Chrome, on the server's desktop (`:0`). That window is unreachable over my multi-hop SSH remote access; a DevTools relay was tried and dropped. The server stays registered but unused. It is revisited when a session at the server's desktop can complete one sign-in with "stay signed in", after which logins run unattended. The reentrance-ticket path was built and tested on 2026-09-18 (`tools/adt-reentrance-login/`) and **rejected on evidence**: the tenant ignores the ticket as both a `MYSAPSSO2` cookie and header, answering with its SAML redirect page (KNOWLEDGE 2026-09-18). Reviving OQ-9 requires capturing how ADT for VS Code exchanges the ticket. Until then, tenant work stays on SAP's ADT MCP plus editor paste. Until then, the UI leg continues with SAP's `adt-mcp` plus editor paste. The registration is run by hand, because Claude Code's permission guard refuses agent-side changes to its own MCP configuration (03:17, nothing written). The target is the development tenant, client 100, SSO login, first with `readOnly: true` + `allowedPackages: ["ZARENA_PLM"]` + `MCP_READ_ONLY=1`, then write enabled for `ZARENA_PLM` only |
| OQ-10 | Ownership of UI annotations: the backend metadata extension `ZC_CHANGEAPPROVAL` or the app's local `annotation.xml`. Today 35 of the 58 local annotations override a backend annotation with the same target, term and qualifier (layering rule [source: fiori-mcp-server "Visualizing and Managing Annotations with SAP Fiori Tools - Service Modeler", verified 2026-09-16]), so a DDLX change to those terms is invisible in the app. The local file adds i18n labels, action criticality, the `#Default` variants and the facet IDs the OPA journey relies on | Open (2026-09-16). Interim rule: a term defined locally is changed locally. I consolidate before launchpad deployment |
| OQ-8 | Per-operation authorization for the approval BO. Today it is `authorization master ( none )`: any holder of the UI app can approve, reject and retry, and any tenant ABAP code can create and mark* through EML. SAP Help calls `( none )` "not recommended in real-world scenarios". The target is `( global )` with a `FOR GLOBAL AUTHORIZATION` handler and `AUTHORITY-CHECK OBJECT` on a custom authorization object: decisions for business roles, create/mark* for the communication role. First verify that custom authorization objects can be created on `my431353` [source: abap-docs /abap-docs-cloud/ABENBDL_AUTHORIZATION, ABAPHANDLER_METH_GLOBAL_AUTH; sap-docs sap-help loio 673c05562e144702a080c574c3da2da3, verified 2026-09-16 by my review] | Open (2026-09-16): does not block the dev-tenant UI POC; must close before any business role other than the developer's gets the app (IAM brief) |
| OQ-7 | Tenant object naming and cleanup for the approval BO | **Closed 2026-09-16.** The package was deleted in ADT, contents and package itself (verified live through ADT MCP validation, 2026-09-16). I build from scratch, without the generator: table `ZCHANGEAPPROVAL`, `ZR_CHANGEAPPROVAL`, `ZBP_R_CHANGEAPPROVAL`, `ZC_CHANGEAPPROVAL`, SRVD `ZUI_ARENA_CHANGE_APPROVAL` with SRVB `ZUI_ARENA_CHANGE_APPR_O4`, and SRVD `ZAPI_ARENA_CHANGE_APPROVAL` with SRVB `ZAPI_ARENA_CHANGE_APPR_A2X`. Binding names follow SAP's 26-character limit (RAP-5). Entity set is `ChangeApproval`; the A2X projection and parameter entity names are unchanged |
## Status
| Work item | State |
|---|---|
| Package home + governance | Done (2026-09-04) |
| Developer environment | Done (2026-09-04); MCP loadout revised to ABAP/RAP set (done 2026-09-04) |
| Ground-truth enforcement kit (ADR-003 hooks) | Done (2026-09-04); hardened 2026-09-14 — Bash/MultiEdit/filesystem writes gated, grounding-only marker refresh, portable paths, fail-closed, 37 pipe-tests green |
| Specialist agent roster (5 agents, docs/agent-roster.md) | Done (2026-09-04; all 5 files YAML-verified in .claude/agents/) |
| V-1…V-3 verification POC | Planned — V-1 (ADT access on my429480) is the user-side gate for everything on-stack |
| Fiori Elements app (`app/`, mock-bound) | Done for the mock stage (2026-09-14) — gateway service shape (binding-derived identity), six-state domain, polished List Report/Object Page, launchpad inbound `ArenaChangeApproval-manage`; SAP review findings closed. Deploy gated on V-1/V-2 (live `$metadata` reconciliation) |
| RAP BO (approval domain) | In progress (2026-09-16): from-scratch build in package `ZARENA_PLM` (under `ZLOCAL`, no transport recording) under the clean names (OQ-7 closed). The handover in `docs/handover/rap/` has all pre-paste review fixes applied and was stable as of 02:45. Wave A (U1–U5: table, three parameter entities, root view) was created empty at 02:30. Its sources were pasted at 02:47, and all five activated at 02:49 with no errors, `preserving type` included. Wave B (U6 base BDEF, U10 root access control) was created empty at 02:50, its sources were pasted at 02:53, and both activated at 02:55 (BDEF through `.bdef.abdl`). Wave C (U7 behavior pool, U8 UI projection view) was pasted at ~03:00 and activated at 03:03 (U6 and U7 together, then U8), with no errors. It is not yet confirmed that the handler source sits in the class's Local Types include; until it is, activation does not prove the three flagged constructs. Wave D (U9 projection BDEF, U11 access control, U12 metadata extension, U13 UI service definition) was created empty at 03:05 and pasted at ~04:12. U9, U11 and U12 activated at 04:15. U13 activation failed, listing "Comments are not supported and will be deleted on save" (Ln 1) and "oData V4 services with no draft capability will be primarily READ-ONLY" (Ln 21, expected by design). After a comment-free re-save, U13 activated at 04:18. U14 binding `ZUI_ARENA_CHANGE_APPR_O4` (OData V4 UI) was created and activated. **The UI leg is active: all 14 objects; ATC 0 errors, 0 warnings, 43 infos.** **Published 2026-09-16 04:26** through the ADT Publish code lens: `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`, entity set `ChangeApproval` (`fetch_service_information`). The table is empty until the worker leg creates records, because the UI exposes no create. V-2 app reconciliation done. **Worker (A2X) leg ACTIVE 2026-09-16 06:37:** W1 view `ZC_CHANGEAPPROVAL_A2X`, W2 access control, W3 projection BDEF (create, markExecuting, markSynced, markFailed), W4 service definition `ZAPI_ARENA_CHANGE_APPROVAL` and W5 OData V4 Web API binding `ZAPI_ARENA_CHANGE_APPR_A2X` (unpublished, service `0001`). ATC on the 5 worker objects: 0 errors, 1 priority-3 warning (W607 on `ZC_CHANGEAPPROVAL_A2X`: `authorizationCheck: #CHECK` should be `#MANDATORY`), deferred to OQ-8. **The approval BO is complete on the development tenant (19 objects).** Next: expose W5 to the worker's communication user through a custom communication scenario (V-2 A2X half); IAM app, business catalog and role for the UI app (ARN-007); OQ-8 authorization before other business users. The table source goes into `.tabl.ddic`; `.tabl.json` holds only header metadata. (3) UI leg, 14 sources ending with binding `ZUI_ARENA_CHANGE_APPR_O4`: I create each object through the MCP, its source is pasted in the VS Code editor, and I activate it. The `markSynced`/`markFailed` parameter entities belong to this leg, because the base BDEF references them. (4) Publish the UI binding, then run V-2 reconciliation of the app against its live `$metadata`. (5) Worker (A2X) leg, 4 sources. Syntax proven only by tenant activation, still open: `OPTIONS PRIVILEGED ACCESS` in `checkDuplicate` (fallback `FROM … WITH PRIVILEGED ACCESS`), `%op-%action` on MODIFY response rows, `preserving type` on the U5 boolean casts |
| Connectivity worker | Review wave Done (2026-09-14) — TTL wiring, cursor-after-success, buffer-full = tick failure, health conformance, strict JSON-only validation, bounded buffer, graceful drain, HTTP timeout, fixed-phrase errors; 137 tests green incl. the schema-driven contract-conformance suite. Next: Arena client POC (live), executor leg gated on V-2. **Do not deploy the scaffold**: the ingest buffer has no consumer yet, so a long-running instance would answer 503 after `WEBHOOK_QUEUE_MAX_SIZE` events. Next: Arena client POC (live), executor leg gated on V-2 |
| Worker API contract (`docs/api/worker.openapi.json`) | v0.2.1 Done (2026-09-14) — health enums/`degraded`/`poller`, strict `SyncRunRequest`, webhook 503, 413/415 + `default` on every operation, reserved 502, `DOCUMENTS` token; `x-sap-stateInfo: beta`, provisional webhook schema pending Arena POC |