Skip to content

Commit f24cb83

Browse files
os-zhuangclaude
andauthored
feat(spec)!: dissolve ObjectStackProtocol composition alias — ADR-0076 D9 end-state (v17, #3606) (#3615)
The v17 window opens; the transitional union goes: - spec: the 12-contract extends alias + ObjectStackProtocolSchema (171 lines) + ObjectStackProtocolZod inferred type deleted; stale comments repointed at per-domain guidance. - metadata-protocol: ObjectStackProtocolImplementation now implements exactly the four domains it provides (Data/Metadata/Analytics/ Package). TS2559 on the old 12-way implements was the D10 evidence made compiler-visible — the facade NEVER implemented the other eight; they live in their owning services behind the discovery registry. - api-surface regenerated (net: alias/type dropped, no other drift); reference docs + skill-refs regenerated in sync. Cross-repo: cloud/objectui have zero imports of the alias (surveyed). Verified: full build 72 tasks, full test 132 tasks green. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 4e9e184 commit f24cb83

4 files changed

Lines changed: 32 additions & 201 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
"@objectstack/spec": major
3+
---
4+
5+
feat(spec)!: dissolve the ObjectStackProtocol composition alias — ADR-0076 D9 end-state (v17, #3606)
6+
7+
The transitional union of the twelve per-domain contracts (and its parallel
8+
`ObjectStackProtocolSchema` Zod object + `ObjectStackProtocolZod` inferred
9+
type, 171 schema lines) is removed. Capability availability comes from the
10+
runtime discovery `services` registry — a static union was its degraded
11+
snapshot (ADR-0076 rev.7 verdict). Depend on the narrowest per-domain slice
12+
(`DataProtocol`, `MetadataProtocol`, …; composition precedent: REST's
13+
`DataProtocol & MetadataProtocol`, A1.5/#3028).
14+
`ObjectStackProtocolImplementation` now declares exactly the four domains it
15+
actually provides (Data/Metadata/Analytics/Package) — the D10 "facade never
16+
implemented the other domains" reality, now enforced by the type system.
17+
BREAKING for anything importing the alias or the Zod schema; no runtime
18+
behavior change.

packages/metadata-protocol/src/protocol.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
22

3-
import { ObjectStackProtocol } from '@objectstack/spec/api';
3+
import type {
4+
DataProtocol, MetadataProtocol, AnalyticsProtocol, PackageProtocol,
5+
} from '@objectstack/spec/api';
46
import { IDataEngine } from '@objectstack/core';
57
import { readEnvWithDeprecation } from '@objectstack/types';
68
import type { MetadataHostEngine } from './host-engine.js';
@@ -1028,7 +1030,14 @@ export interface MetadataAuthoringGateContext {
10281030
}
10291031
export type MetadataAuthoringGate = (ctx: MetadataAuthoringGateContext) => void | Promise<void>;
10301032

1031-
export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
1033+
/**
1034+
* Implements the per-domain contracts this class ACTUALLY provides (ADR-0076
1035+
* D10 — the facade never implemented the other domains; those live in their
1036+
* owning services and are reached through the discovery `services` registry,
1037+
* never through this class).
1038+
*/
1039+
export class ObjectStackProtocolImplementation implements
1040+
DataProtocol, MetadataProtocol, AnalyticsProtocol, PackageProtocol {
10321041
private engine: MetadataHostEngine;
10331042
private getServicesRegistry?: () => Map<string, any>;
10341043
/**

packages/spec/api-surface.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2747,9 +2747,6 @@
27472747
"ObjectDefinitionResponseSchema (const)",
27482748
"ObjectQLReference (type)",
27492749
"ObjectQLReferenceSchema (const)",
2750-
"ObjectStackProtocol (interface)",
2751-
"ObjectStackProtocolSchema (const)",
2752-
"ObjectStackProtocolZod (type)",
27532750
"OpenApi31Extensions (type)",
27542751
"OpenApi31ExtensionsSchema (const)",
27552752
"OpenApiGenerationConfig (type)",

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

Lines changed: 3 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -984,177 +984,6 @@ export const GetFieldLabelsResponseSchema = lazySchema(() => z.object({
984984
// Protocol Interface Schema
985985
// ==========================================
986986

987-
/**
988-
* ObjectStack Protocol Contract
989-
*
990-
* This schema defines the complete API contract as a Zod schema.
991-
* Unlike the old TypeScript interface, this provides runtime validation
992-
* and can be used for:
993-
* - API Gateway validation
994-
* - RPC call validation
995-
* - Client SDK generation
996-
* - API documentation generation
997-
*
998-
* Each method is defined with its request and response schemas.
999-
*/
1000-
export const ObjectStackProtocolSchema = lazySchema(() => z.object({
1001-
// Discovery & Metadata
1002-
getDiscovery: z.function()
1003-
.describe('Get API discovery information'),
1004-
1005-
getMetaTypes: z.function()
1006-
.describe('Get available metadata types'),
1007-
1008-
getMetaItems: z.function()
1009-
.describe('Get all items of a metadata type'),
1010-
1011-
getMetaItem: z.function()
1012-
.describe('Get a specific metadata item'),
1013-
saveMetaItem: z.function()
1014-
.describe('Save metadata item'),
1015-
deleteMetaItem: z.function()
1016-
.describe('Delete a customization overlay row (reset to artifact default — ADR-0005)'),
1017-
getMetaItemCached: z.function()
1018-
.describe('Get a metadata item with cache validation'),
1019-
1020-
getUiView: z.function()
1021-
.describe('Get UI view definition'),
1022-
1023-
// Analytics Operations
1024-
analyticsQuery: z.function()
1025-
.describe('Execute analytics query'),
1026-
1027-
getAnalyticsMeta: z.function()
1028-
.describe('Get analytics metadata (cubes)'),
1029-
1030-
// Automation Operations
1031-
triggerAutomation: z.function()
1032-
.describe('Trigger an automation flow or script'),
1033-
1034-
// Package Management Operations
1035-
listPackages: z.function()
1036-
.describe('List installed packages with optional filters'),
1037-
1038-
getPackage: z.function()
1039-
.describe('Get a specific installed package by ID'),
1040-
1041-
installPackage: z.function()
1042-
.describe('Install a new package from manifest'),
1043-
1044-
uninstallPackage: z.function()
1045-
.describe('Uninstall a package by ID'),
1046-
1047-
enablePackage: z.function()
1048-
.describe('Enable a disabled package'),
1049-
1050-
disablePackage: z.function()
1051-
.describe('Disable an installed package'),
1052-
1053-
// Data Operations
1054-
findData: z.function()
1055-
.describe('Find data records'),
1056-
1057-
getData: z.function()
1058-
.describe('Get single data record'),
1059-
1060-
createData: z.function()
1061-
.describe('Create a data record'),
1062-
1063-
updateData: z.function()
1064-
.describe('Update a data record'),
1065-
1066-
deleteData: z.function()
1067-
.describe('Delete a data record'),
1068-
1069-
// Batch Operations
1070-
batchData: z.function()
1071-
.describe('Perform batch operations'),
1072-
1073-
createManyData: z.function()
1074-
.describe('Create multiple records'),
1075-
1076-
updateManyData: z.function()
1077-
.describe('Update multiple records'),
1078-
1079-
deleteManyData: z.function()
1080-
.describe('Delete multiple records'),
1081-
1082-
// View Management Operations
1083-
listViews: z.function()
1084-
.describe('List views for an object'),
1085-
getView: z.function()
1086-
.describe('Get a specific view'),
1087-
createView: z.function()
1088-
.describe('Create a new view'),
1089-
updateView: z.function()
1090-
.describe('Update an existing view'),
1091-
deleteView: z.function()
1092-
.describe('Delete a view'),
1093-
1094-
// Permission Operations
1095-
checkPermission: z.function()
1096-
.describe('Check if an action is permitted'),
1097-
getObjectPermissions: z.function()
1098-
.describe('Get permissions for an object'),
1099-
getEffectivePermissions: z.function()
1100-
.describe('Get effective permissions for current user'),
1101-
1102-
// Workflow Operations
1103-
getWorkflowConfig: z.function()
1104-
.describe('Get workflow configuration for an object'),
1105-
getWorkflowState: z.function()
1106-
.describe('Get workflow state for a record'),
1107-
workflowTransition: z.function()
1108-
.describe('Execute a workflow state transition'),
1109-
1110-
// Realtime Operations
1111-
realtimeConnect: z.function()
1112-
.describe('Establish realtime connection'),
1113-
realtimeDisconnect: z.function()
1114-
.describe('Close realtime connection'),
1115-
realtimeSubscribe: z.function()
1116-
.describe('Subscribe to a realtime channel'),
1117-
realtimeUnsubscribe: z.function()
1118-
.describe('Unsubscribe from a realtime channel'),
1119-
setPresence: z.function()
1120-
.describe('Set user presence state'),
1121-
getPresence: z.function()
1122-
.describe('Get channel presence information'),
1123-
1124-
// Notification Operations
1125-
registerDevice: z.function()
1126-
.describe('Register a device for push notifications'),
1127-
unregisterDevice: z.function()
1128-
.describe('Unregister a device'),
1129-
getNotificationPreferences: z.function()
1130-
.describe('Get notification preferences'),
1131-
updateNotificationPreferences: z.function()
1132-
.describe('Update notification preferences'),
1133-
listNotifications: z.function()
1134-
.describe('List notifications'),
1135-
markNotificationsRead: z.function()
1136-
.describe('Mark specific notifications as read'),
1137-
markAllNotificationsRead: z.function()
1138-
.describe('Mark all notifications as read'),
1139-
1140-
// AI Operations
1141-
aiNlq: z.function()
1142-
.describe('Natural language query'),
1143-
aiChat: z.function()
1144-
.describe('AI chat interaction'),
1145-
aiSuggest: z.function()
1146-
.describe('Get AI-powered suggestions'),
1147-
aiInsights: z.function()
1148-
.describe('Get AI-generated insights'),
1149-
1150-
// i18n Operations
1151-
getLocales: z.function()
1152-
.describe('Get available locales'),
1153-
getTranslations: z.function()
1154-
.describe('Get translations for a locale'),
1155-
getFieldLabels: z.function()
1156-
.describe('Get translated field labels for an object'),
1157-
}));
1158987

1159988
/**
1160989
* TypeScript Types
@@ -1305,21 +1134,20 @@ export type {
13051134

13061135
/**
13071136
* Zod-inferred protocol type (for runtime validation only).
1308-
* Use ObjectStackProtocol interface for implementation contracts.
1137+
* Depend on the narrowest per-domain contract (e.g. `DataProtocol`).
13091138
*/
1310-
export type ObjectStackProtocolZod = z.infer<typeof ObjectStackProtocolSchema>;
13111139

13121140
/**
13131141
* ObjectStack Protocol Interface
13141142
*
13151143
* Properly typed interface for implementing the ObjectStack API protocol.
1316-
* The Zod schema (ObjectStackProtocolSchema) is used for runtime validation,
1144+
* Per-domain Zod schemas are used for runtime validation,
13171145
* while this interface provides compile-time type safety for implementations.
13181146
*/
13191147
// ─────────────────────────────────────────────────────────────────────────────
13201148
// Protocol contracts, segmented per domain (ADR-0076 D9).
13211149
//
1322-
// `ObjectStackProtocol` (below) is the composition of these per-domain contracts
1150+
// The historical `ObjectStackProtocol` union of these per-domain contracts was
13231151
// and is shape-identical to the historical flat interface — a back-compat alias.
13241152
// New code should depend on the narrowest slice it needs (e.g. `DataProtocol`).
13251153
// Per ADR-0076 D9 (rev.7) the union is transitional; the end-state dissolves it
@@ -1440,24 +1268,3 @@ export interface I18nProtocol {
14401268
getFieldLabels?(request: GetFieldLabelsRequest): Promise<GetFieldLabelsResponse>;
14411269
}
14421270

1443-
/**
1444-
* ObjectStackProtocol — composition of the per-domain contracts above
1445-
* (ADR-0076 D9). Shape-identical to the historical flat interface, so every
1446-
* existing implementation/consumer is unaffected. Prefer depending on the
1447-
* narrowest slice (e.g. `DataProtocol`). Per ADR-0076 D9 (rev.7) this union is
1448-
* transitional; the end-state dissolves it (capability availability comes from
1449-
* the discovery `services` registry, not a static union).
1450-
*/
1451-
export interface ObjectStackProtocol extends
1452-
DataProtocol,
1453-
MetadataProtocol,
1454-
AnalyticsProtocol,
1455-
AutomationProtocol,
1456-
PackageProtocol,
1457-
ViewProtocol,
1458-
PermissionProtocol,
1459-
WorkflowProtocol,
1460-
RealtimeProtocol,
1461-
NotificationProtocol,
1462-
AiProtocol,
1463-
I18nProtocol {}

0 commit comments

Comments
 (0)