diff --git a/.squad/decisions.md b/.squad/decisions.md index 6e575ee..bb6c42b 100644 --- a/.squad/decisions.md +++ b/.squad/decisions.md @@ -2,6 +2,12 @@ ## Active Decisions +### 2026-06-05T23:40:00Z: Operation reconciliation PATCH strips schema refs +**By:** ApimExpert + TypeScriptDev +**Status:** Implemented +**What:** `reconcileOperationsAfterSpecImport` removes `schemaId` and `typeName` from operation `request.representations` and `responses[].representations` before PATCH. +**Why:** Those IDs are source-instance specific. After target spec import, APIM assigns its own schema IDs; sending stale source IDs causes APIM to drop schema refs. + ### 2026-05-28T23:06:01Z: Team-Wide Evidence Standard **By:** User directive (anonymized) **Status:** Active directive diff --git a/src/services/api-publisher.ts b/src/services/api-publisher.ts index e7a23c3..72bb736 100644 --- a/src/services/api-publisher.ts +++ b/src/services/api-publisher.ts @@ -434,6 +434,9 @@ async function reconcileOperationsAfterSpecImport( } } + // Strip source schema refs; APIM rebinds on import and drops stale IDs. + stripRepresentationSchemaRefs(patchProps); + if (Object.keys(patchProps).length === 0) return; const patchBody: Record = { properties: patchProps }; @@ -456,6 +459,39 @@ async function reconcileOperationsAfterSpecImport( } } +/** Strip source schema refs from request/response representations before PATCH. */ +function stripRepresentationSchemaRefs(patchProps: Record): void { + const SCHEMA_REF_FIELDS = ['schemaId', 'typeName']; + + function stripFromRepresentations(representations: unknown): void { + if (!Array.isArray(representations)) return; + for (const rep of representations) { + if (rep && typeof rep === 'object') { + for (const field of SCHEMA_REF_FIELDS) { + delete (rep as Record)[field]; + } + } + } + } + + // Strip schema refs from request.representations. + const request = patchProps.request; + if (request && typeof request === 'object') { + const req = request as Record; + stripFromRepresentations(req.representations); + } + + // Strip schema refs from responses[].representations. + const responses = patchProps.responses; + if (Array.isArray(responses)) { + for (const response of responses) { + if (response && typeof response === 'object') { + stripFromRepresentations((response as Record).representations); + } + } + } +} + /** * Extract revision number from API name (e.g., "my-api;rev=2" -> 2) */