@mestra-dev/contract 0.0.9 → 0.0.11

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.
Files changed (2) hide show
  1. package/dist/index.d.ts +694 -110
  2. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -88,11 +88,15 @@ declare const routes: import("hono/hono-base").HonoBase<{
88
88
  },
89
89
  {
90
90
  readonly name: "Files";
91
- readonly description: "S3 file upload (presigned POST), profile picture upload/confirm/delete, comment attachment upload, list task comment files with download URLs, folder create/delete, list (includes pin metadata), pin/unpin, download, and file delete. General uploads accept JPEG/PNG/WebP/PDF; profile pictures accept JPEG/PNG only (0.5 MB).";
91
+ readonly description: "S3 file upload (presigned POST), profile and workspace picture upload/confirm/delete, comment attachment upload, list task comment files with download URLs, folder create/delete, list (includes pin metadata), pin/unpin, download, and file delete. General uploads accept JPEG/PNG/WebP/PDF; profile/workspace pictures accept JPEG/PNG only (0.5 MB).";
92
92
  },
93
93
  {
94
94
  readonly name: "Chat";
95
95
  readonly description: "Matrix (Synapse) chat session bootstrap and chat-tenant collaborator listing; owners get an `owner_` username prefix; caches Matrix access tokens. Requires workspace access and crm::chats read.";
96
+ },
97
+ {
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.";
96
100
  }
97
101
  ];
98
102
  readonly components: {
@@ -219,6 +223,110 @@ declare const routes: import("hono/hono-base").HonoBase<{
219
223
  };
220
224
  };
221
225
  };
