Skip to content
Closed
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
15 changes: 15 additions & 0 deletions .changeset/29067-push-device-registry-spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
'@objectstack/spec': patch
---

feat(spec): the push channel's protocol face: the widened device registration request, optional `INotificationService` device members, the push delivery data with its same-server `route`, and the APNs / FCM transport configuration by reference (ADR-0012 §6)

Clause-②: yes (widening)
Metadata-protocol: none

- **`RegisterDeviceRequestSchema`** gains three optional members: `vendor` (`apns` | `fcm`; absent, the server derives it from `platform`, `ios` → `apns` and `android` → `fcm`), `appId` and `locale`. `token`, `platform`, `deviceId` and `name` are unchanged, so every body a client sent before still parses as it did. The describes now say that re-registering a `deviceId` refreshes that device, and that a request without one gets a server-minted id the client keeps. A `vendor` outside `apns` / `fcm` is refused, and since the member is new, no body sent before carries one. `RegisterDeviceResponseSchema` and `UnregisterDevice*` are unchanged.
- **`INotificationService`** gains three optional members: `registerDevice(userId, request)`, `unregisterDevice(userId, deviceId)` and `invalidateDeviceToken(token)`. Their docs state the semantics an implementation owes: one live owner per token (a second user's registration takes it over), unregistering a device the user does not hold answers not found, and an invalidated token keeps its device row, disabled, with the invalidation time. Absence means the capability is unavailable, so every existing implementation stays valid.
- **`PushDeliveryDataSchema`** (new, `api/push-delivery.zod.ts`) is the data a push carries to the shell: `notificationId` and an optional `route`. `PushRouteSchema` admits only a same-server relative path (one leading `/`; no scheme, host, backslash, whitespace or control character). The route is derived, never authored: it is the notification's existing `actionUrl` when that passes the schema, and absent otherwise. No `notify` key is added.
- **`PushServiceConfigSchema`** (new, `system/push-config.zod.ts`, beside the email transport configuration): an `apns` block (token auth: `teamId`, `keyId`, `topic`, `environment: sandbox | production`, the `.p8` key by `keyRef`) and an `fcm` block (HTTP v1: `projectId`, the service-account JSON by `serviceAccountRef`). Secrets are references only (ADR-0143 D3). An inline secret is refused by name under the keys an operator would reach for, and refused as the content of a reference (a PEM block or a JSON document). `PushVendorSchema` names the two vendors. Nothing reads this shape until the push channel plugin lands, and it is not a stack-definition key.

No route row is added: the device routes land with their handlers in the server slice, so `DEFAULT_NOTIFICATION_ROUTES` is unchanged. Nothing an author or a client writes today is refused.
3 changes: 2 additions & 1 deletion content/docs/references/api/index.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: API Protocol — complete schema reference
navTitle: API Protocol
description: "The ObjectStack API Protocol in 34 reference pages: every schema in @objectstack/spec with its properties, types, defaults and a TypeScript example."
description: "The ObjectStack API Protocol in 35 reference pages: every schema in @objectstack/spec with its properties, types, defaults and a TypeScript example."
---

{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
Expand Down Expand Up @@ -33,6 +33,7 @@ This section contains all protocol schemas for the api layer of ObjectStack.
<Card href="/docs/references/api/package-lifecycle" title="Package Lifecycle" description="Source: packages/spec/src/api/package-lifecycle.zod.ts" />
<Card href="/docs/references/api/plugin-rest-api" title="Plugin Rest Api" description="Source: packages/spec/src/api/plugin-rest-api.zod.ts" />
<Card href="/docs/references/api/protocol" title="Protocol" description="Source: packages/spec/src/api/protocol.zod.ts" />
<Card href="/docs/references/api/push-delivery" title="Push Delivery" description="Source: packages/spec/src/api/push-delivery.zod.ts" />
<Card href="/docs/references/api/query-adapter" title="Query Adapter" description="Source: packages/spec/src/api/query-adapter.zod.ts" />
<Card href="/docs/references/api/realtime" title="Realtime" description="Source: packages/spec/src/api/realtime.zod.ts" />
<Card href="/docs/references/api/realtime-shared" title="Realtime Shared" description="Source: packages/spec/src/api/realtime-shared.zod.ts" />
Expand Down
1 change: 1 addition & 0 deletions content/docs/references/api/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"misc",
"package-api-assembled",
"package-lifecycle",
"push-delivery",
"record-page",
"sortability"
]
Expand Down
5 changes: 4 additions & 1 deletion content/docs/references/api/protocol.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2767,8 +2767,11 @@ The authoring surface of a metadata write. Closed: `copilot` is an AI assistant'
| :--- | :--- | :--- | :--- |
| **token** | `string` | ✅ | Device push notification token |
| **platform** | `Enum<'ios' \| 'android' \| 'web'>` | ✅ | Device platform |
| **deviceId** | `string` | optional | Unique device identifier |
| **deviceId** | `string` | optional | Client-held device id, stable per app install. Re-registering the same deviceId refreshes that device; absent, the server mints one and answers it, and the client keeps it for later registrations and unregister |
| **name** | `string` | optional | Device friendly name |
| **vendor** | `Enum<'apns' \| 'fcm'>` | optional | Push vendor the token belongs to: apns or fcm. Absent, the server derives it from platform: ios means apns, android means fcm (web has no core vendor) |
| **appId** | `string` | optional | App the token was issued to: the iOS bundle ID or the Android application ID |
| **locale** | `string` | optional | Device locale (BCP 47, for example zh-CN) that pushes to this device are rendered in |


---
Expand Down
65 changes: 65 additions & 0 deletions content/docs/references/api/push-delivery.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
title: Push Delivery schema — API Protocol reference
navTitle: Push Delivery
description: "Push delivery data — what a push carries to the shell. Reference for PushDeliveryData, PushRoute: every property with its type and default."
---

{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}

Push delivery data — what a push carries to the shell (ADR-0012 §8: the
`data` member of the push channel's rendered body).

The shell reads it when the user taps the push: `notificationId` names the
notification (the same id the inbox lists and `markRead` takes), and
`route` is the Console path the shell opens.

**Where `route` comes from — derived, never authored.** There is no
`notify` key for it. It is the notification's existing `actionUrl`, the
value the inbox already serves: an explicit `url` / `actionUrl` in the
notification's payload, else `/OBJECT/ID` built from the notification's
source record, else none. When that value passes `PushRouteSchema`
the push carries it as `route`; when it does not (an absolute URL to
another site, say) or there is none, the push carries no `route` and the
tap opens the shell's default screen. The delivery is never failed for it.

Not to be confused with the `PushNotificationSchema` that `system/` once
declared and then removed (ADR-0049): that was an authoring template shape;
this is the wire data of a delivery, produced by the platform.

<Callout type="info">
**Source:** `packages/spec/src/api/push-delivery.zod.ts`
</Callout>

## TypeScript Usage

```typescript
import { PushDeliveryDataSchema, PushRouteSchema } from '@objectstack/spec/api';
import type { PushDeliveryData, PushRoute } from '@objectstack/spec/api';

// Validate data
const result = PushDeliveryDataSchema.parse(data);
```

---

## PushDeliveryData

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **notificationId** | `string` | ✅ | Notification id — the one the inbox lists and markRead takes |
| **route** | `string` | optional | Console route opened on tap: the notification actionUrl when it is a same-server relative path, absent otherwise |


---

## PushRoute

Same-server relative path the shell opens on tap (for example /apps/crm/opportunity/123); never an absolute or off-server URL

**Type:** `string`


---

14 changes: 8 additions & 6 deletions content/docs/references/index.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Protocol reference — every schema by module
navTitle: Protocol Reference
description: Every schema published by @objectstack/spec — 1596 schemas across 14 protocol modules
description: Every schema published by @objectstack/spec — 1602 schemas across 14 protocol modules
---

{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
Expand All @@ -21,7 +21,7 @@ counts are sums of the rows they head. Regenerate with
| Module | Pages | Schemas | Description |
| :--- | ---: | ---: | :--- |
| [AI Protocol](/docs/references/ai) | 12 | 68 | Agents, tools, skills, RAG and knowledge sources, model registry, conversations. |
| [API Protocol](/docs/references/api) | 34 | 471 | REST contracts, endpoints, routing, realtime, batch, discovery. |
| [API Protocol](/docs/references/api) | 35 | 473 | REST contracts, endpoints, routing, realtime, batch, discovery. |
| [Automation Protocol](/docs/references/automation) | 15 | 78 | Flows and their nodes, approvals, ETL pipelines, webhooks, state machines, execution records. |
| [Data Protocol](/docs/references/data) | 31 | 174 | Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer. |
| [Identity Protocol](/docs/references/identity) | 5 | 27 | Users and accounts, organizations, positions, SCIM provisioning. |
Expand All @@ -32,9 +32,9 @@ counts are sums of the rows they head. Regenerate with
| [Security Protocol](/docs/references/security) | 6 | 37 | Permission sets, row-level security, sharing rules, tenancy posture. |
| [Shared Protocol](/docs/references/shared) | 10 | 31 | Primitives used across every protocol — identifiers, HTTP, expressions, error maps, enums. |
| [Studio Protocol](/docs/references/studio) | 3 | 35 | Studio designer metadata — the authoring surfaces for the protocols above. |
| [System Protocol](/docs/references/system) | 37 | 287 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. |
| [System Protocol](/docs/references/system) | 38 | 291 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. |
| [UI Protocol](/docs/references/ui) | 16 | 175 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. |
| **Total** | **205** | **1596** | 14 protocol modules |
| **Total** | **207** | **1602** | 14 protocol modules |

---

Expand Down Expand Up @@ -63,7 +63,7 @@ Agents, tools, skills, RAG and knowledge sources, model registry, conversations.

## API Protocol

**Source:** `packages/spec/src/api/` · **Import:** `@objectstack/spec/api` · **34 pages, 471 schemas**
**Source:** `packages/spec/src/api/` · **Import:** `@objectstack/spec/api` · **35 pages, 473 schemas**

REST contracts, endpoints, routing, realtime, batch, discovery.

Expand Down Expand Up @@ -93,6 +93,7 @@ REST contracts, endpoints, routing, realtime, batch, discovery.
| [`package-lifecycle.zod.ts`](/docs/references/api/package-lifecycle) | `DiscardPackageDraftsResponse`, `DuplicatePackageResponse`, `EnsureCustomizationPackageRequest`, `EnsureCustomizationPackageResponse`, `GetPackageCustomizationsRequest`, `GetPackageCustomizationsResponse`, `ImportUnmanagedPackageRequest`, `ImportUnmanagedPackageResponse`, `ListPackageCommitsResponse`, `PackageExportManifest`, `PackagePublishResult`, `ReassignOrphanedMetadataResponse`, `RevertPackageCommitResponse`, `RollbackToPackageCommitResponse` |
| [`plugin-rest-api.zod.ts`](/docs/references/api/plugin-rest-api) | `ErrorHandlingConfig`, `OpenApiGenerationConfig`, `RequestValidationConfig`, `ResponseEnvelopeConfig`, `RestApiEndpoint`, `RestApiPluginConfig`, `RestApiRouteCategory`, `RestApiRouteRegistration`, `ValidationMode` |
| [`protocol.zod.ts`](/docs/references/api/protocol) | `AiAgentCapabilities`, `AiAgentChatRequest`, `AiAgentSummary`, `AiAgentsResponse`, `AiChatRequest`, `AiChatResponse`, `AiCompleteRequest`, `AiConversation`, `AiMessage`, `AiModelsResponse`, `AiPendingAction`, `AiPendingActionStatus`, `AiStreamChunk`, `ApproveAiPendingActionResponse`, `AuditMetaItemRequest`, `AuditMetaItemResponse`, `AutomationActionsResponse`, `AutomationTriggerRequest`, `AutomationTriggerResponse`, `BatchDataRequest`, `BatchDataResponse`, `CheckPermissionRequest`, `CheckPermissionResponse`, `CloneDataResponse`, `CreateAiConversationRequest`, `CreateDataRequest`, `CreateDataResponse`, `CreateManyDataRequest`, `CreateManyDataResponse`, `DeleteDataRequest`, `DeleteDataResponse`, `DeleteManyDataRequest`, `DeleteManyDataResponse`, `DeleteMetaItemRequest`, `DeleteMetaItemResponse`, `DiffMetaItemResponse`, `DisablePackageRequest`, `DisablePackageResponse`, `EnablePackageRequest`, `EnablePackageResponse`, `FindDataRequest`, `FindDataResponse`, `FindReferencesToMetaResponse`, `FlowRegistration`, `FlowRegistrationRefusal`, `GetDataRequest`, `GetDataResponse`, `GetDiscoveryRequest`, `GetDiscoveryResponse`, `GetEffectivePermissionsRequest`, `GetEffectivePermissionsResponse`, `GetFieldLabelsRequest`, `GetFieldLabelsResponse`, `GetLocalesRequest`, `GetLocalesResponse`, `GetMetaDiagnosticsResponse`, `GetMetaItemCachedRequest`, `GetMetaItemCachedResponse`, `GetMetaItemLayeredRequest`, `GetMetaItemLayeredResponse`, `GetMetaItemRequest`, `GetMetaItemResponse`, `GetMetaItemsRequest`, `GetMetaItemsResponse`, `GetMetaTypesRequest`, `GetMetaTypesResponse`, `GetNotificationPreferencesRequest`, `GetNotificationPreferencesResponse`, `GetObjectPermissionsRequest`, `GetObjectPermissionsResponse`, `GetPackageRequest`, `GetPackageResponse`, `GetPresenceRequest`, `GetPresenceResponse`, `GetPublishedMetaItemResponse`, `GetRecordFieldAccessResponse`, `GetTranslationsRequest`, `GetTranslationsResponse`, `GetUiViewRequest`, `GetUiViewResponse`, `HistoryMetaItemRequest`, `HistoryMetaItemResponse`, `HttpFindQueryParams`, `InstallPackageRequest`, `InstallPackageResponse`, `ListAiConversationsRequest`, `ListAiConversationsResponse`, `ListAiPendingActionsRequest`, `ListAiPendingActionsResponse`, `ListDraftsResponse`, `ListNotificationsRequest`, `ListNotificationsResponse`, `ListPackagesRequest`, `ListPackagesResponse`, `MarkAllNotificationsReadRequest`, `MarkAllNotificationsReadResponse`, `MarkNotificationsReadRequest`, `MarkNotificationsReadResponse`, `MetadataAuthoringClient`, `MetadataAuthoringSurface`, `MetadataConflictError`, `Notification`, `NotificationPreferences`, `PublicFormSubmitResponse`, `PublishMetaItemRequest`, `PublishMetaItemResponse`, `PublishPackageDraftsRequest`, `PublishPackageDraftsResponse`, `RealtimeConnectRequest`, `RealtimeConnectResponse`, `RealtimeDisconnectRequest`, `RealtimeDisconnectResponse`, `RealtimeSubscribeRequest`, `RealtimeSubscribeResponse`, `RealtimeUnsubscribeRequest`, `RealtimeUnsubscribeResponse`, `RegisterDeviceRequest`, `RegisterDeviceResponse`, `RejectAiPendingActionResponse`, `RollbackMetaItemResponse`, `RuntimeAuthoringIssue`, `SaveMetaItemRequest`, `SaveMetaItemResponse`, `SearchAllHit`, `SearchAllPageHit`, `SearchAllResponse`, `SetPresenceRequest`, `SetPresenceResponse`, `UninstallPackageRequest`, `UninstallPackageResponse`, `UnregisterDeviceRequest`, `UnregisterDeviceResponse`, `UpdateAiConversationRequest`, `UpdateDataRequest`, `UpdateDataResponse`, `UpdateManyDataRequest`, `UpdateManyDataResponse`, `UpdateNotificationPreferencesRequest`, `UpdateNotificationPreferencesResponse`, `ValidateDataIssue`, `ValidateDataRequest`, `ValidateDataResponse` |
| [`push-delivery.zod.ts`](/docs/references/api/push-delivery) | `PushDeliveryData`, `PushRoute` |
| [`query-adapter.zod.ts`](/docs/references/api/query-adapter) | `ODataQueryAdapter`, `OperatorMapping`, `QueryAdapterConfig`, `QueryAdapterTarget`, `RestQueryAdapter` |
| [`realtime.zod.ts`](/docs/references/api/realtime) | `RealtimeConfig`, `RealtimeEvent`, `RealtimeEventType`, `RealtimePresence`, `Subscription`, `SubscriptionEvent`, `TransportProtocol` |
| [`realtime-shared.zod.ts`](/docs/references/api/realtime-shared) | `BasePresence`, `PresenceStatus`, `RealtimeRecordAction` |
Expand Down Expand Up @@ -324,7 +325,7 @@ Studio designer metadata — the authoring surfaces for the protocols above.

## System Protocol

**Source:** `packages/spec/src/system/` · **Import:** `@objectstack/spec/system` · **37 pages, 287 schemas**
**Source:** `packages/spec/src/system/` · **Import:** `@objectstack/spec/system` · **38 pages, 291 schemas**

The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance.

Expand Down Expand Up @@ -355,6 +356,7 @@ The runtime environment — logging, jobs, cache, metrics, notifications, i18n a
| [`migration.zod.ts`](/docs/references/system/migration) | `AddFieldOperation`, `ChangeSet`, `CreateObjectOperation`, `DataMigrationFlag`, `DeleteObjectOperation`, `ExecuteSqlOperation`, `MigrationDependency`, `MigrationJournalEvent`, `MigrationOperation`, `ModifyFieldOperation`, `OrganizationOwnershipBirthMarker`, `RemoveFieldOperation`, `RenameObjectOperation` |
| [`notification.zod.ts`](/docs/references/system/notification) | `NotificationChannel` |
| [`object-storage.zod.ts`](/docs/references/system/object-storage) | `AccessControlConfig`, `BucketConfig`, `FileMetadata`, `LifecycleAction`, `LifecyclePolicyConfig`, `LifecyclePolicyRule`, `MultipartUploadConfig`, `ObjectMetadata`, `ObjectStorageConfig`, `PresignedUrlConfig`, `StorageAcl`, `StorageClass`, `StorageConnection`, `StorageProvider`, `StorageScope` |
| [`push-config.zod.ts`](/docs/references/system/push-config) | `ApnsTransportConfig`, `FcmTransportConfig`, `PushServiceConfig`, `PushVendor` |
| [`registry-config.zod.ts`](/docs/references/system/registry-config) | `RegistryConfig`, `RegistrySyncPolicy`, `RegistryUpstream` |
| [`search-engine.zod.ts`](/docs/references/system/search-engine) | `AnalyzerConfig`, `FacetConfig`, `SearchConfig`, `SearchIndexConfig`, `SearchProvider` |
| [`security-context.zod.ts`](/docs/references/system/security-context) | `ComplianceAuditRequirement`, `ComplianceEncryptionRequirement`, `ComplianceFramework`, `DataClassification`, `DataClassificationPolicy`, `MaskingVisibilityRule`, `SecurityContextConfig`, `SecurityEventCorrelation` |
Expand Down
3 changes: 2 additions & 1 deletion content/docs/references/system/index.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: System Protocol — complete schema reference
navTitle: System Protocol
description: "The ObjectStack System Protocol in 37 reference pages: every schema in @objectstack/spec with its properties, types, defaults and a TypeScript example."
description: "The ObjectStack System Protocol in 38 reference pages: every schema in @objectstack/spec with its properties, types, defaults and a TypeScript example."
---

{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
Expand Down Expand Up @@ -34,6 +34,7 @@ This section contains all protocol schemas for the system layer of ObjectStack.
<Card href="/docs/references/system/migration" title="Migration" description="Source: packages/spec/src/system/migration.zod.ts" />
<Card href="/docs/references/system/notification" title="Notification" description="Source: packages/spec/src/system/notification.zod.ts" />
<Card href="/docs/references/system/object-storage" title="Object Storage" description="Source: packages/spec/src/system/object-storage.zod.ts" />
<Card href="/docs/references/system/push-config" title="Push Config" description="Source: packages/spec/src/system/push-config.zod.ts" />
<Card href="/docs/references/system/registry-config" title="Registry Config" description="Source: packages/spec/src/system/registry-config.zod.ts" />
<Card href="/docs/references/system/search-engine" title="Search Engine" description="Source: packages/spec/src/system/search-engine.zod.ts" />
<Card href="/docs/references/system/security-context" title="Security Context" description="Source: packages/spec/src/system/security-context.zod.ts" />
Expand Down
1 change: 1 addition & 0 deletions content/docs/references/system/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"demo-staff",
"dev-login",
"fate-supplement",
"push-config",
"sms-config",
"stack-server"
]
Expand Down
Loading
Loading