Add Design Center Experience API (dc-xapi-service) spec - #161
Conversation
Publishes the OpenAPI spec for dc-xapi-service, the Experience API
that powers the current Design Center UI architecture. Translated
manually from the internal RAML source (definitions/v2/api.raml in
the dc-xapi-service repo), following the same pattern used for
api-designer-experience: shared securitySchemes/parameters via
fragments/anypoint_fragment.yaml.
Covers /status, /features, /configuration, /oauth-callback,
/auth/profile, /auth/me, /organizations/{organizationId}/environments,
/organizations/{organizationId}/projects, and /events.
Validated locally: make validate-api (0 violations, 4 accepted
warnings matching the api-portal-xapi baseline), x-origin validation,
make generate-portal, and make test-portal (592 pytest + 251 Jest).
lbauret
left a comment
There was a problem hiding this comment.
New OAS publish for dc-xapi-service — hand-translated from dc-xapi-service/definitions/v2/api.raml. Path-item parameter placement, security carve-outs on /status//oauth-callback, and the shared-fragment refs all land at the right YAML nesting. Two fidelity issues below are worth catching before this ships to the Hub (both change what consumers will actually see), plus four smaller notes on cleanup that would be much easier now than after publish.
AI-assisted review
Should fix
1. originalFormatVersion: "1.0" in exchange.json is wrong for an OAS 3.0 asset — apis/dc-xapi-service/exchange.json:10
Every peer OAS asset in apis/ uses "3.0" (api-portal-xapi, cloudhub-20, access-management, api-manager, api-designer-experience, metrics). The value refers to the OpenAPI format version, not the API's own version. Publishing with "1.0" misrepresents the format in Exchange metadata and may affect portal generation / MCP tooling that discriminates on it.
"originalFormatVersion": "3.0"2. /status/apis endpoint dropped, and /status response shape doesn't match the RAML source — apis/dc-xapi-service/api.yaml:23-46
Source RAML has two distinct resources: GET /status (empty body — health probe) and nested GET /status/apis (returns naked array [{name,url,isMock}]). This PR collapses them: it exposes only GET /status and returns a wrapper {apis: [...]}. That's neither of the two source shapes. Either the OAS drops a real endpoint or it documents the wrong response schema — unless runtime testing confirmed the deployed service already returns {apis: [...]} from /status, in which case worth mentioning in the PR body.
/status/apis:
get:
description: List downstream services this xAPI depends on.
operationId: getStatusApis
security: []
responses:
'200':
content:
application/json:
schema:
type: array
items:
type: object
properties:
name: { type: string }
url: { type: string }
isMock: { type: boolean }…and remove the apis wrapper from /status.
Consider
3. Authorization header declared both as bearerAuth scheme and as an explicit required header parameter — apis/dc-xapi-service/api.yaml:106-115, 128-137
/auth/profile and /auth/me inherit security: [bearerAuth, clientAuth] AND declare Authorization as a required header parameter. Spec-tooling clients will generate both a bearer-auth injector and an Authorization argument. OpenAPI's bearerAuth already covers this. Sibling api-designer-experience has the same anti-pattern — pre-existing, but worth cleaning up on a fresh publish.
4. /oauth-callback description likely fails validate-descriptions (imperative check) — apis/dc-xapi-service/api.yaml:82
"OAuth2 redirect callback invoked by Core Services after a successful login…" starts with a noun phrase. Makefile advertises make validate-descriptions explicitly to enforce imperative operation descriptions. Every other operation here starts imperative (Check, Get, List, Report). PR body claims make validate-api clean but doesn't mention validate-descriptions.
Fix: "Exchange an OAuth2 authorization code and redirect the browser back to the originating URL."
5. exchange.json has stray leading indentation — apis/dc-xapi-service/exchange.json:1
Two spaces before the opening {. Valid JSON but no other exchange.json in apis/ starts that way; anything diffing/templating on this file treats it as an anomaly.
6. type: integer for pageIndex / pageSize diverges from RAML source type: number — apis/dc-xapi-service/api.yaml:170-181
Almost certainly correct (indexes are ints), but a silent tightening from the source contract. Flagging for author awareness only — no fix required.
Summary
2 Should fix, 4 Consider — verdict COMMENT. Top ask: fix originalFormatVersion to "3.0" and reconcile /status vs /status/apis before this lands in the Hub, since both change what published consumers see.
| "assetId": "api-designer-dc-xapi-service", | ||
| "version": "1.0.0", | ||
| "apiVersion": "v2", | ||
| "originalFormatVersion": "1.0", |
There was a problem hiding this comment.
Should fix — this field is the OpenAPI format version, not the API's own version. Every peer OAS asset in apis/ (api-portal-xapi, cloudhub-20, access-management, api-manager, api-designer-experience, metrics) uses "3.0". Publishing as "1.0" misrepresents the format to Exchange and downstream MCP/portal tooling.
"originalFormatVersion": "3.0"| - clientAuth: [] | ||
| paths: | ||
| /status: | ||
| get: |
There was a problem hiding this comment.
Should fix — the RAML source has two distinct resources: GET /status (empty body health probe) and nested GET /status/apis (naked array [{name,url,isMock}]). This PR collapses them into a single GET /status returning a wrapper {apis: [...]} — which matches neither source shape. Either add /status/apis back and drop the apis wrapper from /status, or if runtime already returns {apis: [...]} from /status, please mention that in the PR body so the RAML/OAS divergence is documented.
| get: | ||
| description: Get the runtime configuration for the current environment (feature flags, downstream service URLs, and related settings consumed by the Design Center UI). | ||
| operationId: getConfiguration | ||
| responses: |
There was a problem hiding this comment.
Consider — this description starts with a noun phrase, but the Makefile enforces imperative descriptions via make validate-descriptions. Every other operation in this file starts with a verb (Check, Get, List, Report). Suggested imperative form:
Exchange an OAuth2 authorization code and redirect the browser back to the originating URL.
| description: Authorization code issued by the identity provider. | ||
| required: true | ||
| schema: | ||
| type: string |
There was a problem hiding this comment.
Consider — /auth/profile and /auth/me already inherit security: [bearerAuth, clientAuth] from the top level, so declaring Authorization as an explicit required header parameter here (also at L128 on /auth/me) is redundant. Spec-tooling clients will generate both a bearer-auth injector AND an Authorization argument. Recommend dropping the explicit header parameter — the security scheme already covers it. Sibling api-designer-experience has the same anti-pattern; cleaning it up on this fresh publish keeps generated clients tidy.
…r redundancy, description style - Split /status into GET /status (bare health check) and GET /status/apis (downstream API list), matching the RAML source's two distinct resources - Fix originalFormatVersion in exchange.json (1.0 -> 3.0) - Remove redundant explicit Authorization header from /auth/profile and /auth/me (already covered by inherited security scheme) - Rewrite /oauth-callback description in imperative mood - Remove stray leading whitespace in exchange.json
spezzirriemiliano
left a comment
There was a problem hiding this comment.
APPROVE — New API spec (dc-xapi-service) passes all deterministic validators; only warnings match the api-portal-xapi baseline the PR calls out. Manual review found no blockers.
Suggestions (non-blocking):
sharedquery parameter ongetProjectsis declaredtype: stringbut its description says 'When true...'. Considertype: booleanfor clarity.projectType,validProjectTypes, andorderByare naked strings; enums (or a documented format) would help agents call them correctly.getStatusApisexample includes an internal service-mesh hostname (project-manager.msap.svc.mesh.sfdc.net). It is what the endpoint returns, but consider whether an example is the right place to surface it publicly.
Validators: descriptions PASS · xorigin PASS · governed PASS (0 violations, 4 baseline warnings).
- /status/apis: drop the security: [] override so it inherits the global bearerAuth + clientAuth, matching securedBy: [auth] added in mulesoft-emu/dc-xapi-service#465 - /events: response is 204 No Content, not 200 with a body
spezzirriemiliano
left a comment
There was a problem hiding this comment.
New private API spec for dc-xapi-service (Design Center Experience API) follows established repo patterns: server URLs, x-origin warnings, and examples all match the existing api-portal-xapi baseline. All operationIds are camelCase verb-noun. Validators pass with 0 violations (validate-descriptions, validate-xorigin, validate-all-governed). No blockers found.
Design Center Experience API was incorrectly marked visibility: private, which caused the portal generator to exclude it from the public catalog and homepage — it only surfaced in AGENTS.md's Internal APIs section. No other API in this spec set (besides the intentionally-private api-portal-xapi) has this flag, so it was left over from an earlier draft.
|
Hi team. Could you please review this PR (Design Center Experience API / dc-xapi-service)? Already approved by someone on the team, and the requested changes have been incorporated. I also validated the specification and the portal locally with:
|
spezzirriemiliano
left a comment
There was a problem hiding this comment.
New OAS spec for dc-xapi-service passes all deterministic validators (validate-descriptions, validate-xorigin, validate-all-governed) with 0 violations — only warnings match the api-portal-xapi baseline. Prior review feedback (originalFormatVersion, /status endpoint shape, Authorization header redundancy, imperative description style) has already been addressed in later commits. No blockers found.
|
Hi team — quick question on PR merge permissions for #161. I created it following the EMU contribution guide, using my non-EMU account (IgnacioAmerico), which is the one the commits are under. With my EMU account (iamerico_sfemu) I correctly get blocked ("You cannot contribute to repositories outside of your enterprise Salesforce-EMU") — that matches the guide. But with IgnacioAmerico there's no Merge button showing on the PR at all. Could you let me know who should merge this PR, or what step I'm missing to get merge access as the non-EMU contributor? |
Summary
dc-xapi-service, the Experience API that powers the current Design Center UI architecture.definitions/v2/api.ramlin thedc-xapi-servicerepo), following the same pattern used forapi-designer-experience: sharedsecuritySchemes/parameters viafragments/anypoint_fragment.yaml./status,/features,/configuration,/oauth-callback,/auth/profile,/auth/me,/organizations/{organizationId}/environments,/organizations/{organizationId}/projects, and/events.Test plan
make validate-api— 0 violations, 4 accepted warnings matching theapi-portal-xapibaseline (organizationId/environmentId/region path-param pattern).python3 scripts/build/validate_xorigin.py— no violations.make generate-portal— generates correctly, respectsvisibility: privateinexchange.json.make test-portal— 592 pytest + 251 Jest tests pass.