226
+ readonly Notification: {
227
+ readonly type: "object";
228
+ readonly required: readonly [
229
+ "id",
230
+ "userId",
231
+ "workspaceId",
232
+ "title",
233
+ "message",
234
+ "type",
235
+ "read",
236
+ "archive",
237
+ "created_at"
238
+ ];
239
+ readonly properties: {
240
+ readonly id: {
241
+ readonly type: "string";
242
+ readonly format: "uuid";
243
+ };
244
+ readonly userId: {
245
+ readonly type: "string";
246
+ readonly format: "uuid";
247
+ };
248
+ readonly workspaceId: {
249
+ readonly type: "string";
250
+ readonly format: "uuid";
251
+ };
252
+ readonly title: {
253
+ readonly type: "string";
254
+ readonly maxLength: 256;
255
+ };
256
+ readonly message: {
257
+ readonly type: "string";
258
+ readonly maxLength: 256;
259
+ };
260
+ readonly type: {
261
+ readonly type: "string";
262
+ readonly maxLength: 50;
263
+ readonly description: "Notification category (application-defined).";
264
+ };
265
+ readonly read: {
266
+ readonly type: "boolean";
267
+ };
268
+ readonly archive: {
269
+ readonly type: "boolean";
270
+ };
271
+ readonly created_at: {
272
+ readonly type: "string";
273
+ readonly format: "date-time";
274
+ };
275
+ readonly updated_at: {
276
+ readonly type: "string";
277
+ readonly format: "date-time";
278
+ readonly nullable: true;
279
+ readonly description: "Set when the notification is marked read or archived.";
280
+ };
281
+ readonly deleted_at: {
282
+ readonly type: "string";
283
+ readonly format: "date-time";
284
+ readonly nullable: true;
285
+ };
286
+ readonly verified_at: {
287
+ readonly type: "string";
288
+ readonly format: "date-time";
289
+ readonly nullable: true;
290
+ };
291
+ readonly suspended_at: {
292
+ readonly type: "string";
293
+ readonly format: "date-time";
294
+ readonly nullable: true;
295
+ };
296
+ };
297
+ };
298
+ readonly NotificationSyncSuccess: {
299
+ readonly type: "object";
300
+ readonly required: readonly [
301
+ "success",
302
+ "notifications",
303
+ "cursor",
304
+ "hasMore"
305
+ ];
306
+ readonly properties: {
307
+ readonly success: {
308
+ readonly type: "boolean";
309
+ readonly const: true;
310
+ };
311
+ readonly notifications: {
312
+ readonly type: "array";
313
+ readonly items: {
314
+ readonly $ref: "#/components/schemas/Notification";
315
+ };
316
+ readonly description: "Notifications created or updated after the request cursor, oldest change first.";
317
+ };
318
+ readonly cursor: {
319
+ readonly type: "string";
320
+ readonly format: "date-time";
321
+ readonly nullable: true;
322
+ readonly description: "Newest change timestamp in this page. Store it and pass it as `cursor` on the next sync. Null only when no cursor was sent and no notifications exist.";
323
+ };
324
+ readonly hasMore: {
325
+ readonly type: "boolean";
326
+ readonly description: "True when more changes remain; call again immediately with the returned cursor.";
327
+ };
328
+ };
329
+ };
222
330
  readonly CreateWorkspaceSuccess: {
223
331
  readonly type: "object";
224
332
  readonly required: readonly [
@@ -715,6 +823,11 @@ declare const routes: import("hono/hono-base").HonoBase<{
715
823
  readonly category: {
716
824
  readonly $ref: "#/components/schemas/WorkspaceCategory";
717
825
  };
826
+ readonly picture: {
827
+ readonly type: "string";
828
+ readonly nullable: true;
829
+ readonly description: "Presigned workspace avatar URL (7-day expiry, refreshed periodically); empty string when unset.";
830
+ };
718
831
  readonly created_at: {
719
832
  readonly type: "string";
720
833
  readonly format: "date-time";
@@ -753,6 +866,11 @@ declare const routes: import("hono/hono-base").HonoBase<{
753
866
  readonly workspaceName: {
754
867
  readonly type: "string";
755
868
  };
869
+ readonly profilePicture: {
870
+ readonly type: "string";
871
+ readonly nullable: true;
872
+ readonly description: "Presigned workspace avatar URL from `workspaces.picture` (7-day expiry); null or empty when unset.";
873
+ };
756
874
  readonly workspaceCategory: {
757
875
  readonly $ref: "#/components/schemas/WorkspaceCategory";
758
876
  };
@@ -1235,7 +1353,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
1235
1353
  "image/jpeg",
1236
1354
  "image/png"
1237
1355
  ];
1238
- readonly description: "Allowed MIME type declared for the temporary profile-picture upload.";
1356
+ readonly description: "Allowed MIME type declared for temporary profile or workspace picture uploads.";
1239
1357
  };
1240
1358
  readonly UploadFileRequest: {
1241
1359
  readonly type: "object";
@@ -1471,6 +1589,73 @@ declare const routes: import("hono/hono-base").HonoBase<{
1471
1589
  };
1472
1590
  };
1473
1591
  };
1592
+ readonly UploadWorkspacePictureRequest: {
1593
+ readonly type: "object";
1594
+ readonly required: readonly [
1595
+ "workspace",
1596
+ "contentType"
1597
+ ];
1598
+ readonly properties: {
1599
+ readonly workspace: {
1600
+ readonly type: "string";
1601
+ readonly format: "uuid";
1602
+ readonly description: "Workspace identifier.";
1603
+ };
1604
+ readonly contentType: {
1605
+ readonly $ref: "#/components/schemas/ProfileImageContentType";
1606
+ };
1607
+ };
1608
+ };
1609
+ readonly WorkspacePictureWorkspaceRequest: {
1610
+ readonly type: "object";
1611
+ readonly required: readonly [
1612
+ "workspace"
1613
+ ];
1614
+ readonly properties: {
1615
+ readonly workspace: {
1616
+ readonly type: "string";
1617
+ readonly format: "uuid";
1618
+ readonly description: "Workspace identifier.";
1619
+ };
1620
+ };
1621
+ };
1622
+ readonly ConfirmWorkspacePictureSuccess: {
1623
+ readonly type: "object";
1624
+ readonly required: readonly [
1625
+ "success",
1626
+ "url"
1627
+ ];
1628
+ readonly properties: {
1629
+ readonly success: {
1630
+ readonly type: "boolean";
1631
+ readonly const: true;
1632
+ };
1633
+ readonly url: {
1634
+ readonly type: "string";
1635
+ readonly description: "Presigned GET URL for `profiles/workspaces/{workspace}/avatar.webp` (WebP response content type, 7-day expiry). Also saved on the workspace.";
1636
+ };
1637
+ };
1638
+ };
1639
+ readonly DeleteWorkspacePictureSuccess: {
1640
+ readonly type: "object";
1641
+ readonly required: readonly [
1642
+ "success",
1643
+ "message"
1644
+ ];
1645
+ readonly properties: {
1646
+ readonly success: {
1647
+ readonly type: "boolean";
1648
+ readonly const: true;
1649
+ };
1650
+ readonly message: {
1651
+ readonly type: "string";
1652
+ readonly enum: readonly [
1653
+ "Workspace picture deleted successfully",
1654
+ "Workspace picture already deleted"
1655
+ ];
1656
+ };
1657
+ };
1658
+ };
1474
1659
  readonly CreateFolderRequest: {
1475
1660
  readonly type: "object";
1476
1661
  readonly required: readonly [
@@ -4039,7 +4224,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
4039
4224
  "Workspace"
4040
4225
  ];
4041
4226
  readonly summary: "List workspaces for the authenticated user";
4042
- readonly description: "Returns workspaces the user collaborates on, each with category, role, billing flags, invitation state, and the resource grants effective for the caller.";
4227
+ readonly description: "Returns workspaces the user collaborates on, each with category, role, billing flags, invitation state, workspace profile picture URL, and the resource grants effective for the caller.";
4043
4228
  readonly security: readonly [
4044
4229
  never
4045
4230
  ];
@@ -9618,13 +9803,13 @@ declare const routes: import("hono/hono-base").HonoBase<{
9618
9803
  };
9619
9804
  };
9620
9805
  };
9621
- readonly "/chat/start": {
9806
+ readonly "/files/upload-workspace-picture": {
9622
9807
  readonly post: {
9623
9808
  readonly tags: readonly [
9624
- "Chat"
9809
+ "Files"
9625
9810
  ];
9626
- readonly summary: "Start Matrix chat session";
9627
- readonly description: "Provisions or reuses a Matrix (Synapse) user for the authenticated collaborator. Existing tenants are looked up by JWT `userId` + workspace. Username is `owner_{emailLocalPart}-{workspace}` when the caller is the workspace owner (`workspaces.owner_id`), otherwise `{emailLocalPart}-{workspace}`. Persists a tenant row when new, logs in via Matrix `/login` on first use (stable `device_id` and display name), caches `access_token` on the tenant, and returns the raw login JSON. Requires workspace access and read access to crm::chats.";
9811
+ readonly summary: "Create presigned upload for workspace picture";
9812
+ readonly description: "Returns a presigned POST URL and form fields for uploading a temporary workspace picture to `profiles/workspaces/{workspace}/temp` (max 0.5 MB, 5-minute expiry). Accepts JPEG and PNG. After the multipart upload succeeds, call `/files/confirm-workspace-picture` to validate, optimize, and persist the image. Requires workspace access and write access to crm::general.";
9628
9813
  readonly security: readonly [
9629
9814
  never
9630
9815
  ];
@@ -9633,34 +9818,29 @@ declare const routes: import("hono/hono-base").HonoBase<{
9633
9818
  readonly content: {
9634
9819
  readonly "application/json": {
9635
9820
  readonly schema: {
9636
- readonly type: "object";
9637
- readonly required: readonly [
9638
- "workspace"
9639
- ];
9640
- readonly properties: {
9641
- readonly workspace: {
9642
- readonly type: "string";
9643
- readonly format: "uuid";
9644
- readonly description: "Workspace identifier for chat tenancy.";
9645
- };
9646
- };
9821
+ readonly $ref: "#/components/schemas/UploadWorkspacePictureRequest";
9647
9822
  };
9648
9823
  };
9649
9824
  };
9650
9825
  };
9651
9826
  readonly responses: {
9652
- readonly 201: {
9653
- readonly description: "Matrix login payload (fresh Synapse login or cached token response).";
9827
+ readonly 200: {
9828
+ readonly description: "Presigned workspace picture upload created.";
9654
9829
  readonly content: {
9655
9830
  readonly "application/json": {
9656
9831
  readonly schema: {
9657
- readonly $ref: "#/components/schemas/MatrixLoginResponse";
9832
+ readonly allOf: readonly [
9833
+ {
9834
+ readonly $ref: "#/components/schemas/PresignedUploadSuccess";
9835
+ }
9836
+ ];
9837
+ readonly description: "key is `profiles/workspaces/{workspace}/temp`; maxSize is 524288 (0.5 MB).";
9658
9838
  };
9659
9839
  };
9660
9840
  };
9661
9841
  };
9662
9842
  readonly 400: {
9663
- readonly description: "Invalid request payload.";
9843
+ readonly description: "Invalid request payload or unsupported content type.";
9664
9844
  readonly content: {
9665
9845
  readonly "application/json": {
9666
9846
  readonly schema: {
@@ -9673,7 +9853,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
9673
9853
  readonly description: "Unauthorized - Missing or invalid access token.";
9674
9854
  };
9675
9855
  readonly 403: {
9676
- readonly description: "Forbidden - Token issuer is not 'access', collaborator invite not accepted, user lacks workspace access, or user lacks read access to crm::chats.";
9856
+ readonly description: "Forbidden - Token issuer is not 'access', user lacks workspace access, or user lacks write access to crm::general.";
9677
9857
  readonly content: {
9678
9858
  readonly "application/json": {
9679
9859
  readonly schema: {
@@ -9692,54 +9872,42 @@ declare const routes: import("hono/hono-base").HonoBase<{
9692
9872
  };
9693
9873
  };
9694
9874
  };
9695
- readonly 500: {
9696
- readonly description: "Failed to provision the Matrix user on Synapse.";
9697
- readonly content: {
9698
- readonly "application/json": {
9699
- readonly schema: {
9700
- readonly $ref: "#/components/schemas/ChatStartFailure";
9701
- };
9702
- };
9703
- };
9704
- };
9705
9875
  };
9706
9876
  };
9707
9877
  };
9708
- readonly "/chat/collaborators/{workspace}": {
9709
- readonly get: {
9878
+ readonly "/files/confirm-workspace-picture": {
9879
+ readonly post: {
9710
9880
  readonly tags: readonly [
9711
- "Chat"
9881
+ "Files"
9712
9882
  ];
9713
- readonly summary: "List chat tenants / collaborators";
9714
- readonly description: "Returns chat tenants for the workspace joined with collaborator role and user profile fields. `username` is a fully qualified Matrix user ID (`@{localpart}:aio.mestra.chat`). Requires workspace access and read access to crm::chats.";
9883
+ readonly summary: "Confirm and persist an uploaded workspace picture";
9884
+ readonly description: "Reads the temporary object at `profiles/workspaces/{workspace}/temp`, verifies size (<= 0.5 MB) and real image type (JPEG, PNG, or WebP), resizes it to a 512x512 WebP avatar (cover fit, without enlargement, input pixel limit 4096x4096), stores it privately at `profiles/workspaces/{workspace}/avatar.webp`, deletes the temporary object, creates a 7-day presigned GET URL for the avatar, and saves that URL on the workspace. On failure, the temporary object is deleted and the workspace picture is cleared. Requires workspace access and write access to crm::general.";
9715
9885
  readonly security: readonly [
9716
9886
  never
9717
9887
  ];
9718
- readonly parameters: readonly [
9719
- {
9720
- readonly name: "workspace";
9721
- readonly in: "path";
9722
- readonly required: true;
9723
- readonly schema: {
9724
- readonly type: "string";
9725
- readonly format: "uuid";
9888
+ readonly requestBody: {
9889
+ readonly required: true;
9890
+ readonly content: {
9891
+ readonly "application/json": {
9892
+ readonly schema: {
9893
+ readonly $ref: "#/components/schemas/WorkspacePictureWorkspaceRequest";
9894
+ };
9726
9895
  };
9727
- readonly description: "Workspace identifier.";
9728
- }
9729
- ];
9896
+ };
9897
+ };
9730
9898
  readonly responses: {
9731
9899
  readonly 200: {
9732
- readonly description: "Chat collaborators listed successfully.";
9900
+ readonly description: "Workspace picture confirmed and saved successfully.";
9733
9901
  readonly content: {
9734
9902
  readonly "application/json": {
9735
9903
  readonly schema: {
9736
- readonly $ref: "#/components/schemas/ListChatCollaboratorsSuccess";
9904
+ readonly $ref: "#/components/schemas/ConfirmWorkspacePictureSuccess";
9737
9905
  };
9738
9906
  };
9739
9907
  };
9740
9908
  };
9741
9909
  readonly 400: {
9742
- readonly description: "Invalid workspace id.";
9910
+ readonly description: "Temporary object missing, file too large, invalid image type, or processing failed.";
9743
9911
  readonly content: {
9744
9912
  readonly "application/json": {
9745
9913
  readonly schema: {
@@ -9752,7 +9920,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
9752
9920
  readonly description: "Unauthorized - Missing or invalid access token.";
9753
9921
  };
9754
9922
  readonly 403: {
9755
- readonly description: "Forbidden - Token issuer is not 'access', collaborator invite not accepted, user lacks workspace access, or user lacks read access to crm::chats.";
9923
+ readonly description: "Forbidden - Token issuer is not 'access', user lacks workspace access, or user lacks write access to crm::general.";
9756
9924
  readonly content: {
9757
9925
  readonly "application/json": {
9758
9926
  readonly schema: {
@@ -9762,7 +9930,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
9762
9930
  };
9763
9931
  };
9764
9932
  readonly 404: {
9765
- readonly description: "Workspace not found, or collaborators not found.";
9933
+ readonly description: "Workspace not found.";
9766
9934
  readonly content: {
9767
9935
  readonly "application/json": {
9768
9936
  readonly schema: {
@@ -9774,41 +9942,338 @@ declare const routes: import("hono/hono-base").HonoBase<{
9774
9942
  };
9775
9943
  };
9776
9944
  };
9777
- };
9778
- };
9779
- outputFormat: "json";
9780
- status: import("hono/utils/http-status").ContentfulStatusCode;
9781
- };
9782
- };
9783
- } & {
9784
- "/docs": {
9785
- $get: {
9786
- input: {};
9787
- output: {};
9788
- outputFormat: string;
9789
- status: import("hono/utils/http-status").StatusCode;
9790
- };
9791
- };
9792
- } & {
9793
- "/health": {
9794
- $get: {
9795
- input: {};
9796
- output: {
9797
- status: string;
9798
- };
9799
- outputFormat: "json";
9800
- status: import("hono/utils/http-status").ContentfulStatusCode;
9801
- };
9802
- };
9803
- } & {
9804
- "/": {
9805
- $get: {
9806
- input: {};
9807
- output: {
9808
- message: string;
9809
- link: string;
9810
- };
9811
- outputFormat: "json";
9945
+ readonly "/files/delete-workspace-picture": {
9946
+ readonly post: {
9947
+ readonly tags: readonly [
9948
+ "Files"
9949
+ ];
9950
+ readonly summary: "Delete a workspace picture";
9951
+ readonly description: "Deletes `profiles/workspaces/{workspace}/avatar.webp` from S3 when present and clears the picture on the workspace. If the object is already missing, still clears the stored value and returns success with message `Workspace picture already deleted`. Requires workspace access and write access to crm::general.";
9952
+ readonly security: readonly [
9953
+ never
9954
+ ];
9955
+ readonly requestBody: {
9956
+ readonly required: true;
9957
+ readonly content: {
9958
+ readonly "application/json": {
9959
+ readonly schema: {
9960
+ readonly $ref: "#/components/schemas/WorkspacePictureWorkspaceRequest";
9961
+ };
9962
+ };
9963
+ };
9964
+ };
9965
+ readonly responses: {
9966
+ readonly 200: {
9967
+ readonly description: "Workspace picture deleted, or already absent and cleared from the workspace.";
9968
+ readonly content: {
9969
+ readonly "application/json": {
9970
+ readonly schema: {
9971
+ readonly $ref: "#/components/schemas/DeleteWorkspacePictureSuccess";
9972
+ };
9973
+ };
9974
+ };
9975
+ };
9976
+ readonly 400: {
9977
+ readonly description: "Invalid request payload.";
9978
+ readonly content: {
9979
+ readonly "application/json": {
9980
+ readonly schema: {
9981
+ readonly $ref: "#/components/schemas/ErrorResponse";
9982
+ };
9983
+ };
9984
+ };
9985
+ };
9986
+ readonly 401: {
9987
+ readonly description: "Unauthorized - Missing or invalid access token.";
9988
+ };
9989
+ readonly 403: {
9990
+ readonly description: "Forbidden - Token issuer is not 'access', user lacks workspace access, or user lacks write access to crm::general.";
9991
+ readonly content: {
9992
+ readonly "application/json": {
9993
+ readonly schema: {
9994
+ readonly $ref: "#/components/schemas/ErrorResponse";
9995
+ };
9996
+ };
9997
+ };
9998
+ };
9999
+ readonly 404: {
10000
+ readonly description: "Workspace not found.";
10001
+ readonly content: {
10002
+ readonly "application/json": {
10003
+ readonly schema: {
10004
+ readonly $ref: "#/components/schemas/ErrorResponse";
10005
+ };
10006
+ };
10007
+ };
10008
+ };
10009
+ readonly 500: {
10010
+ readonly description: "Failed to delete the workspace picture object.";
10011
+ readonly content: {
10012
+ readonly "application/json": {
10013
+ readonly schema: {
10014
+ readonly $ref: "#/components/schemas/ErrorResponse";
10015
+ };
10016
+ };
10017
+ };
10018
+ };
10019
+ };
10020
+ };
10021
+ };
10022
+ readonly "/notifications/sync": {
10023
+ readonly get: {
10024
+ readonly tags: readonly [
10025
+ "Notifications"
10026
+ ];
10027
+ readonly summary: "Sync notifications incrementally";
10028
+ readonly description: "Returns the authenticated user's notifications created or updated after the given `cursor` (change timestamp = greatest of created_at/updated_at), ordered oldest change first. Without a cursor, returns notifications from the beginning. Responses are paged by `limit`; when `hasMore` is true, call again with the returned cursor until it is false. Marking notifications read or archived bumps their change timestamp, so state changes propagate to all of the user's devices. Requires a valid access token (no workspace policy check).";
10029
+ readonly security: readonly [
10030
+ never
10031
+ ];
10032
+ readonly parameters: readonly [
10033
+ {
10034
+ readonly name: "cursor";
10035
+ readonly in: "query";
10036
+ readonly required: false;
10037
+ readonly schema: {
10038
+ readonly type: "string";
10039
+ readonly format: "date-time";
10040
+ };
10041
+ readonly description: "Change timestamp returned by the previous sync call (ISO 8601). Omit for a full initial sync.";
10042
+ },
10043
+ {
10044
+ readonly name: "limit";
10045
+ readonly in: "query";
10046
+ readonly required: false;
10047
+ readonly schema: {
10048
+ readonly type: "integer";
10049
+ readonly minimum: 1;
10050
+ readonly maximum: 200;
10051
+ readonly default: 100;
10052
+ };
10053
+ readonly description: "Maximum notifications per page.";
10054
+ }
10055
+ ];
10056
+ readonly responses: {
10057
+ readonly 200: {
10058
+ readonly description: "Changed notifications with the next cursor.";
10059
+ readonly content: {
10060
+ readonly "application/json": {
10061
+ readonly schema: {
10062
+ readonly $ref: "#/components/schemas/NotificationSyncSuccess";
10063
+ };
10064
+ };
10065
+ };
10066
+ };
10067
+ readonly 400: {
10068
+ readonly description: "Invalid cursor or limit query parameter.";
10069
+ readonly content: {
10070
+ readonly "application/json": {
10071
+ readonly schema: {
10072
+ readonly $ref: "#/components/schemas/ErrorResponse";
10073
+ };
10074
+ };
10075
+ };
10076
+ };
10077
+ readonly 401: {
10078
+ readonly description: "Unauthorized - Missing or invalid access token.";
10079
+ };
10080
+ readonly 403: {
10081
+ readonly description: "Forbidden - Token issuer is not 'access'.";
10082
+ };
10083
+ };
10084
+ };
10085
+ };
10086
+ readonly "/chat/start": {
10087
+ readonly post: {
10088
+ readonly tags: readonly [
10089
+ "Chat"
10090
+ ];
10091
+ readonly summary: "Start Matrix chat session";
10092
+ readonly description: "Provisions or reuses a Matrix (Synapse) user for the authenticated collaborator. Existing tenants are looked up by JWT `userId` + workspace. Username is `owner_{emailLocalPart}-{workspace}` when the caller is the workspace owner (`workspaces.owner_id`), otherwise `{emailLocalPart}-{workspace}`. Persists a tenant row when new, logs in via Matrix `/login` on first use (stable `device_id` and display name), caches `access_token` on the tenant, and returns the raw login JSON. Requires workspace access and read access to crm::chats.";
10093
+ readonly security: readonly [
10094
+ never
10095
+ ];
10096
+ readonly requestBody: {
10097
+ readonly required: true;
10098
+ readonly content: {
10099
+ readonly "application/json": {
10100
+ readonly schema: {
10101
+ readonly type: "object";
10102
+ readonly required: readonly [
10103
+ "workspace"
10104
+ ];
10105
+ readonly properties: {
10106
+ readonly workspace: {
10107
+ readonly type: "string";
10108
+ readonly format: "uuid";
10109
+ readonly description: "Workspace identifier for chat tenancy.";
10110
+ };
10111
+ };
10112
+ };
10113
+ };
10114
+ };
10115
+ };
10116
+ readonly responses: {
10117
+ readonly 201: {
10118
+ readonly description: "Matrix login payload (fresh Synapse login or cached token response).";
10119
+ readonly content: {
10120
+ readonly "application/json": {
10121
+ readonly schema: {
10122
+ readonly $ref: "#/components/schemas/MatrixLoginResponse";
10123
+ };
10124
+ };
10125
+ };
10126
+ };
10127
+ readonly 400: {
10128
+ readonly description: "Invalid request payload.";
10129
+ readonly content: {
10130
+ readonly "application/json": {
10131
+ readonly schema: {
10132
+ readonly $ref: "#/components/schemas/ErrorResponse";
10133
+ };
10134
+ };
10135
+ };
10136
+ };
10137
+ readonly 401: {
10138
+ readonly description: "Unauthorized - Missing or invalid access token.";
10139
+ };
10140
+ readonly 403: {
10141
+ readonly description: "Forbidden - Token issuer is not 'access', collaborator invite not accepted, user lacks workspace access, or user lacks read access to crm::chats.";
10142
+ readonly content: {
10143
+ readonly "application/json": {
10144
+ readonly schema: {
10145
+ readonly $ref: "#/components/schemas/ErrorResponse";
10146
+ };
10147
+ };
10148
+ };
10149
+ };
10150
+ readonly 404: {
10151
+ readonly description: "Workspace not found.";
10152
+ readonly content: {
10153
+ readonly "application/json": {
10154
+ readonly schema: {
10155
+ readonly $ref: "#/components/schemas/ErrorResponse";
10156
+ };
10157
+ };
10158
+ };
10159
+ };
10160
+ readonly 500: {
10161
+ readonly description: "Failed to provision the Matrix user on Synapse.";
10162
+ readonly content: {
10163
+ readonly "application/json": {
10164
+ readonly schema: {
10165
+ readonly $ref: "#/components/schemas/ChatStartFailure";
10166
+ };
10167
+ };
10168
+ };
10169
+ };
10170
+ };
10171
+ };
10172
+ };
10173
+ readonly "/chat/collaborators/{workspace}": {
10174
+ readonly get: {
10175
+ readonly tags: readonly [
10176
+ "Chat"
10177
+ ];
10178
+ readonly summary: "List chat tenants / collaborators";
10179
+ readonly description: "Returns chat tenants for the workspace joined with collaborator role and user profile fields. `username` is a fully qualified Matrix user ID (`@{localpart}:aio.mestra.chat`). Requires workspace access and read access to crm::chats.";
10180
+ readonly security: readonly [
10181
+ never
10182
+ ];
10183
+ readonly parameters: readonly [
10184
+ {
10185
+ readonly name: "workspace";
10186
+ readonly in: "path";
10187
+ readonly required: true;
10188
+ readonly schema: {
10189
+ readonly type: "string";
10190
+ readonly format: "uuid";
10191
+ };
10192
+ readonly description: "Workspace identifier.";
10193
+ }
10194
+ ];
10195
+ readonly responses: {
10196
+ readonly 200: {
10197
+ readonly description: "Chat collaborators listed successfully.";
10198
+ readonly content: {
10199
+ readonly "application/json": {
10200
+ readonly schema: {
10201
+ readonly $ref: "#/components/schemas/ListChatCollaboratorsSuccess";
10202
+ };
10203
+ };
10204
+ };
10205
+ };
10206
+ readonly 400: {
10207
+ readonly description: "Invalid workspace id.";
10208
+ readonly content: {
10209
+ readonly "application/json": {
10210
+ readonly schema: {
10211
+ readonly $ref: "#/components/schemas/ErrorResponse";
10212
+ };
10213
+ };
10214
+ };
10215
+ };
10216
+ readonly 401: {
10217
+ readonly description: "Unauthorized - Missing or invalid access token.";
10218
+ };
10219
+ readonly 403: {
10220
+ readonly description: "Forbidden - Token issuer is not 'access', collaborator invite not accepted, user lacks workspace access, or user lacks read access to crm::chats.";
10221
+ readonly content: {
10222
+ readonly "application/json": {
10223
+ readonly schema: {
10224
+ readonly $ref: "#/components/schemas/ErrorResponse";
10225
+ };
10226
+ };
10227
+ };
10228
+ };
10229
+ readonly 404: {
10230
+ readonly description: "Workspace not found, or collaborators not found.";
10231
+ readonly content: {
10232
+ readonly "application/json": {
10233
+ readonly schema: {
10234
+ readonly $ref: "#/components/schemas/ErrorResponse";
10235
+ };
10236
+ };
10237
+ };
10238
+ };
10239
+ };
10240
+ };
10241
+ };
10242
+ };
10243
+ };
10244
+ outputFormat: "json";
10245
+ status: import("hono/utils/http-status").ContentfulStatusCode;
10246
+ };
10247
+ };
10248
+ } & {
10249
+ "/docs": {
10250
+ $get: {
10251
+ input: {};
10252
+ output: {};
10253
+ outputFormat: string;
10254
+ status: import("hono/utils/http-status").StatusCode;
10255
+ };
10256
+ };
10257
+ } & {
10258
+ "/health": {
10259
+ $get: {
10260
+ input: {};
10261
+ output: {
10262
+ status: string;
10263
+ };
10264
+ outputFormat: "json";
10265
+ status: import("hono/utils/http-status").ContentfulStatusCode;
10266
+ };
10267
+ };
10268
+ } & {
10269
+ "/": {
10270
+ $get: {
10271
+ input: {};
10272
+ output: {
10273
+ message: string;
10274
+ link: string;
10275
+ };
10276
+ outputFormat: "json";
9812
10277
  status: import("hono/utils/http-status").ContentfulStatusCode;
9813
10278
  };
9814
10279
  };
@@ -10033,6 +10498,7 @@ declare const routes: import("hono/hono-base").HonoBase<{
10033
10498
  workspaces: {
10034
10499
  workspaceId: string;
10035
10500
  workspaceName: string;
10501
+ profilePicture: string | null;
10036
10502
  workspaceCategory: string;
10037
10503
  role: string;
10038
10504
  maxCollaborators: number;
@@ -10518,9 +10984,10 @@ declare const routes: import("hono/hono-base").HonoBase<{
10518
10984
  output: {
10519
10985
  success: true;
10520
10986
  task: {
10521
- status: string | null;
10522
10987
  id: string;
10523
10988
  workspaceId: string;
10989
+ created_at: string;
10990
+ status: string | null;
10524
10991
  description: string | null;
10525
10992
  subject: string;
10526
10993
  created_by: string;
@@ -10529,7 +10996,6 @@ declare const routes: import("hono/hono-base").HonoBase<{
10529
10996
  deleted_at: string | null;
10530
10997
  verified_at: string | null;
10531
10998
  suspended_at: string | null;
10532
- created_at: string;
10533
10999
  priority: string | null;
10534
11000
  visibility: string | null;
10535
11001
  };
@@ -10779,16 +11245,16 @@ declare const routes: import("hono/hono-base").HonoBase<{
10779
11245
  output: {
10780
11246
  success: true;
10781
11247
  template: {
10782
- title: string;
10783
11248
  id: string;
10784
11249
  workspaceId: string;
11250
+ title: string;
11251
+ created_at: string;
10785
11252
  created_by: string;
10786
11253
  content: string;
10787
11254
  updated_at: string | null;
10788
11255
  deleted_at: string | null;
10789
11256
  verified_at: string | null;
10790
11257
  suspended_at: string | null;
10791
- created_at: string;
10792
11258
  }[];
10793
11259
  };
10794
11260
  outputFormat: "json";
@@ -10837,20 +11303,20 @@ declare const routes: import("hono/hono-base").HonoBase<{
10837
11303
  output: {
10838
11304
  success: true;
10839
11305
  service: {
10840
- name: string;
10841
- active: boolean | null;
10842
11306
  id: string;
10843
11307
  workspaceId: string;
11308
+ type: string | null;
11309
+ created_at: string;
11310
+ name: string;
11311
+ active: boolean | null;
10844
11312
  description: string | null;
10845
11313
  price: number | null;
10846
11314
  stock: number | null;
10847
11315
  currency: string | null;
10848
- type: string | null;
10849
11316
  updated_at: string | null;
10850
11317
  deleted_at: string | null;
10851
11318
  verified_at: string | null;
10852
11319
  suspended_at: string | null;
10853
- created_at: string;
10854
11320
  qrCode: string | null;
10855
11321
  }[];
10856
11322
  };
@@ -11007,19 +11473,19 @@ declare const routes: import("hono/hono-base").HonoBase<{
11007
11473
  output: {
11008
11474
  success: true;
11009
11475
  customer: {
11476
+ id: string;
11477
+ workspaceId: string;
11478
+ type: string | null;
11479
+ created_at: string;
11010
11480
  name: string;
11011
11481
  active: boolean | null;
11012
11482
  email: string | null;
11013
- id: string;
11014
- workspaceId: string;
11015
11483
  description: string | null;
11016
- type: string | null;
11017
11484
  phone: string | null;
11018
11485
  updated_at: string | null;
11019
11486
  deleted_at: string | null;
11020
11487
  verified_at: string | null;
11021
11488
  suspended_at: string | null;
11022
- created_at: string;
11023
11489
  website: string | null;
11024
11490
  companyPhone: string | null;
11025
11491
  companyAddress: string | null;
@@ -11239,9 +11705,10 @@ declare const routes: import("hono/hono-base").HonoBase<{
11239
11705
  output: {
11240
11706
  success: true;
11241
11707
  billing: {
11242
- active: boolean | null;
11243
11708
  id: string;
11244
11709
  workspaceId: string;
11710
+ created_at: string;
11711
+ active: boolean | null;
11245
11712
  country: string;
11246
11713
  companyName: string;
11247
11714
  inn: string;
@@ -11256,7 +11723,6 @@ declare const routes: import("hono/hono-base").HonoBase<{
11256
11723
  deleted_at: string | null;
11257
11724
  verified_at: string | null;
11258
11725
  suspended_at: string | null;
11259
- created_at: string;
11260
11726
  }[];
11261
11727
  };
11262
11728
  outputFormat: "json";
@@ -11477,11 +11943,12 @@ declare const routes: import("hono/hono-base").HonoBase<{
11477
11943
  output: {
11478
11944
  success: true;
11479
11945
  assignee: {
11946
+ id: string;
11947
+ workspaceId: string;
11948
+ created_at: string;
11480
11949
  startDate: string | null;
11481
11950
  endDate: string | null;
11482
11951
  collaboratorId: string;
11483
- id: string;
11484
- workspaceId: string;
11485
11952
  description: string | null;
11486
11953
  created_by: string;
11487
11954
  taskId: string;
@@ -11489,7 +11956,6 @@ declare const routes: import("hono/hono-base").HonoBase<{
11489
11956
  deleted_at: string | null;
11490
11957
  verified_at: string | null;
11491
11958
  suspended_at: string | null;
11492
- created_at: string;
11493
11959
  };
11494
11960
  };
11495
11961
  outputFormat: "json";
@@ -11599,15 +12065,15 @@ declare const routes: import("hono/hono-base").HonoBase<{
11599
12065
  output: {
11600
12066
  success: true;
11601
12067
  tag: {
11602
- name: string;
11603
12068
  id: string;
11604
12069
  workspaceId: string;
12070
+ created_at: string;
12071
+ name: string;
11605
12072
  description: string | null;
11606
12073
  updated_at: string | null;
11607
12074
  deleted_at: string | null;
11608
12075
  verified_at: string | null;
11609
12076
  suspended_at: string | null;
11610
- created_at: string;
11611
12077
  }[];
11612
12078
  };
11613
12079
  outputFormat: "json";
@@ -12540,10 +13006,10 @@ declare const routes: import("hono/hono-base").HonoBase<{
12540
13006
  "www-authenticate"?: string | undefined | undefined;
12541
13007
  ":status"?: number | undefined | undefined;
12542
13008
  };
13009
+ readonly type: ResponseType;
12543
13010
  readonly url: string;
12544
13011
  readonly status: number;
12545
13012
  readonly ok: boolean;
12546
- readonly type: ResponseType;
12547
13013
  data: {
12548
13014
  anyoneCanAddSelf?: boolean | null | undefined;
12549
13015
  attachments?: {
@@ -15210,6 +15676,78 @@ declare const routes: import("hono/hono-base").HonoBase<{
15210
15676
  status: 500;
15211
15677
  };
15212
15678
  };
15679
+ } & {
15680
+ "/upload-workspace-picture": {
15681
+ $post: {
15682
+ input: {};
15683
+ output: {
15684
+ success: false;
15685
+ error: never;
15686
+ };
15687
+ outputFormat: "json";
15688
+ status: 400;
15689
+ } | {
15690
+ input: {};
15691
+ output: {
15692
+ url: string;
15693
+ fields: {
15694
+ [x: string]: string;
15695
+ };
15696
+ key: string;
15697
+ maxSize: number;
15698
+ };
15699
+ outputFormat: "json";
15700
+ status: import("hono/utils/http-status").ContentfulStatusCode;
15701
+ };
15702
+ };
15703
+ } & {
15704
+ "/confirm-workspace-picture": {
15705
+ $post: {
15706
+ input: {};
15707
+ output: {
15708
+ success: true;
15709
+ url: string;
15710
+ };
15711
+ outputFormat: "json";
15712
+ status: import("hono/utils/http-status").ContentfulStatusCode;
15713
+ } | {
15714
+ input: {};
15715
+ output: {
15716
+ success: false;
15717
+ error: string;
15718
+ };
15719
+ outputFormat: "json";
15720
+ status: 400;
15721
+ };
15722
+ };
15723
+ } & {
15724
+ "/delete-workspace-picture": {
15725
+ $post: {
15726
+ input: {};
15727
+ output: {
15728
+ success: false;
15729
+ error: never;
15730
+ };
15731
+ outputFormat: "json";
15732
+ status: 400;
15733
+ } | {
15734
+ input: {};
15735
+ output: {
15736
+ success: true;
15737
+ message: string;
15738
+ };
15739
+ outputFormat: "json";
15740
+ status: import("hono/utils/http-status").ContentfulStatusCode;
15741
+ } | {
15742
+ input: {};
15743
+ output: {
15744
+ success: false;
15745
+ error: string;
15746
+ };
15747
+ outputFormat: "json";
15748
+ status: 500;
15749
+ };
15750
+ };
15213
15751
  }, "/files"> | import("hono/types").MergeSchemaPath<{
15214
15752
  "/start": {
15215
15753
  $post: {
@@ -15272,5 +15810,51 @@ declare const routes: import("hono/hono-base").HonoBase<{
15272
15810
  status: 200;
15273
15811
  };
15274
15812
  };
15275
- }, "/chat">, "/", "/">;
15813
+ }, "/chat"> | import("hono/types").MergeSchemaPath<{
15814
+ "/sync": {
15815
+ $get: {
15816
+ input: {};
15817
+ output: {
15818
+ success: false;
15819
+ error: {
15820
+ _errors: string[];
15821
+ limit?: {
15822
+ [x: string]: any;
15823
+ _errors: string[];
15824
+ } | undefined;
15825
+ cursor?: {
15826
+ [x: string]: any;
15827
+ _errors: string[];
15828
+ } | undefined;
15829
+ };
15830
+ };
15831
+ outputFormat: "json";
15832
+ status: 400;
15833
+ } | {
15834
+ input: {};
15835
+ output: {
15836
+ success: true;
15837
+ notifications: {
15838
+ updated_at: string | null;
15839
+ deleted_at: string | null;
15840
+ verified_at: string | null;
15841
+ suspended_at: string | null;
15842
+ created_at: string;
15843
+ id: string;
15844
+ userId: string;
15845
+ workspaceId: string;
15846
+ title: string;
15847
+ message: string;
15848
+ type: string;
15849
+ read: boolean;
15850
+ archive: boolean;
15851
+ }[];
15852
+ cursor: string | null;
15853
+ hasMore: boolean;
15854
+ };
15855
+ outputFormat: "json";
15856
+ status: 200;
15857
+ };
15858
+ };
15859
+ }, "/notifications">, "/", "/">;
15276
15860
  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.9",
3
+ "version": "0.0.11",
4
4
  "description": "Types-only Hono AppType contract for the Mestra auth API",
5
5
  "type": "module",
6
6
  "sideEffects": false,