@mestra-dev/contract 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,10 +34,10 @@ Always use `import type` so the bundler never pulls server code.
34
34
 
35
35
  ## Build (maintainers)
36
36
 
37
- Requires local `services/auth` and `services/utils` sources plus auth `node_modules` for type resolution. Those packages are **not** published with this contract.
37
+ Requires local `services/core` and `services/utils` sources plus core `node_modules` for type resolution. Those packages are **not** published with this contract.
38
38
 
39
39
  ```bash
40
- cd services/contract
40
+ cd services/hc
41
41
  bun install
42
42
  bun run build
43
43
  ```
@@ -47,7 +47,7 @@ Output: `dist/index.d.ts` (self-contained; depends on `hono` types only).
47
47
  ## Publish to npmjs
48
48
 
49
49
  ```bash
50
- cd services/contract
50
+ cd services/hc
51
51
  bun run build
52
52
  bun pm version patch # or: minor / major
53
53
  bun publish --access public
package/dist/index.d.ts CHANGED
@@ -20,8 +20,8 @@ declare const routes: import("hono/hono-base").HonoBase<{
20
20
  readonly openapi: "3.0.3";
21
21
  readonly info: {
22
22
  readonly title: "Auth Service API";
23
- readonly version: "1.5.1";
24
- readonly description: "OpenAPI specification for the Auth, Integrations, Workspace, Tasks, Templates, Tags, Comments, Assignees, Chat, Events, Billings, and Files endpoints exposed by the k3-core platform.";
23
+ readonly version: "1.5.3";
24
+ readonly description: "OpenAPI specification for the Auth, Integrations, Workspace, Tasks, Templates, Tags, Comments, Assignees, Chat, Events, Billings, Files, and Notifications endpoints exposed by the k3-core platform.";
25
25
  };
26
26
  readonly servers: readonly [
27
27
  {
@@ -96,7 +96,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
96
96
  },
97
97
  {
98
98
  readonly name: "Notifications";
99
- readonly description: "Cursor-based incremental notification sync for the authenticated user. Clients store the returned cursor and pass it on the next call to receive only notifications created or updated since.";
99
+ readonly description: "Cursor-based incremental notification sync, plus mark-read / archive (single or all). Clients store the sync cursor and pass it on the next call; mutations bump updated_at so changes propagate via sync.";
100
100
  }
101
101
  ];
102
102
  readonly components: {
@@ -223,6 +223,17 @@ declare const routes: import("hono/hono-base").HonoBase<{
223
223
  };
224
224
  };
225
225
  };
226
+ readonly NotificationType: {
227
+ readonly type: "string";
228
+ readonly enum: readonly [
229
+ "info",
230
+ "warning",
231
+ "success",
232
+ "failure"
233
+ ];
234
+ readonly default: "info";
235
+ readonly description: "Notification severity (`notification_type` Postgres enum).";
236
+ };
226
237
  readonly Notification: {
227
238
  readonly type: "object";
228
239
  readonly required: readonly [
@@ -258,9 +269,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
258
269
  readonly maxLength: 256;
259
270
  };
260
271
  readonly type: {
261
- readonly type: "string";
262
- readonly maxLength: 50;
263
- readonly description: "Notification category (application-defined).";
272
+ readonly $ref: "#/components/schemas/NotificationType";
264
273
  };
265
274
  readonly read: {
266
275
  readonly type: "boolean";
@@ -364,10 +373,30 @@ declare const routes: import("hono/hono-base").HonoBase<{
364
373
  readonly description: "Human readable error message.";
365
374
  };
366
375
  readonly error: {
367
- readonly type: "object";
368
376
  readonly nullable: true;
369
- readonly description: "Validation error details.";
370
- readonly additionalProperties: true;
377
+ readonly description: "String message or Zod validation details, depending on the failure.";
378
+ readonly oneOf: readonly [
379
+ {
380
+ readonly type: "string";
381
+ },
382
+ {
383
+ readonly type: "object";
384
+ readonly additionalProperties: true;
385
+ }
386
+ ];
387
+ };
388
+ };
389
+ };
390
+ readonly NotificationIdRequest: {
391
+ readonly type: "object";
392
+ readonly required: readonly [
393
+ "notificationId"
394
+ ];
395
+ readonly properties: {
396
+ readonly notificationId: {
397
+ readonly type: "string";
398
+ readonly format: "uuid";
399
+ readonly description: "Notification identifier belonging to the authenticated user.";
371
400
  };
372
401
  };
373
402
  };
@@ -3072,7 +3101,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
3072
3101
  };
3073
3102
  };
3074
3103
  readonly 400: {
3075
- readonly description: "Missing code or token verification failure.";
3104
+ readonly description: "Missing `code`, or Google token exchange failed. `error` is a string such as Google's `error_description` (e.g. missing client_secret / invalid_request).";
3076
3105
  readonly content: {
3077
3106
  readonly "application/json": {
3078
3107
  readonly schema: {
@@ -3082,7 +3111,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
3082
3111
  };
3083
3112
  };
3084
3113
  readonly 500: {
3085
- readonly description: "Failed to issue tokens.";
3114
+ readonly description: "`GOOGLE_CLIENT_SECRET is not configured`, or failed to issue session tokens after a successful Google exchange.";
3086
3115
  readonly content: {
3087
3116
  readonly "application/json": {
3088
3117
  readonly schema: {
@@ -3186,7 +3215,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
3186
3215
  };
3187
3216
  };
3188
3217
  readonly 400: {
3189
- readonly description: "Missing query parameters, invalid state, or expired verifier.";
3218
+ readonly description: "`Missing code or state`, `Invalid state`, `Invalid or expired state`, or Google token exchange failure (`error` string from Google / OAuth helper).";
3190
3219
  readonly content: {
3191
3220
  readonly "application/json": {
3192
3221
  readonly schema: {
@@ -3212,7 +3241,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
3212
3241
  };
3213
3242
  };
3214
3243
  readonly 500: {
3215
- readonly description: "Calendar creation, watch registration, or persistence failed (e.g. invalid watch response).";
3244
+ readonly description: "`GOOGLE_CLIENT_SECRET is not configured`, or calendar creation / watch registration / persistence failed (e.g. invalid watch response).";
3216
3245
  readonly content: {
3217
3246
  readonly "application/json": {
3218
3247
  readonly schema: {
@@ -4574,7 +4603,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
4574
4603
  "Workspace"
4575
4604
  ];
4576
4605
  readonly summary: "Create workspace invitation";
4577
- readonly description: "Creates an invitation for a user to join a workspace with specified resources and role. Requires write access to crm::general resource.";
4606
+ readonly description: "Creates an invitation for an email to join a workspace with specified resources and role. Works for emails that are not yet registered: a pending `invitations` row is stored and a collaborator is materialized when that email creates an account (OTP signup or OAuth). If the user already exists, a pending collaborator with policies is created immediately (same accept flow as before). Always returns the invite `token` for the frontend to share. Requires write access to crm::general. Pending invitations for unknown emails count toward the workspace collaborator seat limit.";
4578
4607
  readonly security: readonly [
4579
4608
  never
4580
4609
  ];
@@ -4594,7 +4623,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
4594
4623
  readonly email: {
4595
4624
  readonly type: "string";
4596
4625
  readonly format: "email";
4597
- readonly description: "Email of the user to invite.";
4626
+ readonly description: "Email to invite (registered or not).";
4598
4627
  };
4599
4628
  readonly workspace: {
4600
4629
  readonly type: "string";
@@ -4624,13 +4653,29 @@ declare const routes: import("hono/hono-base").HonoBase<{
4624
4653
  readonly content: {
4625
4654
  readonly "application/json": {
4626
4655
  readonly schema: {
4627
- readonly $ref: "#/components/schemas/SimpleSuccess";
4656
+ readonly type: "object";
4657
+ readonly required: readonly [
4658
+ "success",
4659
+ "token"
4660
+ ];
4661
+ readonly properties: {
4662
+ readonly success: {
4663
+ readonly type: "boolean";
4664
+ readonly const: true;
4665
+ };
4666
+ readonly token: {
4667
+ readonly type: "string";
4668
+ readonly minLength: 64;
4669
+ readonly maxLength: 64;
4670
+ readonly description: "Invite token for GET /workspace/invite/{workspace}/{token} after the invitee authenticates.";
4671
+ };
4672
+ };
4628
4673
  };
4629
4674
  };
4630
4675
  };
4631
4676
  };
4632
4677
  readonly 400: {
4633
- readonly description: "Invalid request payload, max collaborators reached, user not found, user is already a collaborator, or resource not found.";
4678
+ readonly description: "Invalid request payload, max collaborators reached, invitation already pending, user is already a collaborator, or resource not found.";
4634
4679
  readonly content: {
4635
4680
  readonly "application/json": {
4636
4681
  readonly schema: {
@@ -5128,13 +5173,13 @@ declare const routes: import("hono/hono-base").HonoBase<{
5128
5173
  };
5129
5174
  };
5130
5175
  };
5131
- readonly "/workspace/leave/{workspace}/{collaboratorId}": {
5176
+ readonly "/workspace/leave/{workspace}": {
5132
5177
  readonly get: {
5133
5178
  readonly tags: readonly [
5134
5179
  "Workspace"
5135
5180
  ];
5136
- readonly summary: "Remove a collaborator from a workspace";
5137
- readonly description: "Removes the specified collaborator from the workspace. The authenticated workspace owner cannot use this endpoint; they must delete the workspace instead.";
5181
+ readonly summary: "Leave a workspace";
5182
+ readonly description: "Removes the authenticated user from the workspace. Workspace owners cannot leave; they must delete the workspace instead (`Owner cannot leave the workspace, Delete the workspace instead`).";
5138
5183
  readonly security: readonly [
5139
5184
  never
5140
5185
  ];
@@ -5148,21 +5193,11 @@ declare const routes: import("hono/hono-base").HonoBase<{
5148
5193
  readonly type: "string";
5149
5194
  readonly format: "uuid";
5150
5195
  };
5151
- },
5152
- {
5153
- readonly name: "collaboratorId";
5154
- readonly in: "path";
5155
- readonly required: true;
5156
- readonly description: "Collaborator identifier to remove.";
5157
- readonly schema: {
5158
- readonly type: "string";
5159
- readonly format: "uuid";
5160
- };
5161
5196
  }
5162
5197
  ];
5163
5198
  readonly responses: {
5164
5199
  readonly 200: {
5165
- readonly description: "Collaborator removed successfully.";
5200
+ readonly description: "Left the workspace successfully.";
5166
5201
  readonly content: {
5167
5202
  readonly "application/json": {
5168
5203
  readonly schema: {
@@ -5172,7 +5207,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
5172
5207
  };
5173
5208
  };
5174
5209
  readonly 400: {
5175
- readonly description: "Invalid workspace id, user is not a collaborator, or user is the workspace owner.";
5210
+ readonly description: "Invalid workspace id, caller is not a collaborator, or caller is the workspace owner.";
5176
5211
  readonly content: {
5177
5212
  readonly "application/json": {
5178
5213
  readonly schema: {
@@ -10083,6 +10118,186 @@ declare const routes: import("hono/hono-base").HonoBase<{
10083
10118
  };
10084
10119
  };
10085
10120
  };
10121
+ readonly "/notifications/read": {
10122
+ readonly post: {
10123
+ readonly tags: readonly [
10124
+ "Notifications"
10125
+ ];
10126
+ readonly summary: "Mark a notification as read";
10127
+ readonly description: "Sets `read=true` and bumps `updated_at` for a notification owned by the authenticated user so the change is picked up by `/notifications/sync`. Requires a valid access token (no workspace policy check).";
10128
+ readonly security: readonly [
10129
+ never
10130
+ ];
10131
+ readonly requestBody: {
10132
+ readonly required: true;
10133
+ readonly content: {
10134
+ readonly "application/json": {
10135
+ readonly schema: {
10136
+ readonly $ref: "#/components/schemas/NotificationIdRequest";
10137
+ };
10138
+ };
10139
+ };
10140
+ };
10141
+ readonly responses: {
10142
+ readonly 200: {
10143
+ readonly description: "Notification marked as read.";
10144
+ readonly content: {
10145
+ readonly "application/json": {
10146
+ readonly schema: {
10147
+ readonly $ref: "#/components/schemas/SimpleSuccess";
10148
+ };
10149
+ };
10150
+ };
10151
+ };
10152
+ readonly 400: {
10153
+ readonly description: "Invalid request payload.";
10154
+ readonly content: {
10155
+ readonly "application/json": {
10156
+ readonly schema: {
10157
+ readonly $ref: "#/components/schemas/ErrorResponse";
10158
+ };
10159
+ };
10160
+ };
10161
+ };
10162
+ readonly 401: {
10163
+ readonly description: "Unauthorized - Missing or invalid access token.";
10164
+ };
10165
+ readonly 403: {
10166
+ readonly description: "Forbidden - Token issuer is not 'access'.";
10167
+ };
10168
+ readonly 404: {
10169
+ readonly description: "Notification not found for this user.";
10170
+ readonly content: {
10171
+ readonly "application/json": {
10172
+ readonly schema: {
10173
+ readonly $ref: "#/components/schemas/ErrorResponse";
10174
+ };
10175
+ };
10176
+ };
10177
+ };
10178
+ };
10179
+ };
10180
+ };
10181
+ readonly "/notifications/read-all": {
10182
+ readonly post: {
10183
+ readonly tags: readonly [
10184
+ "Notifications"
10185
+ ];
10186
+ readonly summary: "Mark all notifications as read";
10187
+ readonly description: "Sets `read=true` and bumps `updated_at` on every unread notification owned by the authenticated user so the changes are picked up by `/notifications/sync`. Requires a valid access token (no workspace policy check).";
10188
+ readonly security: readonly [
10189
+ never
10190
+ ];
10191
+ readonly responses: {
10192
+ readonly 200: {
10193
+ readonly description: "All unread notifications marked as read.";
10194
+ readonly content: {
10195
+ readonly "application/json": {
10196
+ readonly schema: {
10197
+ readonly $ref: "#/components/schemas/SimpleSuccess";
10198
+ };
10199
+ };
10200
+ };
10201
+ };
10202
+ readonly 401: {
10203
+ readonly description: "Unauthorized - Missing or invalid access token.";
10204
+ };
10205
+ readonly 403: {
10206
+ readonly description: "Forbidden - Token issuer is not 'access'.";
10207
+ };
10208
+ };
10209
+ };
10210
+ };
10211
+ readonly "/notifications/archive": {
10212
+ readonly post: {
10213
+ readonly tags: readonly [
10214
+ "Notifications"
10215
+ ];
10216
+ readonly summary: "Archive a notification";
10217
+ readonly description: "Sets `archive=true` and bumps `updated_at` for a notification owned by the authenticated user so the change is picked up by `/notifications/sync`. Requires a valid access token (no workspace policy check).";
10218
+ readonly security: readonly [
10219
+ never
10220
+ ];
10221
+ readonly requestBody: {
10222
+ readonly required: true;
10223
+ readonly content: {
10224
+ readonly "application/json": {
10225
+ readonly schema: {
10226
+ readonly $ref: "#/components/schemas/NotificationIdRequest";
10227
+ };
10228
+ };
10229
+ };
10230
+ };
10231
+ readonly responses: {
10232
+ readonly 200: {
10233
+ readonly description: "Notification archived.";
10234
+ readonly content: {
10235
+ readonly "application/json": {
10236
+ readonly schema: {
10237
+ readonly $ref: "#/components/schemas/SimpleSuccess";
10238
+ };
10239
+ };
10240
+ };
10241
+ };
10242
+ readonly 400: {
10243
+ readonly description: "Invalid request payload.";
10244
+ readonly content: {
10245
+ readonly "application/json": {
10246
+ readonly schema: {
10247
+ readonly $ref: "#/components/schemas/ErrorResponse";
10248
+ };
10249
+ };
10250
+ };
10251
+ };
10252
+ readonly 401: {
10253
+ readonly description: "Unauthorized - Missing or invalid access token.";
10254
+ };
10255
+ readonly 403: {
10256
+ readonly description: "Forbidden - Token issuer is not 'access'.";
10257
+ };
10258
+ readonly 404: {
10259
+ readonly description: "Notification not found for this user.";
10260
+ readonly content: {
10261
+ readonly "application/json": {
10262
+ readonly schema: {
10263
+ readonly $ref: "#/components/schemas/ErrorResponse";
10264
+ };
10265
+ };
10266
+ };
10267
+ };
10268
+ };
10269
+ };
10270
+ };
10271
+ readonly "/notifications/archive-all": {
10272
+ readonly post: {
10273
+ readonly tags: readonly [
10274
+ "Notifications"
10275
+ ];
10276
+ readonly summary: "Archive all notifications";
10277
+ readonly description: "Sets `archive=true` and bumps `updated_at` on every unarchived notification owned by the authenticated user so the changes are picked up by `/notifications/sync`. Requires a valid access token (no workspace policy check).";
10278
+ readonly security: readonly [
10279
+ never
10280
+ ];
10281
+ readonly responses: {
10282
+ readonly 200: {
10283
+ readonly description: "All unarchived notifications archived.";
10284
+ readonly content: {
10285
+ readonly "application/json": {
10286
+ readonly schema: {
10287
+ readonly $ref: "#/components/schemas/SimpleSuccess";
10288
+ };
10289
+ };
10290
+ };
10291
+ };
10292
+ readonly 401: {
10293
+ readonly description: "Unauthorized - Missing or invalid access token.";
10294
+ };
10295
+ readonly 403: {
10296
+ readonly description: "Forbidden - Token issuer is not 'access'.";
10297
+ };
10298
+ };
10299
+ };
10300
+ };
10086
10301
  readonly "/chat/start": {
10087
10302
  readonly post: {
10088
10303
  readonly tags: readonly [
@@ -10622,6 +10837,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
10622
10837
  input: {};
10623
10838
  output: {
10624
10839
  success: true;
10840
+ token: string;
10625
10841
  };
10626
10842
  outputFormat: "json";
10627
10843
  status: 201;
@@ -12271,6 +12487,14 @@ declare const routes: import("hono/hono-base").HonoBase<{
12271
12487
  };
12272
12488
  outputFormat: "json";
12273
12489
  status: 400;
12490
+ } | {
12491
+ input: {};
12492
+ output: {
12493
+ success: false;
12494
+ error: string;
12495
+ };
12496
+ outputFormat: "json";
12497
+ status: 500;
12274
12498
  } | {
12275
12499
  input: {};
12276
12500
  output: {
@@ -15763,7 +15987,6 @@ declare const routes: import("hono/hono-base").HonoBase<{
15763
15987
  output: {
15764
15988
  success: false;
15765
15989
  error: string;
15766
- details: string;
15767
15990
  };
15768
15991
  outputFormat: "json";
15769
15992
  status: 500;
@@ -15845,7 +16068,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
15845
16068
  workspaceId: string;
15846
16069
  title: string;
15847
16070
  message: string;
15848
- type: string;
16071
+ type: "success" | "info" | "warning" | "failure";
15849
16072
  read: boolean;
15850
16073
  archive: boolean;
15851
16074
  }[];
@@ -15856,5 +16079,81 @@ declare const routes: import("hono/hono-base").HonoBase<{
15856
16079
  status: 200;
15857
16080
  };
15858
16081
  };
16082
+ } & {
16083
+ "/read": {
16084
+ $post: {
16085
+ input: {};
16086
+ output: {
16087
+ success: false;
16088
+ error: never;
16089
+ };
16090
+ outputFormat: "json";
16091
+ status: 400;
16092
+ } | {
16093
+ input: {};
16094
+ output: {
16095
+ success: false;
16096
+ error: string;
16097
+ };
16098
+ outputFormat: "json";
16099
+ status: 404;
16100
+ } | {
16101
+ input: {};
16102
+ output: {
16103
+ success: true;
16104
+ };
16105
+ outputFormat: "json";
16106
+ status: 200;
16107
+ };
16108
+ };
16109
+ } & {
16110
+ "/read-all": {
16111
+ $post: {
16112
+ input: {};
16113
+ output: {
16114
+ success: true;
16115
+ };
16116
+ outputFormat: "json";
16117
+ status: 200;
16118
+ };
16119
+ };
16120
+ } & {
16121
+ "/archive": {
16122
+ $post: {
16123
+ input: {};
16124
+ output: {
16125
+ success: false;
16126
+ error: never;
16127
+ };
16128
+ outputFormat: "json";
16129
+ status: 400;
16130
+ } | {
16131
+ input: {};
16132
+ output: {
16133
+ success: false;
16134
+ error: string;
16135
+ };
16136
+ outputFormat: "json";
16137
+ status: 404;
16138
+ } | {
16139
+ input: {};
16140
+ output: {
16141
+ success: true;
16142
+ };
16143
+ outputFormat: "json";
16144
+ status: 200;
16145
+ };
16146
+ };
16147
+ } & {
16148
+ "/archive-all": {
16149
+ $post: {
16150
+ input: {};
16151
+ output: {
16152
+ success: true;
16153
+ };
16154
+ outputFormat: "json";
16155
+ status: 200;
16156
+ };
16157
+ };
15859
16158
  }, "/notifications">, "/", "/">;
15860
16159
  export type AppType = typeof routes;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mestra-dev/contract",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "description": "Types-only Hono AppType contract for the Mestra auth API",
5
5
  "type": "module",
6
6
  "sideEffects": false,