Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/api-console-drop-dead-catalog-keys-4303.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
---
'@object-ui/console': patch
---

API Console's endpoint catalog drops the `workflow` and `feed` entries — 7 endpoint declarations that could never render on any host

`SERVICE_ENDPOINT_CATALOG` keys are looked up directly in `/discovery`'s `services` map, which the framework keys by `CoreServiceName`. Neither `workflow` (5 endpoints under `/api/v1/workflow/*`) nor `feed` (2 endpoints under `/api/v1/feed/*`) names a `CoreServiceName` slot: the `workflow` slot was retired upstream (objectstack#4451) and `feed` never was one. Both were unconditionally hidden by the fail-closed lookup (ADR-0076 D12) — a miss is indistinguishable from "no such service" — so this changes no rendered output; it only removes two catalog entries that could never surface an endpoint.

Counter-probed against current objectstack `origin/main` before removal: no `registerService('workflow')`, no mounted `/api/v1/workflow` route, and no `/api/v1/feed` route anywhere in source — both are confirmed dead, not merely unused. Per objectui#4303's ruling, this is dead-code removal, not a rename: neither key has a correctly-spelled slot to move to.

#4240's tripwire test — which pins `SERVICE_ENDPOINT_CATALOG` keys against `CoreServiceName` and had carried `workflow`/`feed` as a documented exception set — is trimmed alongside the catalog: the exception set and its `#4303` reference are removed now that both keys are gone, so the assertion goes back to a plain "every catalog key is a canonical slot" with no carve-outs.
19 changes: 3 additions & 16 deletions apps/console/src/pages/developer/hooks/useApiDiscovery.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -158,18 +158,6 @@ describe('useApiDiscovery — fail-closed posture is preserved (ADR-0076 D12)',
describe('SERVICE_ENDPOINT_CATALOG keys are canonical service-slot names', () => {
const SLOTS = new Set<string>(CoreServiceName.options);

/**
* Catalog keys that are NOT slots and are known-dead, with the finding that
* tracks them: objectui#4303. `workflow`'s slot was retired in
* objectstack#4451 and `feed` never was one, so neither can ever appear in
* `/discovery` — there is no correctly-spelled name to rename them to, which
* is why they are excepted here instead of fixed in #4240.
*
* This is a subset check, so REMOVING either key keeps this green; only
* adding a new non-slot key goes red.
*/
const KNOWN_DEAD_NON_SLOT_KEYS = new Set(['workflow', 'feed']);

it('the spec exports a usable slot vocabulary (guards the derivation itself)', () => {
expect(SLOTS.size).toBeGreaterThan(5);
expect(SLOTS.has('file-storage'), 'file-storage must be a declared CoreServiceName slot').toBe(true);
Expand All@@ -181,15 +169,14 @@ describe('SERVICE_ENDPOINT_CATALOG keys are canonical service-slot names', () =>
expect(SERVICE_ENDPOINT_CATALOG['file-storage'].defaultRoute).toBe('/api/v1/storage');
});

it('every service-gated catalog key is a canonical slot, except the documented dead ones (#4303)', () => {
it('every service-gated catalog key is a canonical slot', () => {
const nonSlot = Object.keys(SERVICE_ENDPOINT_CATALOG).filter(k => !SLOTS.has(k));
const undocumented = nonSlot.filter(k => !KNOWN_DEAD_NON_SLOT_KEYS.has(k));

expect(
undocumented,
nonSlot,
'these catalog keys name no CoreServiceName slot, so /discovery can never report them '
+ 'and their groups will never render on any host — key them by the canonical slot name, '
+ 'or retire the entry (see objectui#4303)',
+ 'or retire the entry',
).toEqual([]);
});
});
19 changes: 0 additions & 19 deletions apps/console/src/pages/developer/hooks/useApiDiscovery.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -138,17 +138,6 @@ export const SERVICE_ENDPOINT_CATALOG: Record<string, { group: string; defaultRo
{ method: 'GET', path: '/usage', desc: 'AI quota headroom per meter (console usage indicator)' },
],
},
workflow: {
group: 'Workflow',
defaultRoute: '/api/v1/workflow',
endpoints: [
{ method: 'GET', path: '/:object/config', desc: 'Get workflow configuration' },
{ method: 'GET', path: '/:object/:recordId/state', desc: 'Get workflow state' },
{ method: 'POST', path: '/:object/:recordId/transition', desc: 'Execute workflow transition', bodyTemplate: { targetState: '' } },
{ method: 'POST', path: '/:object/:recordId/approve', desc: 'Approve workflow step', bodyTemplate: { comment: '' } },
{ method: 'POST', path: '/:object/:recordId/reject', desc: 'Reject workflow step', bodyTemplate: { comment: '' } },
],
},
realtime: {
group: 'Realtime',
defaultRoute: '/api/v1/realtime',
Expand DownExpand Up@@ -209,14 +198,6 @@ export const SERVICE_ENDPOINT_CATALOG: Record<string, { group: string; defaultRo
{ method: 'DELETE', path: '/views/:id', desc: 'Delete view' },
],
},
feed: {
group: 'Feed',
defaultRoute: '/api/v1/feed',
endpoints: [
{ method: 'GET', path: '/:object/:recordId', desc: 'Get feed items' },
{ method: 'POST', path: '/:object/:recordId', desc: 'Post feed item', bodyTemplate: { body: '' } },
],
},
// The KEY is the canonical service-slot name, because it is looked up
// straight in `/discovery`'s `services` map (`discoveredServices[serviceName]`
// below) — and that map is keyed by `CoreServiceName`. The slot is
Expand Down
Loading