Skip to content

Commit 0024abf

Browse files
os-zhuangclaude
andauthored
feat(spec)!: delete DEFAULT_DISPATCHER_ROUTES + sweep last graphql fixture debris (#3586) (#3595)
The const described a route surface that never existed (/workflow, /realtime listed; eight real prefixes missing) and was consumed by nothing in the runtime — only its own tests and api-surface.json. Its one real-world effect was underwriting CLIENT_SPEC_COMPLIANCE.md's false "FULLY COMPLIANT" verdict (retired in #3571). The maintained, guard-enforced source of truth is packages/runtime/src/route-ledger.ts. Since the major train is loading now (#3562, #3581), the removal ships directly instead of the deprecate-first interim step. Also swept what #3562 left behind: registry test fixtures renamed from graphql_api//graphql to honest OData naming, the tautological config.graphql assertions dropped, the stale '"type": "graphql"' JSDoc example corrected. Client's bare tsc -p is verified clean (the TS2741 acceptance item — resolved by #3562's schema change, confirmed here). Closes #3586 Claude-Session: https://claude.ai/code/session_01LX9ut3MK3KykE11S9bJmv5 Co-authored-by: Claude <noreply@anthropic.com>
1 parent e889386 commit 0024abf

7 files changed

Lines changed: 45 additions & 111 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
"@objectstack/spec": minor
3+
---
4+
5+
feat(spec)!: delete `DEFAULT_DISPATCHER_ROUTES` — the dead route table that
6+
underwrote a false compliance verdict (#3586, #3563 follow-up)
7+
8+
The const was consumed by nothing in the runtime — only its own tests and
9+
`api-surface.json`. It listed dispatcher branches that never existed
10+
(`/workflow`, `/realtime`) while omitting eight real prefixes (`/keys`,
11+
`/mcp`, `/mcp/skill`, `/actions`, `/security`, `/share-links`, `/ready`,
12+
`/openapi.json`), and `CLIENT_SPEC_COMPLIANCE.md` anchored a "FULLY
13+
COMPLIANT" verdict on it while 27 real routes had no SDK expression.
14+
15+
The audited, guard-enforced source of truth for the dispatcher's route
16+
surface is `packages/runtime/src/route-ledger.ts` (#3569): the conformance
17+
suite fails when the registry and the ledger drift, which the dead table
18+
never could.
19+
20+
Also swept the last GraphQL fixture debris that #3562's surface removal
21+
left behind: registry test fixtures renamed to honest OData naming, the
22+
tautological `config.graphql` assertions dropped, and the stale
23+
`"type": "graphql"` JSDoc example in `registry.zod.ts` corrected.
24+
25+
Breaking for anyone importing `DEFAULT_DISPATCHER_ROUTES` (a repo-wide and
26+
objectui-wide grep shows zero consumers); shipped as minor per the
27+
launch-window convention, cf. #3562/#3581.

packages/spec/api-surface.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2357,7 +2357,6 @@
23572357
"DEFAULT_BATCH_ROUTES (const)",
23582358
"DEFAULT_DATA_CRUD_ROUTES (const)",
23592359
"DEFAULT_DISCOVERY_ROUTES (const)",
2360-
"DEFAULT_DISPATCHER_ROUTES (const)",
23612360
"DEFAULT_I18N_ROUTES (const)",
23622361
"DEFAULT_METADATA_ROUTES (const)",
23632362
"DEFAULT_NOTIFICATION_ROUTES (const)",

packages/spec/src/api/dispatcher.test.ts

Lines changed: 3 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
DispatcherConfigSchema,
55
DispatcherErrorCode,
66
DispatcherErrorResponseSchema,
7-
DEFAULT_DISPATCHER_ROUTES,
87
type DispatcherRoute,
98
type DispatcherConfig,
109
} from './dispatcher.zod';
@@ -120,71 +119,9 @@ describe('DispatcherConfigSchema', () => {
120119
});
121120
});
122121

123-
describe('DEFAULT_DISPATCHER_ROUTES', () => {
124-
it('should have routes for all protocol namespaces', () => {
125-
expect(DEFAULT_DISPATCHER_ROUTES.length).toBeGreaterThanOrEqual(15);
126-
});
127-
128-
it('should include required services', () => {
129-
const services = DEFAULT_DISPATCHER_ROUTES.map(r => r.service);
130-
expect(services).toContain('metadata');
131-
expect(services).toContain('data');
132-
expect(services).toContain('auth');
133-
});
134-
135-
it('should include the storage service', () => {
136-
const services = DEFAULT_DISPATCHER_ROUTES.map(r => r.service);
137-
expect(services).toContain('file-storage');
138-
// The feed route was retired (ADR-0052 §5 / #3180) — comments/activity are
139-
// served by the generic data API on sys_comment / sys_activity.
140-
expect(DEFAULT_DISPATCHER_ROUTES.find(r => r.prefix.includes('feed'))).toBeUndefined();
141-
});
142-
143-
it('should include optional services', () => {
144-
const services = DEFAULT_DISPATCHER_ROUTES.map(r => r.service);
145-
expect(services).toContain('ai');
146-
expect(services).toContain('i18n');
147-
expect(services).toContain('ui');
148-
expect(services).toContain('workflow');
149-
expect(services).toContain('realtime');
150-
expect(services).toContain('notification');
151-
expect(services).toContain('analytics');
152-
expect(services).toContain('automation');
153-
});
154-
155-
it('should have discovery as public route', () => {
156-
const discovery = DEFAULT_DISPATCHER_ROUTES.find(r => r.prefix.includes('discovery'));
157-
expect(discovery).toBeDefined();
158-
expect(discovery!.authRequired).toBe(false);
159-
});
160-
161-
it('should mark required services with required criticality', () => {
162-
const required = DEFAULT_DISPATCHER_ROUTES.filter(r => r.criticality === 'required');
163-
const requiredServices = required.map(r => r.service);
164-
expect(requiredServices).toContain('metadata');
165-
expect(requiredServices).toContain('data');
166-
expect(requiredServices).toContain('auth');
167-
});
168-
169-
it('should have all prefixes starting with /', () => {
170-
DEFAULT_DISPATCHER_ROUTES.forEach(route => {
171-
expect(route.prefix).toMatch(/^\//);
172-
});
173-
});
174-
175-
it('should be parseable by DispatcherConfigSchema', () => {
176-
expect(() => DispatcherConfigSchema.parse({
177-
routes: DEFAULT_DISPATCHER_ROUTES,
178-
})).not.toThrow();
179-
});
180-
181-
it('should include health route', () => {
182-
const health = DEFAULT_DISPATCHER_ROUTES.find(r => r.prefix.includes('health'));
183-
expect(health).toBeDefined();
184-
expect(health!.authRequired).toBe(false);
185-
expect(health!.criticality).toBe('required');
186-
});
187-
});
122+
// DEFAULT_DISPATCHER_ROUTES tests removed with the const (#3586) — the
123+
// dispatcher's real route surface is asserted by the route-ledger conformance
124+
// suite in packages/runtime.
188125

189126
// ============================================================================
190127
// Dispatcher Error Schemas

packages/spec/src/api/dispatcher.zod.ts

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -128,40 +128,13 @@ export type DispatcherConfig = z.infer<typeof DispatcherConfigSchema>;
128128
export type DispatcherConfigInput = z.input<typeof DispatcherConfigSchema>;
129129

130130
// ============================================================================
131-
// Default Route Table
131+
// Default Route Table — REMOVED (#3586)
132132
// ============================================================================
133-
134-
/**
135-
* Default route table for the ObjectStack HttpDispatcher.
136-
* Maps all Protocol namespaces to their corresponding services.
137-
*
138-
* This is the recommended baseline configuration. Plugins can extend
139-
* this table by declaring routes in their manifest's contributes.routes.
140-
*/
141-
export const DEFAULT_DISPATCHER_ROUTES: DispatcherRouteInput[] = [
142-
// Discovery (public)
143-
{ prefix: '/api/v1/discovery', service: 'metadata', authRequired: false, criticality: 'required' },
144-
145-
// Health (public)
146-
{ prefix: '/api/v1/health', service: 'metadata', authRequired: false, criticality: 'required' },
147-
148-
// Required Services
149-
{ prefix: '/api/v1/meta', service: 'metadata', criticality: 'required' },
150-
{ prefix: '/api/v1/data', service: 'data', criticality: 'required' },
151-
{ prefix: '/api/v1/auth', service: 'auth', criticality: 'required' },
152-
153-
// Optional Services (plugin-provided)
154-
{ prefix: '/api/v1/packages', service: 'metadata' },
155-
{ prefix: '/api/v1/ui', service: 'ui' }, // @deprecated — use /api/v1/meta/view and /api/v1/meta/dashboard instead
156-
{ prefix: '/api/v1/workflow', service: 'workflow' },
157-
{ prefix: '/api/v1/analytics', service: 'analytics' },
158-
{ prefix: '/api/v1/automation', service: 'automation' },
159-
{ prefix: '/api/v1/storage', service: 'file-storage' },
160-
{ prefix: '/api/v1/i18n', service: 'i18n' },
161-
{ prefix: '/api/v1/notifications', service: 'notification' },
162-
{ prefix: '/api/v1/realtime', service: 'realtime' },
163-
{ prefix: '/api/v1/ai', service: 'ai' },
164-
];
133+
// DEFAULT_DISPATCHER_ROUTES was deleted: nothing in the runtime ever consumed
134+
// it, it listed routes that never existed (/workflow, /realtime) while
135+
// omitting eight real ones, and it underwrote a false compliance verdict.
136+
// The audited, guard-enforced source of truth for the dispatcher's route
137+
// surface is packages/runtime/src/route-ledger.ts.
165138

166139
// ============================================================================
167140
// Dispatcher Error Codes

packages/spec/src/api/query-adapter.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ describe('QueryAdapterConfigSchema', () => {
144144
const config = QueryAdapterConfigSchema.parse({});
145145

146146
expect(config.rest).toBeUndefined();
147-
expect(config.graphql).toBeUndefined();
148147
expect(config.odata).toBeUndefined();
149148
});
150149

@@ -177,7 +176,6 @@ describe('QueryAdapterConfigSchema', () => {
177176
});
178177

179178
expect(config.rest?.filterStyle).toBe('rsql');
180-
expect(config.graphql).toBeUndefined();
181179
expect(config.odata).toBeUndefined();
182180
});
183181
});

