From 95a053d6bb3b38982e9f2e0e0275e355a757692a Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 28 Apr 2026 11:17:07 +0000 Subject: [PATCH] feat: add platform capability contracts --- test/test.node.ts | 3 + ts/index.ts | 2 + ts/platform/ai.ts | 23 ++++++++ ts/platform/backup.ts | 10 ++++ ts/platform/database.ts | 8 +++ ts/platform/email.ts | 73 +++++++++++++++++++++++ ts/platform/index.ts | 27 +++++++++ ts/platform/letter.ts | 26 ++++++++ ts/platform/logging.ts | 5 ++ ts/platform/objectstorage.ts | 6 ++ ts/platform/pushnotification.ts | 18 ++++++ ts/platform/sip.ts | 6 ++ ts/platform/sms.ts | 34 +++++++++++ ts/platform/types.ts | 82 ++++++++++++++++++++++++++ ts/platformservice/aibridge.ts | 4 +- ts/platformservice/letter.ts | 4 +- ts/platformservice/mta.ts | 5 ++ ts/platformservice/pushnotification.ts | 4 +- ts/platformservice/sms.ts | 3 + 19 files changed, 340 insertions(+), 3 deletions(-) create mode 100644 ts/platform/ai.ts create mode 100644 ts/platform/backup.ts create mode 100644 ts/platform/database.ts create mode 100644 ts/platform/email.ts create mode 100644 ts/platform/index.ts create mode 100644 ts/platform/letter.ts create mode 100644 ts/platform/logging.ts create mode 100644 ts/platform/objectstorage.ts create mode 100644 ts/platform/pushnotification.ts create mode 100644 ts/platform/sip.ts create mode 100644 ts/platform/sms.ts create mode 100644 ts/platform/types.ts diff --git a/test/test.node.ts b/test/test.node.ts index 4e732db..5a9c5f6 100644 --- a/test/test.node.ts +++ b/test/test.node.ts @@ -8,6 +8,9 @@ tap.test('exports public namespaces', async () => { if (!interfaces.requests) { throw new Error('Missing requests namespace'); } + if (!interfaces.platform) { + throw new Error('Missing platform namespace'); + } if (!interfaces.platformservice) { throw new Error('Missing platformservice namespace'); } diff --git a/ts/index.ts b/ts/index.ts index e992c34..f7f27bd 100644 --- a/ts/index.ts +++ b/ts/index.ts @@ -1,9 +1,11 @@ import * as data from './data/index.js'; +import * as platform from './platform/index.js'; import * as platformservice from './platformservice/index.js'; import * as requests from './requests/index.js'; export { data, + platform, platformservice, requests } diff --git a/ts/platform/ai.ts b/ts/platform/ai.ts new file mode 100644 index 0000000..f5c92ed --- /dev/null +++ b/ts/platform/ai.ts @@ -0,0 +1,23 @@ +import * as plugins from '../plugins.js'; + +export interface IChat { + systemMessage: string; + messages: { + role: 'assistant' | 'user'; + content: string; + }[]; +} + +export interface IReq_Chat extends plugins.typedrequestInterfaces.implementsTR< + plugins.typedrequestInterfaces.ITypedRequest, + IReq_Chat +> { + method: 'chat'; + request: { + chat: IChat; + }; + response: { + chat: IChat; + latestMessage: string; + }; +} diff --git a/ts/platform/backup.ts b/ts/platform/backup.ts new file mode 100644 index 0000000..4d5a9f3 --- /dev/null +++ b/ts/platform/backup.ts @@ -0,0 +1,10 @@ +export type TPlatformBackupTarget = 'volume' | 'database' | 'bucket'; + +export interface IPlatformBackupBindingConfig { + targets: Array<{ + type: TPlatformBackupTarget; + name: string; + }>; + schedule: string; + retentionDays?: number; +} diff --git a/ts/platform/database.ts b/ts/platform/database.ts new file mode 100644 index 0000000..00b8f87 --- /dev/null +++ b/ts/platform/database.ts @@ -0,0 +1,8 @@ +export type TPlatformDatabaseEngine = 'postgres' | 'mongodb' | 'mysql' | 'redis'; + +export interface IPlatformDatabaseBindingConfig { + engine: TPlatformDatabaseEngine; + databaseName?: string; + version?: string; + extensions?: string[]; +} diff --git a/ts/platform/email.ts b/ts/platform/email.ts new file mode 100644 index 0000000..806b507 --- /dev/null +++ b/ts/platform/email.ts @@ -0,0 +1,73 @@ +import * as plugins from '../plugins.js'; + +export type TTemplates = 'default' | 'linkaction' | 'notification'; + +export interface IReq_SendEmail extends plugins.typedrequestInterfaces.implementsTR< + plugins.typedrequestInterfaces.ITypedRequest, + IReq_SendEmail +> { + method: 'sendEmail'; + request: { + title: string; + from: string; + to: string; + body: string; + attachments?: Array<{ + name: string; + binaryAttachmentString: string; + }>; + }; + response: { + responseId: string; + }; +} + +export interface IReq_RegisterRecipient extends plugins.typedrequestInterfaces.implementsTR< + plugins.typedrequestInterfaces.ITypedRequest, + IReq_RegisterRecipient +> { + method: 'registerRecipient'; + request: { + emailAddress: string; + }; + response: { + status: 'ok' | 'not ok'; + }; +} + +export interface IReq_CheckEmailStatus extends plugins.typedrequestInterfaces.implementsTR< + plugins.typedrequestInterfaces.ITypedRequest, + IReq_CheckEmailStatus +> { + method: 'checkEmailStatus'; + request: { + emailId: string; + }; + response: { + status: string; + details?: { message: string }; + }; +} + +export interface IReq_GetEmailStats extends plugins.typedrequestInterfaces.implementsTR< + plugins.typedrequestInterfaces.ITypedRequest, + IReq_GetEmailStats +> { + method: 'getEmailStats'; + request: { + jwt: string; + }; + response: { + totalEmailsSent: number; + totalEmailsDelivered: number; + totalEmailsBounced: number; + averageDeliveryTimeMs: number; + lastUpdated: string; + }; +} + +export type IReq_GetEMailStats = IReq_GetEmailStats; +export type IRequest_SendEmail = IReq_SendEmail; +export type IRequest_RegisterRecipient = IReq_RegisterRecipient; +export type IRequest_CheckEmailStatus = IReq_CheckEmailStatus; +export type IRequest_GetEMailStats = IReq_GetEmailStats; diff --git a/ts/platform/index.ts b/ts/platform/index.ts new file mode 100644 index 0000000..a7788c1 --- /dev/null +++ b/ts/platform/index.ts @@ -0,0 +1,27 @@ +import * as ai from './ai.js'; +import * as backup from './backup.js'; +import * as database from './database.js'; +import * as email from './email.js'; +import * as letter from './letter.js'; +import * as logging from './logging.js'; +import * as objectstorage from './objectstorage.js'; +import * as pushnotification from './pushnotification.js'; +import * as sip from './sip.js'; +import * as sms from './sms.js'; +import * as types from './types.js'; + +export { + ai, + backup, + database, + email, + letter, + logging, + objectstorage, + pushnotification, + sip, + sms, + types, +}; + +export * from './types.js'; diff --git a/ts/platform/letter.ts b/ts/platform/letter.ts new file mode 100644 index 0000000..5425b70 --- /dev/null +++ b/ts/platform/letter.ts @@ -0,0 +1,26 @@ +import * as plugins from '../plugins.js'; + +export interface IReq_SendLetter extends plugins.typedrequestInterfaces.implementsTR< + plugins.typedrequestInterfaces.ITypedRequest, + IReq_SendLetter +> { + method: 'sendLetter'; + request: { + description: string; + needsCover: boolean; + title?: string; + from?: plugins.tsclass.business.IAddress; + to?: plugins.tsclass.business.IAddress; + coverBody?: string; + service: 'Einschreiben'[]; + pdfAttachments?: Array<{ + name: string; + binaryAttachmentString: string; + }>; + }; + response: { + processId: string; + }; +} + +export type IRequest_SendLetter = IReq_SendLetter; diff --git a/ts/platform/logging.ts b/ts/platform/logging.ts new file mode 100644 index 0000000..8bf6d22 --- /dev/null +++ b/ts/platform/logging.ts @@ -0,0 +1,5 @@ +export interface IPlatformLoggingBindingConfig { + streams?: string[]; + retentionDays?: number; + exposeQueryEndpoint?: boolean; +} diff --git a/ts/platform/objectstorage.ts b/ts/platform/objectstorage.ts new file mode 100644 index 0000000..bc35903 --- /dev/null +++ b/ts/platform/objectstorage.ts @@ -0,0 +1,6 @@ +export interface IPlatformObjectStorageBindingConfig { + bucketName?: string; + region?: string; + publicRead?: boolean; + versioning?: boolean; +} diff --git a/ts/platform/pushnotification.ts b/ts/platform/pushnotification.ts new file mode 100644 index 0000000..b14ab15 --- /dev/null +++ b/ts/platform/pushnotification.ts @@ -0,0 +1,18 @@ +import * as plugins from '../plugins.js'; + +export interface IReq_SendPushNotification extends plugins.typedrequestInterfaces.implementsTR< + plugins.typedrequestInterfaces.ITypedRequest, + IReq_SendPushNotification +> { + method: 'sendPushNotification'; + request: { + deviceToken: string; + message: string; + }; + response: { + ok: boolean; + status: string; + }; +} + +export type IRequest_SendPushNotification = IReq_SendPushNotification; diff --git a/ts/platform/sip.ts b/ts/platform/sip.ts new file mode 100644 index 0000000..58621f9 --- /dev/null +++ b/ts/platform/sip.ts @@ -0,0 +1,6 @@ +export interface IPlatformSipBindingConfig { + trunkId?: string; + extension?: string; + inboundNumbers?: string[]; + outboundCallerId?: string; +} diff --git a/ts/platform/sms.ts b/ts/platform/sms.ts new file mode 100644 index 0000000..6ccea6a --- /dev/null +++ b/ts/platform/sms.ts @@ -0,0 +1,34 @@ +import * as plugins from '../plugins.js'; + +export interface IReq_SendSms extends plugins.typedrequestInterfaces.implementsTR< + plugins.typedrequestInterfaces.ITypedRequest, + IReq_SendSms +> { + method: 'sendSms'; + request: { + toNumber: number; + fromName: string; + messageText: string; + }; + response: { + status: 'ok' | 'not ok'; + }; +} + +export interface IReq_SendVerificationCode extends plugins.typedrequestInterfaces.implementsTR< + plugins.typedrequestInterfaces.ITypedRequest, + IReq_SendVerificationCode +> { + method: 'sendVerificationCode'; + request: { + toNumber: number; + fromName: string; + }; + response: { + status: 'ok' | 'not ok'; + verificationCode: string; + }; +} + +export type IRequest_SendSms = IReq_SendSms; +export type IRequest_SendVerificationCode = IReq_SendVerificationCode; diff --git a/ts/platform/types.ts b/ts/platform/types.ts new file mode 100644 index 0000000..5d66d25 --- /dev/null +++ b/ts/platform/types.ts @@ -0,0 +1,82 @@ +export type TPlatformCapability = + | 'email' + | 'sms' + | 'pushnotification' + | 'letter' + | 'ai' + | 'database' + | 'objectstorage' + | 'logging' + | 'backup' + | 'sip'; + +export type TPlatformAccessMode = 'rpc' | 'binding' | 'sidecar' | 'internal'; +export type TPlatformBindingStatus = 'requested' | 'provisioning' | 'ready' | 'degraded' | 'failed' | 'disabled'; +export type TPlatformDesiredState = 'enabled' | 'disabled'; +export type TPlatformEndpointProtocol = + | 'typedrequest' + | 'http' + | 'tcp' + | 'udp' + | 'smtp' + | 's3' + | 'postgres' + | 'mongodb' + | 'sip'; + +export type TPlatformConfigValue = + | string + | number + | boolean + | null + | TPlatformConfigValue[] + | { [key: string]: TPlatformConfigValue }; + +export interface IPlatformCapability { + id: TPlatformCapability; + title: string; + description?: string; + accessMode: TPlatformAccessMode; + defaultProviderType?: string; +} + +export interface IPlatformProviderConfig { + id: string; + capability: TPlatformCapability; + providerType: string; + name: string; + enabled: boolean; + config?: { [key: string]: TPlatformConfigValue }; + secretBundleId?: string; +} + +export interface IPlatformCredentialRef { + secretBundleId?: string; + secretGroupIds?: string[]; + dockerSecretName?: string; + env?: { [key: string]: string }; +} + +export interface IPlatformServiceEndpoint { + name: string; + capability: TPlatformCapability; + protocol: TPlatformEndpointProtocol; + internalUrl?: string; + externalUrl?: string; + networkAlias?: string; + port?: number; +} + +export interface IPlatformBinding { + id: string; + serviceId: string; + capability: TPlatformCapability; + desiredState: TPlatformDesiredState; + status: TPlatformBindingStatus; + providerConfigId?: string; + config?: { [key: string]: TPlatformConfigValue }; + endpoints?: IPlatformServiceEndpoint[]; + credentials?: IPlatformCredentialRef[]; + createdAt?: number; + updatedAt?: number; +} diff --git a/ts/platformservice/aibridge.ts b/ts/platformservice/aibridge.ts index 54e51dc..3738a64 100644 --- a/ts/platformservice/aibridge.ts +++ b/ts/platformservice/aibridge.ts @@ -20,4 +20,6 @@ export interface IReq_Chat extends plugins.typedrequestInterfaces.implementsTR< chat: IChat; latestMessage: string; } -} \ No newline at end of file +} + +export type IRequest_Chat = IReq_Chat; diff --git a/ts/platformservice/letter.ts b/ts/platformservice/letter.ts index 9d94127..4f2d25d 100644 --- a/ts/platformservice/letter.ts +++ b/ts/platformservice/letter.ts @@ -31,4 +31,6 @@ export interface IRequest_SendLetter extends plugins.typedrequestInterfaces.impl */ processId: string; }; -} \ No newline at end of file +} + +export type IReq_SendLetter = IRequest_SendLetter; diff --git a/ts/platformservice/mta.ts b/ts/platformservice/mta.ts index 2881cb7..0cc4426 100644 --- a/ts/platformservice/mta.ts +++ b/ts/platformservice/mta.ts @@ -68,3 +68,8 @@ export interface IReq_GetEMailStats extends plugins.typedrequestInterfaces.imple lastUpdated: string; }; } + +export type IRequest_SendEmail = IReq_SendEmail; +export type IRequest_RegisterRecipient = IReq_RegisterRecipient; +export type IRequest_CheckEmailStatus = IReq_CheckEmailStatus; +export type IRequest_GetEMailStats = IReq_GetEMailStats; diff --git a/ts/platformservice/pushnotification.ts b/ts/platformservice/pushnotification.ts index b99cff1..766b718 100644 --- a/ts/platformservice/pushnotification.ts +++ b/ts/platformservice/pushnotification.ts @@ -13,4 +13,6 @@ export interface IRequest_SendPushNotification extends plugins.typedrequestInter ok: boolean; status: string; } -} \ No newline at end of file +} + +export type IReq_SendPushNotification = IRequest_SendPushNotification; diff --git a/ts/platformservice/sms.ts b/ts/platformservice/sms.ts index 9150c99..3f172a1 100644 --- a/ts/platformservice/sms.ts +++ b/ts/platformservice/sms.ts @@ -31,3 +31,6 @@ export interface IRequest_SendSms verificationCode: string; } } + +export type IReq_SendSms = IRequest_SendSms; +export type IReq_SendVerificationCode = IRequest_SendVerificationCode;