@jskit-ai/users-core 0.1.33 → 0.1.36

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.
@@ -1,9 +1,9 @@
1
1
  export default Object.freeze({
2
2
  packageVersion: 1,
3
3
  packageId: "@jskit-ai/users-core",
4
- version: "0.1.33",
4
+ version: "0.1.36",
5
5
  kind: "runtime",
6
- description: "Users/workspace domain runtime plus HTTP routes for workspace, account, and console features.",
6
+ description: "Users/account runtime plus HTTP routes for account and console features.",
7
7
  dependsOn: [
8
8
  "@jskit-ai/auth-core",
9
9
  "@jskit-ai/database-runtime",
@@ -44,11 +44,11 @@ export default Object.freeze({
44
44
  {
45
45
  subpath: "./server",
46
46
  summary:
47
- "Exports UsersCoreServiceProvider, users/workspace/console repositories/services, feature route registration modules, and action definitions."
47
+ "Exports UsersCoreServiceProvider, users/console repositories and services, account feature route registration modules, and action definitions."
48
48
  },
49
49
  {
50
50
  subpath: "./shared",
51
- summary: "Exports shared users/workspace role and settings utilities."
51
+ summary: "Exports shared users settings and tenancy utilities."
52
52
  },
53
53
  {
54
54
  subpath: "./client",
@@ -62,66 +62,6 @@ export default Object.freeze({
62
62
  },
63
63
  server: {
64
64
  routes: [
65
- {
66
- method: "POST",
67
- path: "/api/workspaces",
68
- summary: "Create a workspace for the authenticated user."
69
- },
70
- {
71
- method: "GET",
72
- path: "/api/workspaces",
73
- summary: "List workspaces visible to authenticated user."
74
- },
75
- {
76
- method: "GET",
77
- path: "/api/workspace/invitations/pending",
78
- summary: "List pending workspace invitations for authenticated user."
79
- },
80
- {
81
- method: "POST",
82
- path: "/api/workspace/invitations/redeem",
83
- summary: "Accept or refuse a workspace invitation using an invite token."
84
- },
85
- {
86
- method: "GET",
87
- path: "/api/w/:workspaceSlug/settings",
88
- summary: "Get workspace settings and role catalog by workspace slug."
89
- },
90
- {
91
- method: "PATCH",
92
- path: "/api/w/:workspaceSlug/settings",
93
- summary: "Update workspace settings by workspace slug."
94
- },
95
- {
96
- method: "GET",
97
- path: "/api/w/:workspaceSlug/roles",
98
- summary: "Get role catalog by workspace slug."
99
- },
100
- {
101
- method: "GET",
102
- path: "/api/w/:workspaceSlug/members",
103
- summary: "List members by workspace slug."
104
- },
105
- {
106
- method: "PATCH",
107
- path: "/api/w/:workspaceSlug/members/:memberUserId/role",
108
- summary: "Update workspace member role by workspace slug."
109
- },
110
- {
111
- method: "GET",
112
- path: "/api/w/:workspaceSlug/invites",
113
- summary: "List workspace invites by workspace slug."
114
- },
115
- {
116
- method: "POST",
117
- path: "/api/w/:workspaceSlug/invites",
118
- summary: "Create workspace invite by workspace slug."
119
- },
120
- {
121
- method: "DELETE",
122
- path: "/api/w/:workspaceSlug/invites/:inviteId",
123
- summary: "Revoke workspace invite by workspace slug."
124
- },
125
65
  {
126
66
  method: "GET",
127
67
  path: "/api/settings",
@@ -198,36 +138,29 @@ export default Object.freeze({
198
138
  mutations: {
199
139
  dependencies: {
200
140
  runtime: {
201
- "@jskit-ai/auth-core": "0.1.23",
202
- "@jskit-ai/database-runtime": "0.1.24",
203
- "@jskit-ai/http-runtime": "0.1.23",
204
- "@jskit-ai/kernel": "0.1.24",
205
- "@jskit-ai/uploads-runtime": "0.1.2",
141
+ "@jskit-ai/auth-core": "0.1.25",
142
+ "@jskit-ai/database-runtime": "0.1.26",
143
+ "@jskit-ai/http-runtime": "0.1.25",
144
+ "@jskit-ai/kernel": "0.1.26",
145
+ "@jskit-ai/uploads-runtime": "0.1.4",
206
146
  "@fastify/type-provider-typebox": "^6.1.0",
207
- "typebox": "^1.0.81"
147
+ typebox: "^1.0.81"
208
148
  },
209
149
  dev: {}
210
150
  },
211
151
  packageJson: {
212
- scripts: {
213
- "server:app": "SERVER_SURFACE=app node ./bin/server.js",
214
- "server:admin": "SERVER_SURFACE=admin node ./bin/server.js",
215
- "dev:app": "VITE_SURFACE=app vite",
216
- "dev:admin": "VITE_SURFACE=admin vite",
217
- "build:app": "VITE_SURFACE=app vite build",
218
- "build:admin": "VITE_SURFACE=admin vite build"
219
- }
152
+ scripts: {}
220
153
  },
221
154
  procfile: {},
222
155
  files: [
223
156
  {
224
157
  op: "install-migration",
225
- from: "templates/migrations/users_core_initial.cjs",
158
+ from: "templates/migrations/users_core_generic_initial.cjs",
226
159
  toDir: "migrations",
227
160
  extension: ".cjs",
228
- reason: "Install users/workspace core schema migration.",
161
+ reason: "Install users/account core schema migration.",
229
162
  category: "migration",
230
- id: "users-core-initial-schema"
163
+ id: "users-core-generic-initial-schema"
231
164
  },
232
165
  {
233
166
  op: "install-migration",
@@ -243,36 +176,10 @@ export default Object.freeze({
243
176
  from: "templates/migrations/users_core_console_owner.cjs",
244
177
  toDir: "migrations",
245
178
  extension: ".cjs",
246
- reason: "Install users/workspace console owner migration.",
179
+ reason: "Install console owner migration.",
247
180
  category: "migration",
248
181
  id: "users-core-console-owner-schema"
249
182
  },
250
- {
251
- op: "install-migration",
252
- from: "templates/migrations/users_core_workspace_settings_single_name_source.cjs",
253
- toDir: "migrations",
254
- extension: ".cjs",
255
- reason: "Remove workspace_settings name/avatar fields so workspace identity data comes from workspaces only.",
256
- category: "migration",
257
- id: "users-core-workspace-settings-single-name-source"
258
- },
259
- {
260
- op: "install-migration",
261
- from: "templates/migrations/users_core_workspaces_drop_color.cjs",
262
- toDir: "migrations",
263
- extension: ".cjs",
264
- reason: "Drop legacy workspaces.color now that workspace theme colors live in workspace_settings.",
265
- category: "migration",
266
- id: "users-core-workspaces-drop-color"
267
- },
268
- {
269
- from: "templates/packages/main/src/shared/resources/workspaceSettingsFields.js",
270
- to: "packages/main/src/shared/resources/workspaceSettingsFields.js",
271
- preserveOnRemove: true,
272
- reason: "Install app-owned workspace settings field definitions.",
273
- category: "users-core",
274
- id: "users-core-app-owned-workspace-settings-fields"
275
- },
276
183
  {
277
184
  from: "templates/packages/main/src/shared/resources/consoleSettingsFields.js",
278
185
  to: "packages/main/src/shared/resources/consoleSettingsFields.js",
@@ -288,14 +195,6 @@ export default Object.freeze({
288
195
  reason: "Install app-owned user settings field definitions.",
289
196
  category: "users-core",
290
197
  id: "users-core-app-owned-user-settings-fields"
291
- },
292
- {
293
- from: "templates/config/roles.js",
294
- to: "config/roles.js",
295
- preserveOnRemove: true,
296
- reason: "Install app-owned role catalog in a dedicated config file.",
297
- category: "users-core",
298
- id: "users-core-app-owned-role-catalog-config"
299
198
  }
300
199
  ],
301
200
  text: [
@@ -308,16 +207,6 @@ export default Object.freeze({
308
207
  category: "runtime-config",
309
208
  id: "users-core-auth-profile-mode"
310
209
  },
311
- {
312
- op: "append-text",
313
- file: "packages/main/src/shared/index.js",
314
- position: "top",
315
- skipIfContains: "import \"./resources/workspaceSettingsFields.js\";",
316
- value: "import \"./resources/workspaceSettingsFields.js\";\n",
317
- reason: "Load app-owned workspace settings field definitions inside the main shared module.",
318
- category: "users-core",
319
- id: "users-core-main-shared-workspace-settings-field-import"
320
- },
321
210
  {
322
211
  op: "append-text",
323
212
  file: "packages/main/src/shared/index.js",
@@ -357,125 +246,7 @@ export default Object.freeze({
357
246
  reason: "Ensure server runtime loads app-owned shared settings field registration.",
358
247
  category: "users-core",
359
248
  id: "users-core-server-import-main-shared"
360
- },
361
- {
362
- op: "append-text",
363
- file: "config/public.js",
364
- position: "top",
365
- skipIfContains: "import { roleCatalog } from \"./roles.js\";",
366
- value: "import { roleCatalog } from \"./roles.js\";\n",
367
- reason: "Load app-owned role catalog from dedicated config file.",
368
- category: "users-core",
369
- id: "users-core-role-catalog-public-import"
370
- },
371
- {
372
- op: "append-text",
373
- file: "config/public.js",
374
- position: "top",
375
- skipIfContains: "import { surfaceAccessPolicies } from \"./surfaceAccessPolicies.js\";",
376
- value: "import { surfaceAccessPolicies } from \"./surfaceAccessPolicies.js\";\n",
377
- reason: "Load app-owned surface access policy catalog from dedicated config file.",
378
- category: "users-core",
379
- id: "users-core-surface-access-policies-public-import"
380
- },
381
- {
382
- op: "append-text",
383
- file: "config/surfaceAccessPolicies.js",
384
- position: "top",
385
- skipIfContains: "export const surfaceAccessPolicies = {};",
386
- value: "export const surfaceAccessPolicies = {};\n\n",
387
- reason: "Initialize app-owned surface access policy config if missing.",
388
- category: "users-core",
389
- id: "users-core-surface-access-policies-config-init"
390
- },
391
- {
392
- op: "append-text",
393
- file: "config/surfaceAccessPolicies.js",
394
- position: "bottom",
395
- skipIfContains: "surfaceAccessPolicies.workspace_member = {",
396
- value: "\nsurfaceAccessPolicies.workspace_member = {\n requireAuth: true,\n requireWorkspaceMembership: true\n};\n",
397
- reason: "Register workspace-member surface access policy for workspace surfaces.",
398
- category: "users-core",
399
- id: "users-core-surface-access-policies-workspace-member"
400
- },
401
- {
402
- op: "append-text",
403
- file: "config/public.js",
404
- position: "bottom",
405
- skipIfContains: "config.surfaceDefinitions.app = {",
406
- value:
407
- "\nconfig.surfaceDefinitions.app = {\n id: \"app\",\n label: \"App\",\n pagesRoot: \"w/[workspaceSlug]\",\n enabled: true,\n requiresAuth: true,\n requiresWorkspace: true,\n accessPolicyId: \"workspace_member\",\n origin: \"\"\n};\n\nconfig.surfaceDefinitions.admin = {\n id: \"admin\",\n label: \"Admin\",\n pagesRoot: \"w/[workspaceSlug]/admin\",\n enabled: true,\n requiresAuth: true,\n requiresWorkspace: true,\n accessPolicyId: \"workspace_member\",\n origin: \"\"\n};\n",
408
- reason: "Append workspace surface topology when tenancy enables workspace routing.",
409
- category: "users-core",
410
- id: "users-core-surface-config-workspace",
411
- when: {
412
- config: "tenancyMode",
413
- in: ["personal", "workspaces"]
414
- }
415
- },
416
- {
417
- op: "append-text",
418
- file: "config/public.js",
419
- position: "bottom",
420
- skipIfContains: "config.workspaceSwitching =",
421
- value:
422
- "\nconfig.workspaceSwitching = true;\nconfig.workspaceInvitations = {\n enabled: true,\n allowInPersonalMode: true\n};\nconfig.assistantEnabled = false;\nconfig.assistantRequiredPermission = \"\";\nconfig.socialEnabled = false;\nconfig.socialFederationEnabled = false;\n",
423
- reason: "Append default public users/workspace feature toggles into app-owned config.",
424
- category: "users-core",
425
- id: "users-core-public-config"
426
- },
427
- {
428
- op: "append-text",
429
- file: "config/public.js",
430
- position: "bottom",
431
- skipIfContains: "config.roleCatalog = roleCatalog;",
432
- value: "\nconfig.roleCatalog = roleCatalog;\n",
433
- reason: "Bind app-owned role catalog onto public config.",
434
- category: "users-core",
435
- id: "users-core-role-catalog-public-config"
436
- },
437
- {
438
- op: "append-text",
439
- file: "config/public.js",
440
- position: "bottom",
441
- skipIfContains: "config.surfaceAccessPolicies = surfaceAccessPolicies;",
442
- value: "\nconfig.surfaceAccessPolicies = surfaceAccessPolicies;\n",
443
- reason: "Bind app-owned surface access policies onto public config.",
444
- category: "users-core",
445
- id: "users-core-surface-access-policies-public-config"
446
- },
447
- {
448
- op: "append-text",
449
- file: "config/server.js",
450
- position: "bottom",
451
- skipIfContains: "config.workspaceColor =",
452
- value: "\nconfig.workspaceColor = \"#1867C0\";\n",
453
- reason: "Append default server-only users/workspace settings into app-owned config.",
454
- category: "users-core",
455
- id: "users-core-server-config"
456
- },
457
- {
458
- op: "append-text",
459
- file: "config/server.js",
460
- position: "bottom",
461
- skipIfContains: "config.workspaceSettings =",
462
- value:
463
- "\nconfig.workspaceSettings = {\n defaults: {\n invitesEnabled: true\n }\n};\n",
464
- reason: "Append app-owned workspace settings defaults into the server config.",
465
- category: "users-core",
466
- id: "users-core-workspace-settings-server-config"
467
- },
468
- {
469
- op: "append-text",
470
- file: "config/server.js",
471
- position: "bottom",
472
- skipIfContains: "config.workspaceMembers =",
473
- value:
474
- "\nconfig.workspaceMembers = {\n defaults: {\n inviteExpiresInMs: 604800000\n }\n};\n",
475
- reason: "Append app-owned workspace member invite policy defaults into the server config.",
476
- category: "users-core",
477
- id: "users-core-workspace-members-server-config"
478
- },
249
+ }
479
250
  ]
480
251
  }
481
252
  });
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@jskit-ai/users-core",
3
- "version": "0.1.33",
3
+ "version": "0.1.36",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
7
7
  },
8
8
  "exports": {
9
- "./server/support/workspaceActionSurfaces": "./src/server/support/workspaceActionSurfaces.js",
9
+ "./server/UsersWorkspacesServiceProvider": "./src/server/UsersWorkspacesServiceProvider.js",
10
10
  "./server/support/workspaceRouteInput": "./src/server/support/workspaceRouteInput.js",
11
11
  "./server/support/resolveWorkspace": "./src/server/support/resolveWorkspace.js",
12
12
  "./server/validators/routeParamsValidator": "./src/server/common/validators/routeParamsValidator.js",
@@ -24,11 +24,11 @@
24
24
  "./shared/resources/consoleSettingsFields": "./src/shared/resources/consoleSettingsFields.js"
25
25
  },
26
26
  "dependencies": {
27
- "@jskit-ai/auth-core": "0.1.23",
28
- "@jskit-ai/database-runtime": "0.1.24",
29
- "@jskit-ai/http-runtime": "0.1.23",
30
- "@jskit-ai/kernel": "0.1.24",
31
- "@jskit-ai/uploads-runtime": "0.1.2",
27
+ "@jskit-ai/auth-core": "0.1.25",
28
+ "@jskit-ai/database-runtime": "0.1.26",
29
+ "@jskit-ai/http-runtime": "0.1.25",
30
+ "@jskit-ai/kernel": "0.1.26",
31
+ "@jskit-ai/uploads-runtime": "0.1.4",
32
32
  "@fastify/type-provider-typebox": "^6.1.0",
33
33
  "typebox": "^1.0.81"
34
34
  }
@@ -1,14 +1,4 @@
1
1
  import { USERS_SHARED_API } from "../shared/index.js";
2
- import { bootWorkspaceDirectoryRoutes } from "./workspaceDirectory/bootWorkspaceDirectoryRoutes.js";
3
- import { registerWorkspaceDirectory } from "./workspaceDirectory/registerWorkspaceDirectory.js";
4
- import {
5
- registerWorkspacePendingInvitations
6
- } from "./workspacePendingInvitations/registerWorkspacePendingInvitations.js";
7
- import { bootWorkspacePendingInvitations } from "./workspacePendingInvitations/bootWorkspacePendingInvitations.js";
8
- import { registerWorkspaceMembers } from "./workspaceMembers/registerWorkspaceMembers.js";
9
- import { bootWorkspaceMembers } from "./workspaceMembers/bootWorkspaceMembers.js";
10
- import { registerWorkspaceSettings } from "./workspaceSettings/registerWorkspaceSettings.js";
11
- import { bootWorkspaceSettings } from "./workspaceSettings/bootWorkspaceSettings.js";
12
2
  import { bootAccountProfileRoutes } from "./accountProfile/bootAccountProfileRoutes.js";
13
3
  import { bootAccountPreferencesRoutes } from "./accountPreferences/bootAccountPreferencesRoutes.js";
14
4
  import { bootAccountNotificationsRoutes } from "./accountNotifications/bootAccountNotificationsRoutes.js";
@@ -16,14 +6,13 @@ import { bootAccountSecurityRoutes } from "./accountSecurity/bootAccountSecurity
16
6
  import { bootConsoleSettingsRoutes } from "./consoleSettings/bootConsoleSettingsRoutes.js";
17
7
  import { registerSharedApi } from "./common/registerSharedApi.js";
18
8
  import { registerCommonRepositories } from "./common/registerCommonRepositories.js";
19
- import { registerWorkspaceCore } from "./registerWorkspaceCore.js";
20
- import { registerWorkspaceBootstrap } from "./registerWorkspaceBootstrap.js";
9
+ import { registerUsersCore } from "./registerUsersCore.js";
10
+ import { registerUsersBootstrap } from "./registerUsersBootstrap.js";
21
11
  import { registerAccountPreferences } from "./accountPreferences/registerAccountPreferences.js";
22
12
  import { registerAccountNotifications } from "./accountNotifications/registerAccountNotifications.js";
23
13
  import { registerAccountProfile } from "./accountProfile/registerAccountProfile.js";
24
14
  import { registerAccountSecurity } from "./accountSecurity/registerAccountSecurity.js";
25
15
  import { registerConsoleSettings } from "./consoleSettings/registerConsoleSettings.js";
26
- import { registerUsersCoreActionSurfaceSources } from "./support/workspaceActionSurfaces.js";
27
16
 
28
17
  class UsersCoreServiceProvider {
29
18
  static id = "users.core";
@@ -31,15 +20,10 @@ class UsersCoreServiceProvider {
31
20
  static dependsOn = ["runtime.server", "runtime.actions", "runtime.database", "runtime.storage", "auth.provider", "runtime.uploads"];
32
21
 
33
22
  register(app) {
34
- registerUsersCoreActionSurfaceSources(app);
35
23
  registerSharedApi(app, USERS_SHARED_API);
36
24
  registerCommonRepositories(app);
37
- registerWorkspaceCore(app);
38
- registerWorkspaceBootstrap(app);
39
- registerWorkspaceDirectory(app);
40
- registerWorkspaceMembers(app);
41
- registerWorkspaceSettings(app);
42
- registerWorkspacePendingInvitations(app);
25
+ registerUsersCore(app);
26
+ registerUsersBootstrap(app);
43
27
 
44
28
  registerAccountProfile(app);
45
29
  registerAccountPreferences(app);
@@ -49,14 +33,6 @@ class UsersCoreServiceProvider {
49
33
  }
50
34
 
51
35
  async boot(app) {
52
- if (app.make("users.workspace.enabled") === true) {
53
- bootWorkspaceDirectoryRoutes(app);
54
- if (app.make("users.workspace.invitations.enabled") === true) {
55
- bootWorkspacePendingInvitations(app);
56
- }
57
- bootWorkspaceSettings(app);
58
- bootWorkspaceMembers(app);
59
- }
60
36
  bootAccountProfileRoutes(app);
61
37
  bootAccountPreferencesRoutes(app);
62
38
  bootAccountNotificationsRoutes(app);
@@ -0,0 +1,44 @@
1
+ import { bootWorkspaceDirectoryRoutes } from "./workspaceDirectory/bootWorkspaceDirectoryRoutes.js";
2
+ import { registerWorkspaceDirectory } from "./workspaceDirectory/registerWorkspaceDirectory.js";
3
+ import {
4
+ registerWorkspacePendingInvitations
5
+ } from "./workspacePendingInvitations/registerWorkspacePendingInvitations.js";
6
+ import { bootWorkspacePendingInvitations } from "./workspacePendingInvitations/bootWorkspacePendingInvitations.js";
7
+ import { registerWorkspaceMembers } from "./workspaceMembers/registerWorkspaceMembers.js";
8
+ import { bootWorkspaceMembers } from "./workspaceMembers/bootWorkspaceMembers.js";
9
+ import { registerWorkspaceSettings } from "./workspaceSettings/registerWorkspaceSettings.js";
10
+ import { bootWorkspaceSettings } from "./workspaceSettings/bootWorkspaceSettings.js";
11
+ import { registerWorkspaceRepositories } from "./registerWorkspaceRepositories.js";
12
+ import { registerWorkspaceCore } from "./registerWorkspaceCore.js";
13
+ import { registerWorkspaceBootstrap } from "./registerWorkspaceBootstrap.js";
14
+
15
+ class UsersWorkspacesServiceProvider {
16
+ static id = "workspaces.core";
17
+
18
+ static dependsOn = ["users.core"];
19
+
20
+ register(app) {
21
+ registerWorkspaceRepositories(app);
22
+ registerWorkspaceCore(app);
23
+ registerWorkspaceBootstrap(app);
24
+ registerWorkspaceDirectory(app);
25
+ registerWorkspaceMembers(app);
26
+ registerWorkspaceSettings(app);
27
+ registerWorkspacePendingInvitations(app);
28
+ }
29
+
30
+ async boot(app) {
31
+ if (app.make("users.workspace.enabled") !== true) {
32
+ return;
33
+ }
34
+
35
+ bootWorkspaceDirectoryRoutes(app);
36
+ if (app.make("users.workspace.invitations.enabled") === true) {
37
+ bootWorkspacePendingInvitations(app);
38
+ }
39
+ bootWorkspaceSettings(app);
40
+ bootWorkspaceMembers(app);
41
+ }
42
+ }
43
+
44
+ export { UsersWorkspacesServiceProvider };
@@ -1,8 +1,5 @@
1
1
  import { createRepository as createUsersRepository } from "./repositories/usersRepository.js";
2
2
  import { createRepository as createUserSettingsRepository } from "./repositories/userSettingsRepository.js";
3
- import { createRepository as createWorkspacesRepository } from "./repositories/workspacesRepository.js";
4
- import { createRepository as createWorkspaceMembershipsRepository } from "./repositories/workspaceMembershipsRepository.js";
5
- import { createRepository as createWorkspaceInvitesRepository } from "./repositories/workspaceInvitesRepository.js";
6
3
  import { createRepository as createConsoleSettingsRepository } from "../consoleSettings/consoleSettingsRepository.js";
7
4
 
8
5
  function registerCommonRepositories(app) {
@@ -19,22 +16,6 @@ function registerCommonRepositories(app) {
19
16
  const knex = scope.make("jskit.database.knex");
20
17
  return createUserSettingsRepository(knex);
21
18
  });
22
-
23
- app.singleton("workspacesRepository", (scope) => {
24
- const knex = scope.make("jskit.database.knex");
25
- return createWorkspacesRepository(knex);
26
- });
27
-
28
- app.singleton("workspaceMembershipsRepository", (scope) => {
29
- const knex = scope.make("jskit.database.knex");
30
- return createWorkspaceMembershipsRepository(knex);
31
- });
32
-
33
- app.singleton("workspaceInvitesRepository", (scope) => {
34
- const knex = scope.make("jskit.database.knex");
35
- return createWorkspaceInvitesRepository(knex);
36
- });
37
-
38
19
  app.singleton("consoleSettingsRepository", (scope) => {
39
20
  const knex = scope.make("jskit.database.knex");
40
21
  return createConsoleSettingsRepository(knex);
@@ -15,7 +15,6 @@ function mapRow(row) {
15
15
 
16
16
  const mapped = {
17
17
  userId: Number(row.user_id),
18
- lastActiveWorkspaceId: row.last_active_workspace_id == null ? null : Number(row.last_active_workspace_id),
19
18
  passwordSignInEnabled: row.password_sign_in_enabled == null ? true : Boolean(row.password_sign_in_enabled),
20
19
  passwordSetupRequired: row.password_setup_required == null ? false : Boolean(row.password_setup_required),
21
20
  createdAt: toIsoString(row.created_at),
@@ -48,7 +47,6 @@ function normalizeBoolean(value, fallback = false) {
48
47
  function createInsertPayload(userId) {
49
48
  const payload = {
50
49
  user_id: Number(userId),
51
- last_active_workspace_id: null,
52
50
  password_sign_in_enabled: DEFAULT_USER_SETTINGS.passwordSignInEnabled,
53
51
  password_setup_required: DEFAULT_USER_SETTINGS.passwordSetupRequired,
54
52
  created_at: nowDb(),
@@ -127,10 +125,6 @@ function createRepository(knex) {
127
125
  if (Object.hasOwn(source, "passwordSetupRequired")) {
128
126
  dbPatch.password_setup_required = normalizeBoolean(source.passwordSetupRequired, ensured.passwordSetupRequired);
129
127
  }
130
- if (Object.hasOwn(source, "lastActiveWorkspaceId")) {
131
- dbPatch.last_active_workspace_id = source.lastActiveWorkspaceId == null ? null : Number(source.lastActiveWorkspaceId);
132
- }
133
-
134
128
  await client("user_settings").where({ user_id: Number(userId) }).update(dbPatch);
135
129
  return findByUserId(userId, { trx: client });
136
130
  }
@@ -160,10 +154,6 @@ function createRepository(knex) {
160
154
  return patchUserSettings(userId, { passwordSetupRequired: required }, options);
161
155
  }
162
156
 
163
- async function updateLastActiveWorkspaceId(userId, workspaceId, options = {}) {
164
- return patchUserSettings(userId, { lastActiveWorkspaceId: workspaceId }, options);
165
- }
166
-
167
157
  return Object.freeze({
168
158
  findByUserId,
169
159
  ensureForUserId,
@@ -171,8 +161,7 @@ function createRepository(knex) {
171
161
  updatePreferences,
172
162
  updateNotifications,
173
163
  updatePasswordSignInEnabled,
174
- updatePasswordSetupRequired,
175
- updateLastActiveWorkspaceId
164
+ updatePasswordSetupRequired
176
165
  });
177
166
  }
178
167
 
@@ -0,0 +1,22 @@
1
+ import { registerBootstrapPayloadContributor } from "@jskit-ai/kernel/server/runtime";
2
+ import { resolveAppConfig } from "@jskit-ai/kernel/server/support";
3
+ import { createUsersBootstrapContributor } from "./usersBootstrapContributor.js";
4
+
5
+ function registerUsersBootstrap(app) {
6
+ if (!app || typeof app.singleton !== "function") {
7
+ throw new Error("registerUsersBootstrap requires application singleton().");
8
+ }
9
+
10
+ registerBootstrapPayloadContributor(app, "users.core.bootstrap.payloadContributor", (scope) => {
11
+ return createUsersBootstrapContributor({
12
+ usersRepository: scope.make("usersRepository"),
13
+ userSettingsRepository: scope.make("userSettingsRepository"),
14
+ appConfig: resolveAppConfig(scope),
15
+ tenancyProfile: scope.make("users.tenancy.profile"),
16
+ authService: scope.make("authService"),
17
+ consoleService: scope.has("consoleService") ? scope.make("consoleService") : null
18
+ });
19
+ });
20
+ }
21
+
22
+ export { registerUsersBootstrap };
@@ -0,0 +1,30 @@
1
+ import { resolveAppConfig } from "@jskit-ai/kernel/server/support";
2
+ import { resolveTenancyProfile } from "../shared/tenancyProfile.js";
3
+ import { createService as createAuthProfileSyncService } from "./common/services/authProfileSyncService.js";
4
+ import { registerUsersCoreActionSurfaceSources } from "./support/workspaceActionSurfaces.js";
5
+
6
+ function registerUsersCore(app) {
7
+ if (!app || typeof app.singleton !== "function") {
8
+ throw new Error("registerUsersCore requires application singleton().");
9
+ }
10
+
11
+ registerUsersCoreActionSurfaceSources(app);
12
+
13
+ app.singleton("users.profile.sync.service", (scope) => {
14
+ return createAuthProfileSyncService({
15
+ usersRepository: scope.make("usersRepository"),
16
+ userSettingsRepository: scope.make("userSettingsRepository"),
17
+ workspaceProvisioningService:
18
+ typeof scope.has === "function" && scope.has("users.workspace.service")
19
+ ? scope.make("users.workspace.service")
20
+ : null
21
+ });
22
+ });
23
+
24
+ app.singleton("users.tenancy.profile", (scope) => {
25
+ const appConfig = resolveAppConfig(scope);
26
+ return resolveTenancyProfile(appConfig);
27
+ });
28
+ }
29
+
30
+ export { registerUsersCore };
@@ -8,7 +8,7 @@ function registerWorkspaceBootstrap(app) {
8
8
  throw new Error("registerWorkspaceBootstrap requires application singleton().");
9
9
  }
10
10
 
11
- registerBootstrapPayloadContributor(app, "users.core.workspace.bootstrap.payloadContributor", (scope) => {
11
+ registerBootstrapPayloadContributor(app, "workspaces.core.bootstrap.payloadContributor", (scope) => {
12
12
  const workspaceInvitationsEnabled = scope.make("users.workspace.invitations.enabled");
13
13
 
14
14
  return createWorkspaceBootstrapContributor({
@@ -18,11 +18,8 @@ function registerWorkspaceBootstrap(app) {
18
18
  : null,
19
19
  workspaceInvitationsEnabled,
20
20
  usersRepository: scope.make("usersRepository"),
21
- userSettingsRepository: scope.make("userSettingsRepository"),
22
21
  appConfig: resolveAppConfig(scope),
23
- tenancyProfile: scope.make("users.tenancy.profile"),
24
- authService: scope.make("authService"),
25
- consoleService: scope.has("consoleService") ? scope.make("consoleService") : null
22
+ tenancyProfile: scope.make("users.tenancy.profile")
26
23
  });
27
24
  });
28
25
  }