@jskit-ai/users-core 0.1.42 → 0.1.44

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 (55) hide show
  1. package/package.descriptor.mjs +6 -6
  2. package/package.json +6 -6
  3. package/src/server/accountProfile/avatarStorageService.js +3 -3
  4. package/src/server/common/contributors/workspaceRouteVisibilityResolver.js +12 -13
  5. package/src/server/common/formatters/workspaceFormatter.js +3 -2
  6. package/src/server/common/repositories/repositoryUtils.js +12 -3
  7. package/src/server/common/repositories/userSettingsRepository.js +35 -11
  8. package/src/server/common/repositories/usersRepository.js +44 -27
  9. package/src/server/common/repositories/workspaceInvitesRepository.js +49 -13
  10. package/src/server/common/repositories/workspaceMembershipsRepository.js +55 -22
  11. package/src/server/common/repositories/workspacesRepository.js +41 -11
  12. package/src/server/common/services/accountContextService.js +3 -2
  13. package/src/server/common/services/authProfileSyncService.js +7 -5
  14. package/src/server/common/services/workspaceContextService.js +4 -1
  15. package/src/server/common/support/realtimeServiceEvents.js +4 -3
  16. package/src/server/common/validators/authenticatedUserValidator.js +5 -4
  17. package/src/server/consoleSettings/consoleService.js +3 -3
  18. package/src/server/consoleSettings/consoleSettingsRepository.js +10 -6
  19. package/src/server/usersBootstrapContributor.js +7 -3
  20. package/src/server/workspaceBootstrapContributor.js +5 -1
  21. package/src/server/workspaceMembers/registerWorkspaceMembers.js +6 -4
  22. package/src/server/workspaceMembers/workspaceMembersService.js +23 -11
  23. package/src/server/workspacePendingInvitations/registerWorkspacePendingInvitations.js +5 -4
  24. package/src/server/workspacePendingInvitations/workspacePendingInvitationsService.js +3 -2
  25. package/src/server/workspaceSettings/workspaceSettingsRepository.js +29 -10
  26. package/src/server/workspaceSettings/workspaceSettingsService.js +3 -2
  27. package/src/shared/resources/workspaceMembersResource.js +25 -21
  28. package/src/shared/resources/workspacePendingInvitationsResource.js +7 -12
  29. package/src/shared/resources/workspaceResource.js +13 -9
  30. package/src/shared/resources/workspaceSettingsResource.js +7 -5
  31. package/templates/migrations/users_core_console_owner.cjs +1 -1
  32. package/templates/migrations/users_core_generic_initial.cjs +4 -4
  33. package/templates/migrations/users_core_profile_username.cjs +1 -1
  34. package/test/authProfileSyncService.test.js +7 -4
  35. package/test/avatarStorageService.test.js +3 -3
  36. package/test/consoleService.test.js +9 -9
  37. package/test/registerServiceRealtimeEvents.test.js +9 -9
  38. package/test/repositoryContracts.test.js +40 -0
  39. package/test/usersBootstrapContributor.test.js +4 -4
  40. package/test/workspaceBootstrapContributor.test.js +1 -1
  41. package/test/workspaceInvitesRepository.test.js +3 -3
  42. package/test/workspaceMembersService.test.js +34 -34
  43. package/test/workspacePendingInvitationsResource.test.js +4 -4
  44. package/test/workspacePendingInvitationsService.test.js +11 -11
  45. package/test/workspaceRouteVisibilityResolver.test.js +6 -6
  46. package/test/workspaceService.test.js +33 -33
  47. package/test/workspaceSettingsRepository.test.js +7 -6
  48. package/test/workspaceSettingsResource.test.js +2 -2
  49. package/src/server/common/README.md +0 -20
  50. package/src/server/common/contributors/README.md +0 -11
  51. package/src/server/common/formatters/README.md +0 -11
  52. package/src/server/common/repositories/README.md +0 -24
  53. package/src/server/common/routes/README.md +0 -11
  54. package/src/server/common/services/README.md +0 -12
  55. package/src/server/common/validators/README.md +0 -11
