From 272a202152d6c4f74f482320aef5ca9331a0601d Mon Sep 17 00:00:00 2001 From: alexz Date: Tue, 29 Sep 2026 11:22:05 -0700 Subject: [PATCH] =?UTF-8?q?ADR-005:=20OQ-11=20closed=20=E2=80=94=20Integra?= =?UTF-8?q?tion=20Suite=20native=20(ADK=20adapter=20+=20iFlows=20+=20SBPA)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both options framed for OQ-11 failed the deciding criterion: whether the next person finds the thing inside the platform. A CAP service or a hardened worker on Cloud Foundry is discoverable only to whoever already knows the route to it, which is ADR-002's original objection relocated rather than answered. The integration is now Integration Suite native. Nothing on Cloud Foundry, nothing in ABAP: - Arena connectivity as a custom adapter built with the Adapter SDK — sender adapter with the webhook endpoint and delta scheduler, cluster lock for single-flight login, ADK persistency for the delta cursor, tenant user credentials for Arena secrets. - Movement as iFlows to the released Product / BOM / ChangeMaster / Attachment OData APIs. - Human approval in SAP Build Process Automation (entitled in the global account, not yet assigned). Decisive: every mechanism hand-rolled in worker/ has a first-class ADK facility, so the adapter deletes that custom infrastructure rather than merely relocating it; and the ADK's Java/Maven/OSGi toolchain is not a new cost here, because the AS/400 FetchAPI servlets are already Java and Java developers can be staffed in-house. worker/ is reclassified from deliverable to specification: its 137 tests describe the Arena session, delta-cursor and webhook behaviour the adapter must reproduce. app/ has no target service under ADR-005 and is kept as reference, unrepointed. ADR-004's "side-by-side runtime" is narrowed to mean "in Integration Suite". New verification items V-5 (can an ADK adapter hold an Arena session under cluster lock — the first build) and V-6 (where SBPA tasks surface for a business user). No SAP tenant or BTP artifact was modified. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 78 +++++++++++++++++++ PRD.md | 68 ++++++++-------- docs/adr/ADR-005-integration-suite-native.md | 81 ++++++++++++++++++++ 3 files changed, 195 insertions(+), 32 deletions(-) create mode 100644 docs/adr/ADR-005-integration-suite-native.md diff --git a/CHANGELOG.md b/CHANGELOG.md index ee15697..9ff1b13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,84 @@ Append-only decision log for this package. +## 2026-09-29 — ADR-005: OQ-11 closed. Integration Suite native — Arena ADK adapter + iFlows, approval in SAP Build Process Automation + +- What changed: I closed OQ-11 and wrote + `docs/adr/ADR-005-integration-suite-native.md`. The integration becomes + Integration Suite native: an Arena custom adapter built with the Adapter SDK + (sender adapter carrying the webhook endpoint and the delta scheduler), iFlows + for the movement to the released Product / BOM / ChangeMaster / Attachment + APIs, and human approval in SAP Build Process Automation. Nothing runs on + Cloud Foundry; nothing is written in ABAP. I rewrote the PRD's target + architecture accordingly and added V-5 and V-6. +- Why: both options I had framed for OQ-11 failed the criterion that actually + decides this. The test is not build cost, it is whether the next person finds + the thing inside the platform — and a CAP service or a hardened worker on + Cloud Foundry is discoverable only to whoever already knows the route to it, + which is ADR-002's original objection relocated rather than answered. + Two findings then chose between the native options: + - Every mechanism I hand-rolled in `worker/` has a first-class ADK facility: + cluster lock for single-flight login, ADK persistency for the delta cursor, + user credentials for Arena secrets, scheduler support, connection status, + tracing, endpoint visualization, and versioning rules [source: SAP Help, + *Adapter Development Process*, Cloud Integration, verified 2026-09-29]. The + adapter does not merely present better; it deletes the infrastructure the + worker existed to supply. + - I had recorded the ADK's Java/Maven/OSGi toolchain as the cost of this + route. It is not a cost in this estate: the AS/400 FetchAPI servlets on + `mcl2000` are already Java, and Java developers can be staffed in-house. One + language and one team span both ends, and the ADK covers the on-premise leg + directly through *Accessing On-Premise Application using Cloud Connector* — + which retires the deleted Cloud Foundry `fetchapi-bridge` pattern instead of + rebuilding it. +- Affected: PRD (target architecture, decisions, OQ-11 closed, V-5 and V-6 + added), new ADR-005, ADR-004 narrowed. `worker/` is reclassified from + deliverable to specification; `app/` has no target service under ADR-005 and + is kept as reference, not repointed. No SAP tenant or BTP artifact was + modified. +- Decision: ADR-005. I also correct something I asserted too confidently + earlier in the day: that SAP Build Process Automation tasks surface in the + Fiori launchpad. That is now V-6, unverified — what I can state is that the + service is entitled in the global account (`process-automation`, + `process-automation-service`) and therefore needs assigning, not buying. + First build is V-5: a minimal Arena sender adapter that logs in and holds the + session under cluster lock. Nothing else starts before it. + +## 2026-09-29 — Read access to the customizing tenant proven through `mc-s4hana`; the parked password is simply stale + +- What changed: nothing in the tenant — I established how to read it. Through + the BTP destination `mc-s4hana`, three read-only GETs against + `my429480` all answered 200: `API_BUSINESS_PARTNER/$metadata` (EDMX v1.0, + 65 entity sets), `A_BusinessPartner?$top=1` (BusinessPartner `1710`), and + `api_product/srvd_a2x/sap/product/0002/$metadata` (EDMX 4.0, 39 entity sets). + I used the destination service instance `sap-apps-dest` and its existing + service key `dest-anywhere-dest-key`; I created no key and no instance. +- Why: after retargeting, direct basic auth to the customizing tenant returned + 401, and I needed to know whether the tenant was refusing the user or the + stored password was wrong. +- Affected: no SAP object, no BTP artifact. Knowledge only. +- Findings: + - `mc-s4hana` authenticates as **`BasicAuthentication` with the same user, + `AZ_API_USER`**, and succeeds. So the tenant accepts that user over basic + auth: the 401 was neither a lockout nor a user problem. The password in + `_shared/.env.starter-cust-my429480.bak` is stale, and the working value is + already held by the destination. No credential reset is needed. + - The destination's own description reads "SAP S/4HANA Public Cloud - MC + Production" while its URL is the starter customizing tenant — the same + mislabel this package carried, now visible in BTP as well. I left it alone; + it is shared, and a description is not worth an unrequested change. + - `default-env.json` alone does not work with SAP Cloud SDK v4: + `@sap-cloud-sdk/connectivity` 4.6.0 resolves bindings through `@sap/xsenv`'s + `filterServices()`, which reads `process.env.VCAP_SERVICES` and never loads + the file. `require('@sap/xsenv').loadEnv()` must run ahead of the SDK + requires (or `VCAP_SERVICES` be exported). The first attempt failed with + "Could not find service binding of type 'destination'". +- Decision: I will not copy the working password out of the destination into + `.env`. The destination is the sanctioned path for this estate, so the fix is + to make the shared CLI destination-aware rather than to hold a second copy of + a credential. Until that is done, reads against the customizing tenant go + through a destination-based call, not through `sap-api`. + ## 2026-09-29 — Tooling retargeted to the starter customizing tenant; its credential is rejected - What changed: diff --git a/PRD.md b/PRD.md index 4c94f16..3307db6 100644 --- a/PRD.md +++ b/PRD.md @@ -28,43 +28,44 @@ 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-004, 2026-09-29 — supersedes ADR-002) +## Target architecture (ADR-005, 2026-09-29 — closes OQ-11; narrows ADR-004) -The starter system's **customizing** tenant `my429480` (client 100) supports -**key-user extensibility only** — no ABAP, no RAP. ABAP development requires -the starter system's **development** tenant `my431353` (client 080), which I -parked on 2026-09-29 [source: fiori-tools-samples `misc/s4hana/README` -"Tenant Types", verified 2026-09-29]. The on-stack RAP business object of -ADR-002 therefore has no home in the tenant I am now working in, and the -application moves back out to a side-by-side runtime consuming released APIs. +Integration Suite native. Nothing on Cloud Foundry, nothing in ABAP. The +customizing tenant `my429480` (client 100) supports key-user extensibility only +— no ABAP, no RAP — so the on-stack RAP business object of ADR-002 has no home +there [source: fiori-tools-samples `misc/s4hana/README`, "Tenant Types", +verified 2026-09-29]; and a custom application on Cloud Foundry fails the test +that matters, which is whether the next person finds it inside the platform. ``` -Arena PLM ──webhook + delta poll──▶ Connectivity worker (BTP CF, hardened TS) - │ built, 137 tests green, NOT deployed - ▼ - Approval store + state machine + audit - (side-by-side — host is the open call, OQ-11) - │ - Fiori Elements List Report / Object Page - (`app/` — already built, service-repointable) - │ released OData APIs, mc-s4hana -┌─ Starter system · CUSTOMIZING tenant `my429480` (client 100) ─────────────┐ -│ Product / BOM / ChangeMaster / Attachment released APIs ← sync targets │ -│ Key-user extensibility + configuration only — no ABAP, no RAP │ -│ Launchpad reachability for the app: decided with OQ-11 │ -└───────────────────────────────────────────────────────────────────────────┘ +┌─ SAP Integration Suite · Cloud Integration ───────────────────────────────┐ +│ Arena custom adapter (Adapter SDK, Java/OSGi) │ +│ · sender: webhook endpoint + delta scheduler │ +│ · cluster lock -> single-flight Arena login │ +│ · ADK persistency -> delta cursor │ +│ · user credentials -> Arena secrets from the tenant store │ +│ iFlows -> movement: material, BOM, change master, documents │ +└──────────────┬──────────────────────────────────┬─────────────────────────┘ + │ released OData APIs │ approval request + ▼ ▼ +┌─ Starter system · CUSTOMIZING tenant `my429480` ─┐ ┌─ SAP Build Process ──┐ +│ Product / BOM / ChangeMaster / Attachment APIs │ │ Automation │ +│ Key-user extensibility + configuration only │ │ human approval task │ +└──────────────────────────────────────────────────┘ │ (entitled, unassigned)│ + └──────────────────────┘ - parked 2026-09-29 ──▶ Starter system · DEVELOPMENT tenant `my431353` (080) - 19 RAP objects live in ZARENA_PLM, left in place + parked ──▶ Starter system · DEVELOPMENT tenant `my431353` (client 080) + 19 RAP objects live in ZARENA_PLM, left in place + spec ──▶ worker/ — 137 tests describe the Arena behaviour to reproduce + ref ──▶ app/ — no target service under ADR-005; kept, not repointed ``` -**Build state (2026-09-29).** What exists: the Fiori Elements UI -`com.minicircuits.arenaplm` in `app/`, built and bound to a mock OData V4 -service; the connectivity worker in `worker/`, built with 137 tests green and -never deployed (no deployment descriptor was ever written); and 19 activated -RAP objects on the parked development tenant, with their sources kept in -`docs/handover/rap/` as reference. Nothing from this package has ever been -deployed to Cloud Foundry or reached a business user. +**Build state (2026-09-29).** Nothing from this package has ever been deployed +to Cloud Foundry or reached a business user. What exists: the connectivity +worker (built, 137 tests green, never deployed, now the specification for the +adapter); the Fiori Elements app in `app/` (built, mock-bound, no longer the +UI route); and 19 activated RAP objects on the parked development tenant, with +sources kept in `docs/handover/rap/`. ## Systems & boundaries @@ -130,6 +131,7 @@ once V-1 opens the development tenant. - 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. **Superseded by ADR-004.** +- ADR-005 (2026-09-29) — **closes OQ-11**: Integration Suite native. Arena custom adapter (Adapter SDK) + iFlows for movement; human approval in SAP Build Process Automation; nothing on Cloud Foundry, nothing in ABAP. Narrows ADR-004's "side-by-side runtime" to mean "in Integration Suite". `worker/` becomes the specification, not a deliverable. - ADR-004 (2026-09-29) — I withdraw the on-stack RAP route and move the application back to a side-by-side runtime against released APIs. Two facts force it: the customizing tenant `my429480` (client 100) supports key-user extensibility only, and I am no longer willing to carry an ABAP/RAP build for this package. I park the development tenant `my431353` (client 080) with its 19 activated objects in place rather than delete them, so the route stays reversible. The replacement host — key-user extensibility in the tenant versus a CAP service side-by-side — is OQ-11; my recommendation is CAP, because the connectivity worker must be side-by-side regardless and one runtime beats two. ## Verification items & open questions @@ -146,7 +148,9 @@ once V-1 opens the development tenant. | 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 | -| OQ-11 | Where the approval store, state machine and audit live now that ADR-004 withdrew the RAP BO. Option A: key-user extensibility in the customizing tenant (custom business object + low-code UI) — stays in the tenant and in the launchpad natively, but the Arena connectivity still needs an outside worker, so the application ends up with two homes, and key-user objects are transport-bound. Option B: a CAP service side-by-side on BTP CF — one runtime with the worker, matches the archetype the rest of my estate already runs, and `app/` repoints to it cheaply because 35 of its 58 annotations are already local (OQ-10); the cost is BTP runtime and launchpad reachability becomes a federation question. | Open (2026-09-29). I recommend Option B. Decide before any further build. | +| OQ-11 | Where the approval store, state machine and audit live now that ADR-004 withdrew the RAP BO. | **Closed 2026-09-29 by ADR-005.** Neither of the options I framed survived the deciding criterion — a custom app on Cloud Foundry is discoverable only to whoever already knows the route to it, which is ADR-002's original objection relocated. The answer is Integration Suite native: an Arena adapter built with the Adapter SDK plus iFlows for the movement, and SAP Build Process Automation for the human approval. Decisive evidence: every mechanism `worker/` hand-rolled has an ADK facility (cluster lock, ADK persistency, user credentials, scheduler, connection status, tracing, endpoint visualization) [source: SAP Help *Adapter Development Process*, verified 2026-09-29]; and the ADK's Java/OSGi toolchain is not a new cost, because the AS/400 FetchAPI servlets are already Java and Java developers can be staffed in-house. | +| V-5 | POC: can an Adapter SDK sender adapter hold an Arena session (`POST /login` -> `arenaSessionId`, 25-minute TTL) under ADK cluster lock, and persist the delta cursor through ADK persistency? This is the first build and the gate on ADR-005. `worker/` is the behavioural specification | Open (2026-09-29) | +| V-6 | Where SAP Build Process Automation approval tasks surface for a business user, and whether they can be reached from the S/4HANA Fiori launchpad rather than only SAP Build's own inbox. This is what remains of the original acceptance test | Open (2026-09-29) | | OQ-12 | The ABAP/RAP-dependent items V-2, V-3, OQ-5, OQ-8, OQ-9 and OQ-10 are all scoped to the parked development tenant. They are **parked with ADR-004**, not closed; each returns only if the RAP route is revived. | Parked (2026-09-29) | ## Status diff --git a/docs/adr/ADR-005-integration-suite-native.md b/docs/adr/ADR-005-integration-suite-native.md new file mode 100644 index 0000000..b712fe8 --- /dev/null +++ b/docs/adr/ADR-005-integration-suite-native.md @@ -0,0 +1,81 @@ +# ADR-005 — OQ-11 closed: Integration Suite native — Arena ADK adapter + iFlows, approval in SAP Build Process Automation + +Date: 2026-09-29 · Status: Accepted (closes OQ-11; narrows ADR-004) + +## Context + +ADR-004 withdrew the on-stack RAP route and said the application moves to a +side-by-side runtime against released APIs, leaving the host open as OQ-11: +key-user extensibility in the tenant, or a CAP service on Cloud Foundry. + +Both of those options failed the criterion that actually decides this. The test +is not build cost — it is whether the next person finds the thing inside the +platform. A CAP service or a hardened worker on Cloud Foundry is discoverable +only to whoever already knows the route to it, which is the same objection that +produced ADR-002 in the first place, merely relocated. Custom applications +living outside the platform are not acceptable here. + +Two findings then settled which native option to take. + +**The Adapter Development Kit already provides the infrastructure my worker +invented.** Every non-trivial mechanism in `worker/` has a first-class ADK +facility [source: SAP Help, *Adapter Development Process*, Cloud Integration, +verified 2026-09-29]: + +| Hand-rolled in `worker/` | ADK facility | +|---|---| +| Promise lock so only one Arena login runs; correctness dependent on `instances: 1` | Managing Cluster Lock in Custom Adapters | +| Delta cursor persistence | Enabling ADK Persistency | +| Arena credentials in environment / a user-provided service | Accessing User Credentials | +| Delta poll timer | Enabling Scheduler Support for ADK Sender Adapter | +| `/api/health` with `ok`/`degraded` | Enabling Connection Status for Integration Flow | +| Structured logging | Enabling Tracing for Custom Adapter | +| Webhook ingress URL | Enabling Endpoint Visualization for Custom Adapter | + +So the adapter does not merely present better — it deletes the custom +infrastructure the worker existed to supply. + +**Java is not a new skill for this estate.** The ADK is a Java, Maven and OSGi +toolchain, which I had recorded as the cost of this route. It is not a cost +here: the AS/400 FetchAPI servlets on `mcl2000` are already Java, and Java +developers can be staffed from inside the company. One language and one team +therefore span both ends of the estate, and the ADK covers the on-premise leg +directly through *Accessing On-Premise Application using Cloud Connector* — +the sanctioned route to `mcl2000`, which retires the deleted Cloud Foundry +`fetchapi-bridge` pattern rather than rebuilding it. + +## Decision + +The integration is Integration Suite native. Nothing runs on Cloud Foundry and +nothing is written in ABAP. + +- **Arena connectivity** is a custom adapter built with the Adapter SDK: a + sender adapter carrying the webhook endpoint and the delta scheduler, using + cluster lock for single-flight login, ADK persistency for the delta cursor, + and the tenant's user credentials for Arena secrets. +- **Movement** is iFlows: Arena → the released S/4 OData APIs for Product, BOM, + Change Master and Attachment. +- **Human approval** is SAP Build Process Automation, which is already entitled + in the global account (`process-automation`, `process-automation-service`), so + it requires assignment rather than procurement. +- **The S/4 target** remains released OData APIs through the customizing tenant + `my429480`. + +`worker/` stops being a deliverable and becomes the **specification**: its 137 +tests describe the Arena session, delta-cursor and webhook behaviour the adapter +must reproduce. That is worth more than its code, and it is why ADR-004 kept it. + +## Consequences + +- ADR-004's phrase "a side-by-side runtime" is narrowed: there is no custom + application runtime at all. Side-by-side now means "in Integration Suite", + not "on Cloud Foundry". +- The Fiori Elements app in `app/` has no target service under this decision. + Approval screens come from SAP Build Process Automation. I keep `app/` as + reference rather than deleting it, on the same reasoning as the parked RAP + objects, and I do not repoint it. +- New verification items: V-5 (can an ADK adapter hold an Arena session under + cluster lock) and V-6 (where SAP Build Process Automation tasks surface for a + business user). +- The estate gains a second use for the same skill: adapters for `softco-ap` + and the AS/400 legs can follow the same pattern.