Skip to content

Commit d0f4b13

Browse files
os-zhuangclaude
andauthored
feat(spec): segment ObjectStackProtocol into per-domain interfaces (ADR-0076 D9, step 1) (#2429)
* feat(spec): segment ObjectStackProtocol into per-domain protocol interfaces (ADR-0076 D9) Split the 70-method, 11-domain ObjectStackProtocol god-interface into focused, exported per-domain contracts (DataProtocol, MetadataProtocol, AnalyticsProtocol, AutomationProtocol, PackageProtocol, ViewProtocol, PermissionProtocol, WorkflowProtocol, RealtimeProtocol, NotificationProtocol, AiProtocol, I18nProtocol, FeedProtocol). ObjectStackProtocol now `extends` all of them — shape-identical to the old flat interface, so non-breaking. This is the lowest-risk, foundational step of ADR-0076 D9: pure type-level, shape-preserving, no runtime change. Consumers can now depend on the narrowest slice (e.g. DataProtocol). The composed union is transitional (D9 rev.7). Verified: turbo build (spec + rest + metadata-protocol + objectql) green incl. DTS — the impl class still satisfies `implements ObjectStackProtocol`; spec suite 243 files / 6602 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(spec): update api-surface snapshot for the 13 segmented protocol interfaces The api-surface ratchet flagged 13 additive exports (0 breaking) from the ObjectStackProtocol segmentation. Regenerated the committed snapshot. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 4899c47 commit d0f4b13

3 files changed

Lines changed: 107 additions & 26 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@objectstack/spec': minor
3+
---
4+
5+
Segment `ObjectStackProtocol` into per-domain protocol interfaces (ADR-0076 D9)
6+
7+
`ObjectStackProtocol` was a single 70-method interface spanning 11 unrelated domains. It is now the **composition** of focused per-domain contracts — `DataProtocol`, `MetadataProtocol`, `AnalyticsProtocol`, `AutomationProtocol`, `PackageProtocol`, `ViewProtocol`, `PermissionProtocol`, `WorkflowProtocol`, `RealtimeProtocol`, `NotificationProtocol`, `AiProtocol`, `I18nProtocol`, `FeedProtocol` — all newly exported.
8+
9+
`ObjectStackProtocol` now `extends` all of them and is **shape-identical** to the previous flat interface, so every existing implementation/consumer is unaffected (non-breaking). New code should depend on the narrowest slice it needs (e.g. `DataProtocol`). Per ADR-0076 D9 (rev.7) the composed union is transitional; capability availability is provided at runtime by the discovery `services` registry.

packages/spec/api-surface.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2050,13 +2050,15 @@
20502050
"AiNlqRequestSchema (const)",
20512051
"AiNlqResponse (type)",
20522052
"AiNlqResponseSchema (const)",
2053+
"AiProtocol (interface)",
20532054
"AiSuggestRequest (type)",
20542055
"AiSuggestRequestSchema (const)",
20552056
"AiSuggestResponse (type)",
20562057
"AiSuggestResponseSchema (const)",
20572058
"AnalyticsEndpoint (type)",
20582059
"AnalyticsMetadataResponse (type)",
20592060
"AnalyticsMetadataResponseSchema (const)",
2061+
"AnalyticsProtocol (interface)",
20602062
"AnalyticsQueryRequest (type)",
20612063
"AnalyticsQueryRequestSchema (const)",
20622064
"AnalyticsResultResponseSchema (const)",
@@ -2121,6 +2123,7 @@
21212123
"AutomationApiErrorCode (type)",
21222124
"AutomationFlowPathParams (type)",
21232125
"AutomationFlowPathParamsSchema (const)",
2126+
"AutomationProtocol (interface)",
21242127
"AutomationRunPathParams (type)",
21252128
"AutomationRunPathParamsSchema (const)",
21262129
"AutomationTriggerRequest (type)",
@@ -2241,6 +2244,7 @@
22412244
"DataEventType (type)",
22422245
"DataLoaderConfig (type)",
22432246
"DataLoaderConfigSchema (const)",
2247+
"DataProtocol (interface)",
22442248
"DeduplicationStrategy (type)",
22452249
"DeleteDataRequest (type)",
22462250
"DeleteDataRequestSchema (const)",
@@ -2359,6 +2363,7 @@
23592363
"FeedListFilterType (const)",
23602364
"FeedPathParams (type)",
23612365
"FeedPathParamsSchema (const)",
2366+
"FeedProtocol (interface)",
23622367
"FeedUnsubscribeRequest (type)",
23632368
"FeedUnsubscribeRequestSchema (const)",
23642369
"FieldError (type)",
@@ -2527,6 +2532,7 @@
25272532
"HttpFindQueryParamsSchema (const)",
25282533
"HttpMethod (type)",
25292534
"HttpStatusCode (type)",
2535+
"I18nProtocol (interface)",
25302536
"IdRequest (type)",
25312537
"IdRequestSchema (const)",
25322538
"ImportValidationConfig (type)",
@@ -2625,6 +2631,7 @@
26252631
"MetadataOverlayResponse (type)",
26262632
"MetadataOverlayResponseSchema (const)",
26272633
"MetadataOverlaySaveRequestSchema (const)",
2634+
"MetadataProtocol (interface)",
26282635
"MetadataQueryRequestSchema (const)",
26292636
"MetadataQueryResponse (type)",
26302637
"MetadataQueryResponseSchema (const)",
@@ -2644,6 +2651,7 @@
26442651
"NotificationPreferences (type)",
26452652
"NotificationPreferencesInput (type)",
26462653
"NotificationPreferencesSchema (const)",
2654+
"NotificationProtocol (interface)",
26472655
"NotificationSchema (const)",
26482656
"OData (const)",
26492657
"ODataConfig (type)",
@@ -2691,6 +2699,7 @@
26912699
"PackageInstallResponseSchema (const)",
26922700
"PackagePathParams (type)",
26932701
"PackagePathParamsSchema (const)",
2702+
"PackageProtocol (interface)",
26942703
"PackageRollbackRequest (type)",
26952704
"PackageRollbackRequestSchema (const)",
26962705
"PackageRollbackResponse (type)",
@@ -2700,6 +2709,7 @@
27002709
"PackageUpgradeRequestSchema (const)",
27012710
"PackageUpgradeResponse (type)",
27022711
"PackageUpgradeResponseSchema (const)",
2712+
"PermissionProtocol (interface)",
27032713
"PinFeedItemRequest (type)",
27042714
"PinFeedItemRequestSchema (const)",
27052715
"PinFeedItemResponse (type)",
@@ -2739,6 +2749,7 @@
27392749
"RealtimeEventType (type)",
27402750
"RealtimePresence (type)",
27412751
"RealtimePresenceSchema (const)",
2752+
"RealtimeProtocol (interface)",
27422753
"RealtimeRecordAction (type)",
27432754
"RealtimeSubscribeRequest (type)",
27442755
"RealtimeSubscribeRequestSchema (const)",
@@ -2945,6 +2956,7 @@
29452956
"VersioningConfigInput (type)",
29462957
"VersioningConfigSchema (const)",
29472958
"VersioningStrategy (type)",
2959+
"ViewProtocol (interface)",
29482960
"WebSocketConfig (type)",
29492961
"WebSocketConfigSchema (const)",
29502962
"WebSocketEvent (type)",
@@ -2961,6 +2973,7 @@
29612973
"WebhookEventSchema (const)",
29622974
"WellKnownCapabilities (type)",
29632975
"WellKnownCapabilitiesSchema (const)",
2976+
"WorkflowProtocol (interface)",
29642977
"WorkflowState (type)",
29652978
"WorkflowStateSchema (const)",
29662979
"WorkflowTransitionRequest (type)",

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

Lines changed: 85 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,34 @@ export type ObjectStackProtocolZod = z.infer<typeof ObjectStackProtocolSchema>;
13761376
* The Zod schema (ObjectStackProtocolSchema) is used for runtime validation,
13771377
* while this interface provides compile-time type safety for implementations.
13781378
*/
1379-
export interface ObjectStackProtocol {
1379+
// ─────────────────────────────────────────────────────────────────────────────
1380+
// Protocol contracts, segmented per domain (ADR-0076 D9).
1381+
//
1382+
// `ObjectStackProtocol` (below) is the composition of these per-domain contracts
1383+
// and is shape-identical to the historical flat interface — a back-compat alias.
1384+
// New code should depend on the narrowest slice it needs (e.g. `DataProtocol`).
1385+
// Per ADR-0076 D9 (rev.7) the union is transitional; the end-state dissolves it
1386+
// in favour of independent domain protocols + the discovery `services` registry.
1387+
// ─────────────────────────────────────────────────────────────────────────────
1388+
1389+
/** Business-data CRUD + batch operations (thin wire-normalizers over the engine). */
1390+
export interface DataProtocol {
1391+
// Data Operations (core)
1392+
findData(request: FindDataRequest): Promise<FindDataResponse>;
1393+
getData(request: GetDataRequest): Promise<GetDataResponse>;
1394+
createData(request: CreateDataRequest): Promise<CreateDataResponse>;
1395+
updateData(request: UpdateDataRequest): Promise<UpdateDataResponse>;
1396+
deleteData(request: DeleteDataRequest): Promise<DeleteDataResponse>;
1397+
1398+
// Batch Operations (optional)
1399+
batchData?(request: BatchDataRequest): Promise<BatchDataResponse>;
1400+
createManyData?(request: CreateManyDataRequest): Promise<CreateManyDataResponse>;
1401+
updateManyData?(request: UpdateManyDataRequest): Promise<UpdateManyDataResponse>;
1402+
deleteManyData?(request: DeleteManyDataRequest): Promise<DeleteManyDataResponse>;
1403+
}
1404+
1405+
/** Discovery + metadata (sys_metadata) management. */
1406+
export interface MetadataProtocol {
13801407
// Discovery & Metadata (core)
13811408
getDiscovery(request?: GetDiscoveryRequest): Promise<GetDiscoveryResponse>;
13821409
getMetaTypes(request?: GetMetaTypesRequest): Promise<GetMetaTypesResponse>;
@@ -1392,80 +1419,89 @@ export interface ObjectStackProtocol {
13921419
deleteMetaItem?(request: DeleteMetaItemRequest): Promise<DeleteMetaItemResponse>;
13931420
getMetaItemCached?(request: GetMetaItemCachedRequest): Promise<GetMetaItemCachedResponse>;
13941421
getUiView?(request: GetUiViewRequest): Promise<GetUiViewResponse>;
1395-
1396-
// Analytics (optional)
1422+
}
1423+
1424+
/** Analytics (optional). */
1425+
export interface AnalyticsProtocol {
13971426
analyticsQuery?(request: AnalyticsQueryRequest): Promise<AnalyticsResultResponse>;
13981427
getAnalyticsMeta?(request: GetAnalyticsMetaRequest): Promise<GetAnalyticsMetaResponse>;
1428+
}
13991429

1400-
// Automation (optional)
1430+
/** Automation (optional). */
1431+
export interface AutomationProtocol {
14011432
triggerAutomation?(request: AutomationTriggerRequest): Promise<AutomationTriggerResponse>;
1433+
}
14021434

1403-
// Package Management (optional)
1435+
/** Package lifecycle (optional). */
1436+
export interface PackageProtocol {
14041437
listPackages?(request: ListPackagesRequest): Promise<ListPackagesResponse>;
14051438
getPackage?(request: GetPackageRequest): Promise<GetPackageResponse>;
14061439
installPackage?(request: InstallPackageRequest): Promise<InstallPackageResponse>;
14071440
uninstallPackage?(request: UninstallPackageRequest): Promise<UninstallPackageResponse>;
14081441
enablePackage?(request: EnablePackageRequest): Promise<EnablePackageResponse>;
14091442
disablePackage?(request: DisablePackageRequest): Promise<DisablePackageResponse>;
1443+
}
14101444

1411-
// Data Operations (core)
1412-
findData(request: FindDataRequest): Promise<FindDataResponse>;
1413-
getData(request: GetDataRequest): Promise<GetDataResponse>;
1414-
createData(request: CreateDataRequest): Promise<CreateDataResponse>;
1415-
updateData(request: UpdateDataRequest): Promise<UpdateDataResponse>;
1416-
deleteData(request: DeleteDataRequest): Promise<DeleteDataResponse>;
1417-
1418-
// Batch Operations (optional)
1419-
batchData?(request: BatchDataRequest): Promise<BatchDataResponse>;
1420-
createManyData?(request: CreateManyDataRequest): Promise<CreateManyDataResponse>;
1421-
updateManyData?(request: UpdateManyDataRequest): Promise<UpdateManyDataResponse>;
1422-
deleteManyData?(request: DeleteManyDataRequest): Promise<DeleteManyDataResponse>;
1423-
1424-
// View Management (optional)
1445+
/** View management (optional). */
1446+
export interface ViewProtocol {
14251447
listViews?(request: ListViewsRequest): Promise<ListViewsResponse>;
14261448
getView?(request: GetViewRequest): Promise<GetViewResponse>;
14271449
createView?(request: CreateViewRequest): Promise<CreateViewResponse>;
14281450
updateView?(request: UpdateViewRequest): Promise<UpdateViewResponse>;
14291451
deleteView?(request: DeleteViewRequest): Promise<DeleteViewResponse>;
1452+
}
14301453

1431-
// Permissions (optional)
1454+
/** Permissions (optional). */
1455+
export interface PermissionProtocol {
14321456
checkPermission?(request: CheckPermissionRequest): Promise<CheckPermissionResponse>;
14331457
getObjectPermissions?(request: GetObjectPermissionsRequest): Promise<GetObjectPermissionsResponse>;
14341458
getEffectivePermissions?(request: GetEffectivePermissionsRequest): Promise<GetEffectivePermissionsResponse>;
1459+
}
14351460

1436-
// Workflows (optional)
1461+
/** Workflows (optional). */
1462+
export interface WorkflowProtocol {
14371463
getWorkflowConfig?(request: GetWorkflowConfigRequest): Promise<GetWorkflowConfigResponse>;
14381464
getWorkflowState?(request: GetWorkflowStateRequest): Promise<GetWorkflowStateResponse>;
14391465
workflowTransition?(request: WorkflowTransitionRequest): Promise<WorkflowTransitionResponse>;
1466+
}
14401467

1441-
// Realtime (optional)
1468+
/** Realtime / presence (optional). */
1469+
export interface RealtimeProtocol {
14421470
realtimeConnect?(request: RealtimeConnectRequest): Promise<RealtimeConnectResponse>;
14431471
realtimeDisconnect?(request: RealtimeDisconnectRequest): Promise<RealtimeDisconnectResponse>;
14441472
realtimeSubscribe?(request: RealtimeSubscribeRequest): Promise<RealtimeSubscribeResponse>;
14451473
realtimeUnsubscribe?(request: RealtimeUnsubscribeRequest): Promise<RealtimeUnsubscribeResponse>;
14461474
setPresence?(request: SetPresenceRequest): Promise<SetPresenceResponse>;
14471475
getPresence?(request: GetPresenceRequest): Promise<GetPresenceResponse>;
1476+
}
14481477

1449-
// Notifications (optional)
1478+
/** Notifications (optional). */
1479+
export interface NotificationProtocol {
14501480
registerDevice?(request: RegisterDeviceRequest): Promise<RegisterDeviceResponse>;
14511481
unregisterDevice?(request: UnregisterDeviceRequest): Promise<UnregisterDeviceResponse>;
14521482
getNotificationPreferences?(request: GetNotificationPreferencesRequest): Promise<GetNotificationPreferencesResponse>;
14531483
updateNotificationPreferences?(request: UpdateNotificationPreferencesRequest): Promise<UpdateNotificationPreferencesResponse>;
14541484
listNotifications?(request: ListNotificationsRequest): Promise<ListNotificationsResponse>;
14551485
markNotificationsRead?(request: MarkNotificationsReadRequest): Promise<MarkNotificationsReadResponse>;
14561486
markAllNotificationsRead?(request: MarkAllNotificationsReadRequest): Promise<MarkAllNotificationsReadResponse>;
1487+
}
14571488

1458-
// AI (optional — chat is now handled by Vercel AI SDK wire protocol)
1489+
/** AI (optional — chat is now handled by the Vercel AI SDK wire protocol). */
1490+
export interface AiProtocol {
14591491
aiNlq?(request: AiNlqRequest): Promise<AiNlqResponse>;
14601492
aiSuggest?(request: AiSuggestRequest): Promise<AiSuggestResponse>;
14611493
aiInsights?(request: AiInsightsRequest): Promise<AiInsightsResponse>;
1494+
}
14621495

1463-
// i18n (optional)
1496+
/** Localization (optional). */
1497+
export interface I18nProtocol {
14641498
getLocales?(request: GetLocalesRequest): Promise<GetLocalesResponse>;
14651499
getTranslations?(request: GetTranslationsRequest): Promise<GetTranslationsResponse>;
14661500
getFieldLabels?(request: GetFieldLabelsRequest): Promise<GetFieldLabelsResponse>;
1501+
}
14671502

1468-
// Feed (optional)
1503+
/** Feed / social (optional). */
1504+
export interface FeedProtocol {
14691505
listFeed?(request: GetFeedRequest): Promise<GetFeedResponse>;
14701506
createFeedItem?(request: CreateFeedItemRequest): Promise<CreateFeedItemResponse>;
14711507
updateFeedItem?(request: UpdateFeedItemRequest): Promise<UpdateFeedItemResponse>;
@@ -1481,3 +1517,26 @@ export interface ObjectStackProtocol {
14811517
feedSubscribe?(request: SubscribeRequest): Promise<SubscribeResponse>;
14821518
feedUnsubscribe?(request: FeedUnsubscribeRequest): Promise<UnsubscribeResponse>;
14831519
}
1520+
1521+
/**
1522+
* ObjectStackProtocol — composition of the per-domain contracts above
1523+
* (ADR-0076 D9). Shape-identical to the historical flat interface, so every
1524+
* existing implementation/consumer is unaffected. Prefer depending on the
1525+
* narrowest slice (e.g. `DataProtocol`). Per ADR-0076 D9 (rev.7) this union is
1526+
* transitional; the end-state dissolves it (capability availability comes from
1527+
* the discovery `services` registry, not a static union).
1528+
*/
1529+
export interface ObjectStackProtocol extends
1530+
DataProtocol,
1531+
MetadataProtocol,
1532+
AnalyticsProtocol,
1533+
AutomationProtocol,
1534+
PackageProtocol,
1535+
ViewProtocol,
1536+
PermissionProtocol,
1537+
WorkflowProtocol,
1538+
RealtimeProtocol,
1539+
NotificationProtocol,
1540+
AiProtocol,
1541+
I18nProtocol,
1542+
FeedProtocol {}

0 commit comments

Comments
 (0)