@@ -18,8 +18,8 @@ function createStorageDouble() {
18
18
  }
19
19
 
20
20
  test("avatarStorageService builds stable storage key by user id", () => {
21
- assert.equal(__testables.buildAvatarStorageKey(7), "users/avatars/7/avatar");
22
- assert.throws(() => __testables.buildAvatarStorageKey(0), /positive integer user id/);
21
+ assert.equal(__testables.buildAvatarStorageKey("7"), "users/avatars/7/avatar");
22
+ assert.throws(() => __testables.buildAvatarStorageKey("0"), /valid user id/);
23
23
  });
24
24
 
25
25
  test("avatarStorageService detects common avatar mime types", () => {
@@ -45,7 +45,7 @@ test("avatarStorageService saves, reads, and deletes avatar bytes", async () =>
45
45
  const payload = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
46
46
 
47
47
  const saved = await avatarStorageService.saveAvatar({
48
- userId: 42,
48
+ userId: "42",
49
49
  buffer: payload
50
50
  });
51
51
  assert.equal(saved.storageKey, "users/avatars/42/avatar");
@@ -10,7 +10,7 @@ function createFixture(initialOwnerUserId = null) {
10
10
  const service = createService({
11
11
  consoleSettingsRepository: {
12
12
  async ensureOwnerUserId(userId) {
13
- const normalizedUserId = Number(userId);
13
+ const normalizedUserId = String(userId || "");
14
14
  if (!state.ownerUserId) {
15
15
  state.ownerUserId = normalizedUserId;
16
16
  }
@@ -25,22 +25,22 @@ function createFixture(initialOwnerUserId = null) {
25
25
  test("consoleService seeds the first authenticated user as console owner", async () => {
26
26
  const { service, state } = createFixture();
27
27
 
28
- const firstOwner = await service.ensureInitialConsoleMember(7);
29
- const secondAttempt = await service.ensureInitialConsoleMember(9);
28
+ const firstOwner = await service.ensureInitialConsoleMember("7");
29
+ const secondAttempt = await service.ensureInitialConsoleMember("9");
30
30
 
31
- assert.equal(firstOwner, 7);
32
- assert.equal(secondAttempt, 7);
33
- assert.equal(state.ownerUserId, 7);
31
+ assert.equal(firstOwner, "7");
32
+ assert.equal(secondAttempt, "7");
33
+ assert.equal(state.ownerUserId, "7");
34
34
  });
35
35
 
36
36
  test("consoleService.requireConsoleOwner denies authenticated non-owners", async () => {
37
- const { service } = createFixture(7);
37
+ const { service } = createFixture("7");
38
38
 
39
39
  await assert.rejects(
40
40
  () =>
41
41
  service.requireConsoleOwner({
42
42
  actor: {
43
- id: 9
43
+ id: "9"
44
44
  }
45
45
  }),
46
46
  (error) => error?.status === 403
@@ -48,7 +48,7 @@ test("consoleService.requireConsoleOwner denies authenticated non-owners", async
48
48
  });
49
49
 
50
50
  test("consoleService.requireConsoleOwner requires authentication", async () => {
51
- const { service } = createFixture(7);
51
+ const { service } = createFixture("7");
52
52
 
53
53
  await assert.rejects(
54
54
  () => service.requireConsoleOwner({}),
@@ -76,7 +76,7 @@ test("workspace register functions publish members/invites/workspace-list realti
76
76
  assert.equal(members?.metadata?.events?.removeMember?.[1]?.realtime?.event, "users.bootstrap.changed");
77
77
  assert.equal(members?.metadata?.events?.createInvite?.[0]?.realtime?.event, "workspace.invites.changed");
78
78
  assert.equal(members?.metadata?.events?.createInvite?.[1]?.realtime?.event, "users.bootstrap.changed");
79
- assert.equal(members?.metadata?.events?.createInvite?.[1]?.entityId?.({ result: { createdInviteId: 91 } }), 91);
79
+ assert.equal(members?.metadata?.events?.createInvite?.[1]?.entityId?.({ result: { createdInviteId: "91" } }), "91");
80
80
  assert.equal(members?.metadata?.events?.createInvite?.[1]?.realtime?.audience?.preset, "event_scope");
81
81
  assert.equal(typeof members?.metadata?.events?.createInvite?.[1]?.realtime?.audience?.userQuery, "function");
82
82
  const createInviteAudienceQueryResult = await members?.metadata?.events?.createInvite?.[1]?.realtime?.audience?.userQuery({
@@ -87,7 +87,7 @@ test("workspace register functions publish members/invites/workspace-list realti
87
87
  },
88
88
  where(field, value) {
89
89
  assert.equal(field, "wi.id");
90
- assert.equal(value, 91);
90
+ assert.equal(value, "91");
91
91
  return this;
92
92
  },
93
93
  async first() {
@@ -98,13 +98,13 @@ test("workspace register functions publish members/invites/workspace-list realti
98
98
  };
99
99
  },
100
100
  event: {
101
- entityId: 91
101
+ entityId: "91"
102
102
  }
103
103
  });
104
- assert.deepEqual(createInviteAudienceQueryResult, [{ userId: 55 }]);
104
+ assert.deepEqual(createInviteAudienceQueryResult, [{ userId: "55" }]);
105
105
  assert.equal(members?.metadata?.events?.revokeInvite?.[0]?.realtime?.event, "workspace.invites.changed");
106
106
  assert.equal(members?.metadata?.events?.revokeInvite?.[1]?.realtime?.event, "users.bootstrap.changed");
107
- assert.equal(members?.metadata?.events?.revokeInvite?.[1]?.entityId?.({ result: { revokedInviteId: 19 } }), 19);
107
+ assert.equal(members?.metadata?.events?.revokeInvite?.[1]?.entityId?.({ result: { revokedInviteId: "19" } }), "19");
108
108
  assert.equal(members?.metadata?.events?.revokeInvite?.[1]?.realtime?.audience?.preset, "event_scope");
109
109
  assert.equal(typeof members?.metadata?.events?.revokeInvite?.[1]?.realtime?.audience?.userQuery, "function");
110
110
 
@@ -124,22 +124,22 @@ test("workspace register functions publish members/invites/workspace-list realti
124
124
  const acceptedMembersChange = acceptInviteEvents.find(
125
125
  (entry) => entry?.realtime?.event === "workspace.members.changed"
126
126
  );
127
- assert.equal(acceptedMembersChange?.entityId?.({ result: { workspaceId: 9 } }), 9);
127
+ assert.equal(acceptedMembersChange?.entityId?.({ result: { workspaceId: "9" } }), "9");
128
128
  assert.deepEqual(
129
129
  acceptedMembersChange?.realtime?.audience?.({
130
130
  event: {
131
- entityId: 9
131
+ entityId: "9"
132
132
  }
133
133
  }),
134
134
  {
135
- workspaceId: 9
135
+ workspaceId: "9"
136
136
  }
137
137
  );
138
138
 
139
139
  const acceptedInvitesChange = acceptInviteEvents.find(
140
140
  (entry) => entry?.realtime?.event === "workspace.invites.changed"
141
141
  );
142
- assert.equal(acceptedInvitesChange?.entityId?.({ result: { workspaceId: 9 } }), 9);
142
+ assert.equal(acceptedInvitesChange?.entityId?.({ result: { workspaceId: "9" } }), "9");
143
143
 
144
144
  const refuseInviteEvents = Array.isArray(pending?.metadata?.events?.refuseInviteByToken)
145
145
  ? pending.metadata.events.refuseInviteByToken
@@ -0,0 +1,40 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { createRepository as createUsersRepository } from "../src/server/common/repositories/usersRepository.js";
4
+ import { createRepository as createUserSettingsRepository } from "../src/server/common/repositories/userSettingsRepository.js";
5
+ import { createRepository as createWorkspaceInvitesRepository } from "../src/server/common/repositories/workspaceInvitesRepository.js";
6
+ import { createRepository as createWorkspaceMembershipsRepository } from "../src/server/common/repositories/workspaceMembershipsRepository.js";
7
+ import { createRepository as createWorkspacesRepository } from "../src/server/common/repositories/workspacesRepository.js";
8
+ import { createRepository as createConsoleSettingsRepository } from "../src/server/consoleSettings/consoleSettingsRepository.js";
9
+ import { createRepository as createWorkspaceSettingsRepository } from "../src/server/workspaceSettings/workspaceSettingsRepository.js";
10
+
11
+ function createKnexStub() {
12
+ const knex = Object.assign(() => {
13
+ throw new Error("query execution not expected");
14
+ }, {
15
+ async transaction(work) {
16
+ return work({ trxId: "trx-1" });
17
+ }
18
+ });
19
+
20
+ return knex;
21
+ }
22
+
23
+ test("users-core repositories expose withTransaction", async () => {
24
+ const knex = createKnexStub();
25
+ const repositories = [
26
+ createUsersRepository(knex),
27
+ createUserSettingsRepository(knex),
28
+ createWorkspaceInvitesRepository(knex),
29
+ createWorkspaceMembershipsRepository(knex),
30
+ createWorkspacesRepository(knex),
31
+ createConsoleSettingsRepository(knex),
32
+ createWorkspaceSettingsRepository(knex)
33
+ ];
34
+
35
+ for (const repository of repositories) {
36
+ assert.equal(typeof repository.withTransaction, "function");
37
+ const result = await repository.withTransaction(async (trx) => ({ id: trx.trxId }));
38
+ assert.deepEqual(result, { id: "trx-1" });
39
+ }
40
+ });
@@ -8,7 +8,7 @@ import {
8
8
 
9
9
  function createAuthenticatedProfile(overrides = {}) {
10
10
  return {
11
- id: 7,
11
+ id: "7",
12
12
  authProvider: "local",
13
13
  authProviderUserSid: "user-7",
14
14
  username: "tester",
@@ -34,7 +34,7 @@ function createUserSettings() {
34
34
  }
35
35
 
36
36
  test("users bootstrap contributor seeds the initial console owner and exposes generic app payload", async () => {
37
- const profile = createAuthenticatedProfile({ id: 12 });
37
+ const profile = createAuthenticatedProfile({ id: "12" });
38
38
  const consoleOwnerSeeds = [];
39
39
  const writtenSessions = [];
40
40
  const contributor = createUsersBootstrapContributor({
@@ -64,7 +64,7 @@ test("users bootstrap contributor seeds the initial console owner and exposes ge
64
64
  consoleService: {
65
65
  async ensureInitialConsoleMember(userId) {
66
66
  consoleOwnerSeeds.push(Number(userId));
67
- return Number(userId);
67
+ return String(userId || "");
68
68
  }
69
69
  }
70
70
  });
@@ -92,7 +92,7 @@ test("users bootstrap contributor seeds the initial console owner and exposes ge
92
92
  csrfToken: "csrf-1"
93
93
  });
94
94
  assert.equal(payload.session.authenticated, true);
95
- assert.equal(payload.session.userId, 12);
95
+ assert.equal(payload.session.userId, "12");
96
96
  assert.equal(payload.surfaceAccess.consoleowner, true);
97
97
  assert.equal(payload.app.features.workspaceSwitching, false);
98
98
  assert.deepEqual(payload.session.oauthProviders, [
@@ -4,7 +4,7 @@ import { createWorkspaceBootstrapContributor } from "../src/server/workspaceBoot
4
4
 
5
5
  function createAuthenticatedProfile(overrides = {}) {
6
6
  return {
7
- id: 7,
7
+ id: "7",
8
8
  authProvider: "local",
9
9
  authProviderUserSid: "user-7",
10
10
  username: "tester",
@@ -55,12 +55,12 @@ test("workspaceInvitesRepository.insert normalizes expiresAt ISO input to databa
55
55
  const repository = createRepository(knexStub);
56
56
 
57
57
  await repository.insert({
58
- workspaceId: 1,
58
+ workspaceId: "1",
59
59
  email: "invitee@example.com",
60
60
  roleSid: "member",
61
61
  status: "pending",
62
62
  tokenHash: "hash",
63
- invitedByUserId: 1,
63
+ invitedByUserId: "1",
64
64
  expiresAt: "2026-03-16T00:26:35.709Z"
65
65
  });
66
66
 
@@ -106,6 +106,6 @@ test("workspaceInvitesRepository.findPendingByTokenHash reads from invites table
106
106
  token_hash: "hash-token",
107
107
  status: "pending"
108
108
  });
109
- assert.equal(invite?.workspaceId, 9);
109
+ assert.equal(invite?.workspaceId, "9");
110
110
  assert.equal(invite?.workspaceSlug, undefined);
111
111
  });
@@ -7,7 +7,7 @@ function authorizedOptions(permissions = []) {
7
7
  return {
8
8
  context: {
9
9
  actor: {
10
- id: 1
10
+ id: "1"
11
11
  },
12
12
  permissions
13
13
  }
@@ -40,10 +40,10 @@ function createRoleCatalog() {
40
40
 
41
41
  function createFixture() {
42
42
  const workspace = {
43
- id: 7,
43
+ id: "7",
44
44
  slug: "tonymobily3",
45
45
  name: "TonyMobily3",
46
- ownerUserId: 9,
46
+ ownerUserId: "9",
47
47
  avatarUrl: ""
48
48
  };
49
49
 
@@ -53,7 +53,7 @@ function createFixture() {
53
53
  assert.equal(Number(workspaceId), 7);
54
54
  return [
55
55
  {
56
- userId: 11,
56
+ userId: "11",
57
57
  roleSid: "member",
58
58
  status: "active",
59
59
  displayName: "Alice",
@@ -65,8 +65,8 @@ function createFixture() {
65
65
  assert.equal(Number(workspaceId), 7);
66
66
  assert.equal(Number(userId), 11);
67
67
  return {
68
- workspaceId: 7,
69
- userId: 11,
68
+ workspaceId: "7",
69
+ userId: "11",
70
70
  roleSid: "member",
71
71
  status: "active"
72
72
  };
@@ -112,7 +112,7 @@ test("workspaceMembersService.createInvite uses configured inviteExpiresInMs", a
112
112
  async insert(payload) {
113
113
  expiresAtValues.push(payload.expiresAt);
114
114
  return {
115
- id: 31
115
+ id: "31"
116
116
  };
117
117
  },
118
118
  async listPendingByWorkspaceIdWithWorkspace() {
@@ -130,10 +130,10 @@ test("workspaceMembersService.createInvite uses configured inviteExpiresInMs", a
130
130
  const before = Date.now();
131
131
  const response = await service.createInvite(
132
132
  {
133
- id: 7,
134
- ownerUserId: 9
133
+ id: "7",
134
+ ownerUserId: "9"
135
135
  },
136
- { id: 11 },
136
+ { id: "11" },
137
137
  {
138
138
  email: "alice@example.com",
139
139
  roleSid: "member"
@@ -146,7 +146,7 @@ test("workspaceMembersService.createInvite uses configured inviteExpiresInMs", a
146
146
  const expiresAt = new Date(expiresAtValues[0]).getTime();
147
147
  assert.ok(expiresAt >= before + 30 * 60 * 1000);
148
148
  assert.ok(expiresAt <= after + 30 * 60 * 1000);
149
- assert.equal(response.createdInviteId, 31);
149
+ assert.equal(response.createdInviteId, "31");
150
150
  });
151
151
 
152
152
  test("workspaceMembersService.revokeInvite returns the revoked invite id", async () => {
@@ -164,15 +164,15 @@ test("workspaceMembersService.revokeInvite returns the revoked invite id", async
164
164
  async expirePendingByWorkspaceIdAndEmail() {},
165
165
  async insert() {
166
166
  return {
167
- id: 1
167
+ id: "1"
168
168
  };
169
169
  },
170
170
  async findPendingByIdForWorkspace(inviteId, workspaceId) {
171
171
  assert.equal(Number(inviteId), 47);
172
172
  assert.equal(Number(workspaceId), 7);
173
173
  return {
174
- id: 47,
175
- workspaceId: 7,
174
+ id: "47",
175
+ workspaceId: "7",
176
176
  status: "pending"
177
177
  };
178
178
  },
@@ -186,15 +186,15 @@ test("workspaceMembersService.revokeInvite returns the revoked invite id", async
186
186
 
187
187
  const response = await service.revokeInvite(
188
188
  {
189
- id: 7,
190
- ownerUserId: 9
189
+ id: "7",
190
+ ownerUserId: "9"
191
191
  },
192
- 47,
192
+ "47",
193
193
  authorizedOptions(["workspace.invites.revoke"])
194
194
  );
195
195
 
196
196
  assert.equal(revokedInviteId, 47);
197
- assert.equal(response.revokedInviteId, 47);
197
+ assert.equal(response.revokedInviteId, "47");
198
198
  });
199
199
 
200
200
  test("workspaceMembersService rejects invite operations when invitations are disabled", async () => {
@@ -230,8 +230,8 @@ test("workspaceMembersService rejects invite operations when invitations are dis
230
230
  () =>
231
231
  service.listInvites(
232
232
  {
233
- id: 7,
234
- ownerUserId: 9
233
+ id: "7",
234
+ ownerUserId: "9"
235
235
  },
236
236
  authorizedOptions(["workspace.members.view"])
237
237
  ),
@@ -245,10 +245,10 @@ test("workspaceMembersService.listMembers uses the resolved workspace directly",
245
245
  const response = await service.listMembers(workspace, authorizedOptions(["workspace.members.view"]));
246
246
 
247
247
  assert.deepEqual(response.workspace, {
248
- id: 7,
248
+ id: "7",
249
249
  slug: "tonymobily3",
250
250
  name: "TonyMobily3",
251
- ownerUserId: 9,
251
+ ownerUserId: "9",
252
252
  avatarUrl: ""
253
253
  });
254
254
  assert.equal(response.members.length, 1);
@@ -261,7 +261,7 @@ test("workspaceMembersService.updateMemberRole returns the refreshed member list
261
261
  const response = await service.updateMemberRole(
262
262
  workspace,
263
263
  {
264
- memberUserId: 11,
264
+ memberUserId: "11",
265
265
  roleSid: "admin"
266
266
  },
267
267
  authorizedOptions(["workspace.members.manage"])
@@ -274,10 +274,10 @@ test("workspaceMembersService.updateMemberRole returns the refreshed member list
274
274
  test("workspaceMembersService.removeMember marks membership revoked and returns refreshed members", async () => {
275
275
  let removed = false;
276
276
  const workspace = {
277
- id: 7,
277
+ id: "7",
278
278
  slug: "tonymobily3",
279
279
  name: "TonyMobily3",
280
- ownerUserId: 9,
280
+ ownerUserId: "9",
281
281
  avatarUrl: ""
282
282
  };
283
283
  const service = createService({
@@ -288,7 +288,7 @@ test("workspaceMembersService.removeMember marks membership revoked and returns
288
288
  ? []
289
289
  : [
290
290
  {
291
- userId: 11,
291
+ userId: "11",
292
292
  roleSid: "member",
293
293
  status: "active",
294
294
  displayName: "Alice",
@@ -300,8 +300,8 @@ test("workspaceMembersService.removeMember marks membership revoked and returns
300
300
  assert.equal(Number(workspaceId), 7);
301
301
  assert.equal(Number(userId), 11);
302
302
  return {
303
- workspaceId: 7,
304
- userId: 11,
303
+ workspaceId: "7",
304
+ userId: "11",
305
305
  roleSid: "member",
306
306
  status: "active"
307
307
  };
@@ -334,7 +334,7 @@ test("workspaceMembersService.removeMember marks membership revoked and returns
334
334
  const response = await service.removeMember(
335
335
  workspace,
336
336
  {
337
- memberUserId: 11
337
+ memberUserId: "11"
338
338
  },
339
339
  authorizedOptions(["workspace.members.manage"])
340
340
  );
@@ -344,10 +344,10 @@ test("workspaceMembersService.removeMember marks membership revoked and returns
344
344
 
345
345
  test("workspaceMembersService.removeMember rejects removing the owner", async () => {
346
346
  const workspace = {
347
- id: 7,
347
+ id: "7",
348
348
  slug: "tonymobily3",
349
349
  name: "TonyMobily3",
350
- ownerUserId: 9,
350
+ ownerUserId: "9",
351
351
  avatarUrl: ""
352
352
  };
353
353
  const service = createService({
@@ -359,8 +359,8 @@ test("workspaceMembersService.removeMember rejects removing the owner", async ()
359
359
  assert.equal(Number(workspaceId), 7);
360
360
  assert.equal(Number(userId), 9);
361
361
  return {
362
- workspaceId: 7,
363
- userId: 9,
362
+ workspaceId: "7",
363
+ userId: "9",
364
364
  roleSid: "owner",
365
365
  status: "active"
366
366
  };
@@ -389,7 +389,7 @@ test("workspaceMembersService.removeMember rejects removing the owner", async ()
389
389
  service.removeMember(
390
390
  workspace,
391
391
  {
392
- memberUserId: 9
392
+ memberUserId: "9"
393
393
  },
394
394
  authorizedOptions(["workspace.members.manage"])
395
395
  ),
@@ -9,8 +9,8 @@ test("workspacePendingInvitationsResource output normalizer shapes raw invite ro
9
9
  const result = workspacePendingInvitationsResource.operations.list.outputValidator.normalize({
10
10
  pendingInvites: [
11
11
  {
12
- id: 10,
13
- workspaceId: 3,
12
+ id: "10",
13
+ workspaceId: "3",
14
14
  workspaceSlug: "tonymobily3",
15
15
  workspaceName: "",
16
16
  workspaceAvatarUrl: "",
@@ -24,8 +24,8 @@ test("workspacePendingInvitationsResource output normalizer shapes raw invite ro
24
24
 
25
25
  assert.deepEqual(result, [
26
26
  {
27
- id: 10,
28
- workspaceId: 3,
27
+ id: "10",
28
+ workspaceId: "3",
29
29
  workspaceSlug: "tonymobily3",
30
30
  workspaceName: "tonymobily3",
31
31
  workspaceAvatarUrl: "",
@@ -59,8 +59,8 @@ test("listPendingInvitesForUser returns raw pending invite rows for the action l
59
59
  const { service } = createFixture({
60
60
  pendingInvitesByEmail: [
61
61
  {
62
- id: 10,
63
- workspaceId: 1,
62
+ id: "10",
63
+ workspaceId: "1",
64
64
  workspaceSlug: "tonymobily3",
65
65
  workspaceName: "TonyMobily3",
66
66
  workspaceAvatarUrl: "",
@@ -73,7 +73,7 @@ test("listPendingInvitesForUser returns raw pending invite rows for the action l
73
73
  });
74
74
 
75
75
  const pendingInvites = await service.listPendingInvitesForUser({
76
- id: 7,
76
+ id: "7",
77
77
  email: "chiaramobily@gmail.com"
78
78
  });
79
79
 
@@ -88,8 +88,8 @@ test("acceptInviteByToken accepts opaque invite token and resolves invite by dec
88
88
  const { service, calls } = createFixture({
89
89
  inviteByTokenHash: {
90
90
  [tokenHash]: {
91
- id: 44,
92
- workspaceId: 1,
91
+ id: "44",
92
+ workspaceId: "1",
93
93
  email: "chiaramobily@gmail.com",
94
94
  roleSid: "member",
95
95
  status: "pending",
@@ -101,7 +101,7 @@ test("acceptInviteByToken accepts opaque invite token and resolves invite by dec
101
101
 
102
102
  const response = await service.acceptInviteByToken({
103
103
  user: {
104
- id: 7,
104
+ id: "7",
105
105
  email: "chiaramobily@gmail.com",
106
106
  displayName: "Chiara"
107
107
  },
@@ -113,7 +113,7 @@ test("acceptInviteByToken accepts opaque invite token and resolves invite by dec
113
113
  assert.deepEqual(calls.acceptCalls, [44]);
114
114
  assert.deepEqual(calls.revokeCalls, []);
115
115
  assert.equal(response.decision, "accepted");
116
- assert.equal(response.workspaceId, 1);
116
+ assert.equal(response.workspaceId, "1");
117
117
  });
118
118
 
119
119
  test("refuseInviteByToken revokes the invite and returns refused", async () => {
@@ -122,8 +122,8 @@ test("refuseInviteByToken revokes the invite and returns refused", async () => {
122
122
  const { service, calls } = createFixture({
123
123
  inviteByTokenHash: {
124
124
  [tokenHash]: {
125
- id: 45,
126
- workspaceId: 1,
125
+ id: "45",
126
+ workspaceId: "1",
127
127
  email: "chiaramobily@gmail.com",
128
128
  roleSid: "member",
129
129
  status: "pending",
@@ -135,7 +135,7 @@ test("refuseInviteByToken revokes the invite and returns refused", async () => {
135
135
 
136
136
  const response = await service.refuseInviteByToken({
137
137
  user: {
138
- id: 7,
138
+ id: "7",
139
139
  email: "chiaramobily@gmail.com",
140
140
  displayName: "Chiara"
141
141
  },
@@ -147,5 +147,5 @@ test("refuseInviteByToken revokes the invite and returns refused", async () => {
147
147
  assert.deepEqual(calls.revokeCalls, [45]);
148
148
  assert.equal(calls.upsertCalls.length, 0);
149
149
  assert.equal(response.decision, "refused");
150
- assert.equal(response.workspaceId, 1);
150
+ assert.equal(response.workspaceId, "1");
151
151
  });
@@ -18,7 +18,7 @@ test("workspace route visibility resolver contributes workspace_user scope and a
18
18
  id: "user_42"
19
19
  },
20
20
  workspace: {
21
- id: 11
21
+ id: "11"
22
22
  }
23
23
  }
24
24
  });
@@ -26,8 +26,8 @@ test("workspace route visibility resolver contributes workspace_user scope and a
26
26
  assert.deepEqual(contribution, {
27
27
  scopeKind: "workspace_user",
28
28
  requiresActorScope: true,
29
- scopeOwnerId: 11,
30
- userOwnerId: "user_42"
29
+ scopeOwnerId: "11",
30
+ userId: "user_42"
31
31
  });
32
32
  });
33
33
 
@@ -44,7 +44,7 @@ test("workspace route visibility resolver keeps workspace-only visibility actor-
44
44
  visibility: "workspace",
45
45
  context: {
46
46
  workspace: {
47
- id: 11
47
+ id: "11"
48
48
  }
49
49
  }
50
50
  });
@@ -52,7 +52,7 @@ test("workspace route visibility resolver keeps workspace-only visibility actor-
52
52
  assert.deepEqual(contribution, {
53
53
  scopeKind: "workspace",
54
54
  requiresActorScope: false,
55
- scopeOwnerId: 11
55
+ scopeOwnerId: "11"
56
56
  });
57
57
  });
58
58
 
@@ -78,6 +78,6 @@ test("workspace route visibility resolver still marks workspace_user as actor-sc
78
78
  assert.deepEqual(contribution, {
79
79
  scopeKind: "workspace_user",
80
80
  requiresActorScope: true,
81
- userOwnerId: "user_99"
81
+ userId: "user_99"
82
82
  });
83
83
  });