packages/spec/src/api/registry.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -414,15 +414,15 @@ describe('API Registry Protocol', () => {
414414
],
415415
},
416416
{
417-
id: 'graphql_api',
418-
name: 'GraphQL API',
417+
id: 'odata_api',
418+
name: 'OData API',
419419
type: 'odata',
420420
version: 'v1',
421-
basePath: '/graphql',
421+
basePath: '/odata',
422422
endpoints: [
423423
{
424-
id: 'graphql_query',
425-
path: '/graphql',
424+
id: 'odata_query',
425+
path: '/odata',
426426
responses: [],
427427
},
428428
],
@@ -459,11 +459,11 @@ describe('API Registry Protocol', () => {
459459
endpoints: [],
460460
},
461461
{
462-
id: 'graphql_api',
463-
name: 'GraphQL API',
462+
id: 'odata_api',
463+
name: 'OData API',
464464
type: 'odata' as const,
465465
version: 'v1',
466-
basePath: '/graphql',
466+
basePath: '/odata',
467467
endpoints: [],
468468
},
469469
],

packages/spec/src/api/registry.zod.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ export type ConflictResolutionStrategy = z.infer<typeof ConflictResolutionStrate
680680
* "conflictResolution": "priority",
681681
* "apis": [
682682
* { "id": "customer_api", "type": "rest", ... },
683-
* { "id": "graphql_api", "type": "graphql", ... },
683+
* { "id": "odata_api", "type": "odata", ... },
684684
* { "id": "file_upload_api", "type": "file", ... }
685685
* ],
686686
* "totalApis": 3,

0 commit comments

Comments
 (0)