@jskit-ai/agent-docs 0.1.131 → 0.1.133
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/guide/agent/app-extras/assistant.md +29 -605
- package/guide/agent/app-extras/mobile-capacitor.md +29 -362
- package/guide/agent/app-extras/realtime.md +29 -277
- package/guide/agent/app-setup/a-more-interesting-shell.md +44 -815
- package/guide/agent/app-setup/authentication.md +43 -1073
- package/guide/agent/app-setup/console.md +26 -298
- package/guide/agent/app-setup/database-layer.md +110 -790
- package/guide/agent/app-setup/existing-application-migration.md +273 -0
- package/guide/agent/app-setup/initial-scaffolding.md +50 -784
- package/guide/agent/app-setup/multi-homing.md +39 -712
- package/guide/agent/app-setup/quickstart.md +43 -179
- package/guide/agent/app-setup/users.md +34 -353
- package/guide/agent/index.md +17 -23
- package/package.json +2 -2
- package/patterns/INDEX.md +7 -7
- package/patterns/child-cruds.md +3 -3
- package/patterns/client-requests.md +6 -6
- package/patterns/crud-authoring.md +94 -0
- package/patterns/crud-links.md +1 -1
- package/patterns/feature-package/PATTERN.md +108 -0
- package/patterns/feature-package/example/booking-engine/package.json +48 -0
- package/patterns/feature-package/example/booking-engine/src/server/BookingEngineProvider.js +33 -0
- package/patterns/feature-package/example/booking-engine/src/server/actions.js +26 -0
- package/patterns/feature-package/example/booking-engine/src/server/inputSchemas.js +19 -0
- package/patterns/feature-package/example/variations/AvailabilityEngineProvider.js +31 -0
- package/patterns/feature-package/example/variations/InvoiceRollupProvider.js +36 -0
- package/patterns/feature-package/example/variations/customKnexRepository.js +34 -0
- package/patterns/feature-package/example/variations/orchestratorService.js +23 -0
- package/patterns/filters.md +8 -8
- package/patterns/live-actions.md +5 -18
- package/patterns/minimal-foundation/PATTERN.md +98 -0
- package/patterns/minimal-foundation/example/.nvmrc +1 -0
- package/patterns/minimal-foundation/example/AGENTS.md +17 -0
- package/patterns/minimal-foundation/example/Procfile +2 -0
- package/patterns/minimal-foundation/example/app.json +14 -0
- package/patterns/minimal-foundation/example/bin/develop.js +71 -0
- package/patterns/minimal-foundation/example/bin/server.js +8 -0
- package/patterns/minimal-foundation/example/config/public.js +40 -0
- package/patterns/minimal-foundation/example/config/server.js +1 -0
- package/patterns/minimal-foundation/example/config/surfaceAccessPolicies.js +3 -0
- package/patterns/minimal-foundation/example/eslint.config.mjs +19 -0
- package/patterns/minimal-foundation/example/favicon.svg +7 -0
- package/patterns/minimal-foundation/example/gitignore +9 -0
- package/patterns/minimal-foundation/example/index.html +13 -0
- package/patterns/minimal-foundation/example/jsconfig.json +8 -0
- package/patterns/minimal-foundation/example/package.json +57 -0
- package/patterns/minimal-foundation/example/packages/main/package.json +42 -0
- package/patterns/minimal-foundation/example/packages/main/src/shared/index.js +10 -0
- package/patterns/minimal-foundation/example/packages/main/src/shared/schemas/index.js +22 -0
- package/patterns/minimal-foundation/example/playwright.config.mjs +31 -0
- package/patterns/minimal-foundation/example/server/lib/runtimeEnv.js +45 -0
- package/patterns/minimal-foundation/example/server/lib/surfaceRuntime.js +10 -0
- package/patterns/minimal-foundation/example/server.js +195 -0
- package/patterns/minimal-foundation/example/src/App.vue +13 -0
- package/patterns/minimal-foundation/example/src/main.js +85 -0
- package/patterns/minimal-foundation/example/src/pages/home/index.vue +48 -0
- package/patterns/minimal-foundation/example/src/pages/home.vue +13 -0
- package/patterns/minimal-foundation/example/src/views/NotFound.vue +13 -0
- package/patterns/minimal-foundation/example/tests/client/smoke.vitest.js +7 -0
- package/patterns/minimal-foundation/example/tests/e2e/base-shell.spec.ts +23 -0
- package/patterns/minimal-foundation/example/tests/server/smoke.test.js +16 -0
- package/patterns/minimal-foundation/example/vite.config.mjs +81 -0
- package/patterns/page-scaffolding.md +20 -17
- package/patterns/placements.md +17 -15
- package/patterns/row-policies.md +4 -5
- package/patterns/server-search.md +3 -3
- package/patterns/shell-foundation/PATTERN.md +104 -0
- package/patterns/shell-foundation/example/.nvmrc +1 -0
- package/patterns/shell-foundation/example/AGENTS.md +17 -0
- package/patterns/shell-foundation/example/Procfile +2 -0
- package/patterns/shell-foundation/example/app.json +14 -0
- package/patterns/shell-foundation/example/bin/develop.js +71 -0
- package/patterns/shell-foundation/example/bin/server.js +8 -0
- package/patterns/shell-foundation/example/config/public.js +40 -0
- package/patterns/shell-foundation/example/config/server.js +1 -0
- package/patterns/shell-foundation/example/config/surfaceAccessPolicies.js +3 -0
- package/patterns/shell-foundation/example/eslint.config.mjs +19 -0
- package/patterns/shell-foundation/example/favicon.svg +7 -0
- package/patterns/shell-foundation/example/gitignore +9 -0
- package/patterns/shell-foundation/example/index.html +13 -0
- package/patterns/shell-foundation/example/jsconfig.json +8 -0
- package/patterns/shell-foundation/example/package.json +59 -0
- package/patterns/shell-foundation/example/packages/main/package.json +56 -0
- package/patterns/shell-foundation/example/packages/main/src/client/index.js +9 -0
- package/patterns/shell-foundation/example/packages/main/src/client/providers/MainClientProvider.js +18 -0
- package/patterns/shell-foundation/example/packages/main/src/shared/index.js +10 -0
- package/patterns/shell-foundation/example/packages/main/src/shared/schemas/index.js +22 -0
- package/patterns/shell-foundation/example/playwright.config.mjs +31 -0
- package/patterns/shell-foundation/example/server/lib/runtimeEnv.js +45 -0
- package/patterns/shell-foundation/example/server/lib/surfaceRuntime.js +10 -0
- package/patterns/shell-foundation/example/server.js +195 -0
- package/patterns/shell-foundation/example/src/App.vue +11 -0
- package/patterns/shell-foundation/example/src/components/ShellLayout.vue +12 -0
- package/patterns/shell-foundation/example/src/components/menus/MenuLinkItem.vue +30 -0
- package/patterns/shell-foundation/example/src/components/menus/SurfaceAwareMenuLinkItem.vue +42 -0
- package/patterns/shell-foundation/example/src/components/menus/TabLinkItem.vue +42 -0
- package/patterns/shell-foundation/example/src/error.js +19 -0
- package/patterns/shell-foundation/example/src/main.js +85 -0
- package/patterns/shell-foundation/example/src/pages/home/index.vue +116 -0
- package/patterns/shell-foundation/example/src/pages/home/settings/general/index.vue +40 -0
- package/patterns/shell-foundation/example/src/pages/home/settings/index.vue +7 -0
- package/patterns/shell-foundation/example/src/pages/home/settings.vue +109 -0
- package/patterns/shell-foundation/example/src/pages/home.vue +20 -0
- package/patterns/shell-foundation/example/src/placement.js +56 -0
- package/patterns/shell-foundation/example/src/placementTopology.js +149 -0
- package/patterns/shell-foundation/example/src/views/NotFound.vue +13 -0
- package/patterns/shell-foundation/example/tests/client/smoke.vitest.js +7 -0
- package/patterns/shell-foundation/example/tests/e2e/adaptive-shell.spec.ts +10 -0
- package/patterns/shell-foundation/example/tests/e2e/base-shell.spec.ts +23 -0
- package/patterns/shell-foundation/example/tests/server/smoke.test.js +16 -0
- package/patterns/shell-foundation/example/vite.config.mjs +81 -0
- package/patterns/ui-contract.md +56 -0
- package/patterns/ui-testing.md +10 -12
- package/reference/autogen/KERNEL_MAP.md +29 -107
- package/reference/autogen/PATTERN_INDEX.md +230 -0
- package/reference/autogen/README.md +4 -8
- package/reference/autogen/packages/agent-docs.md +259 -0
- package/reference/autogen/packages/assistant-core.md +3 -3
- package/reference/autogen/packages/assistant-runtime.md +32 -17
- package/reference/autogen/packages/auth-core.md +31 -33
- package/reference/autogen/packages/auth-provider-local-core.md +4 -12
- package/reference/autogen/packages/auth-provider-local-db-core.md +4 -4
- package/reference/autogen/packages/auth-provider-supabase-core.md +14 -18
- package/reference/autogen/packages/auth-web.md +42 -22
- package/reference/autogen/packages/console-core.md +8 -25
- package/reference/autogen/packages/console-web.md +5 -5
- package/reference/autogen/packages/crud-core.md +61 -17
- package/reference/autogen/packages/database-runtime-mysql.md +12 -2
- package/reference/autogen/packages/database-runtime-postgres.md +12 -2
- package/reference/autogen/packages/database-runtime.md +26 -25
- package/reference/autogen/packages/google-rewarded-core.md +19 -104
- package/reference/autogen/packages/http-runtime.md +4 -8
- package/reference/autogen/packages/http-web.md +32 -0
- package/reference/autogen/packages/json-rest-api-core.md +4 -6
- package/reference/autogen/packages/kernel.md +109 -390
- package/reference/autogen/packages/mobile-capacitor.md +2 -13
- package/reference/autogen/packages/realtime.md +29 -26
- package/reference/autogen/packages/resource-crud-core.md +6 -0
- package/reference/autogen/packages/shell-web.md +69 -54
- package/reference/autogen/packages/storage-runtime.md +3 -3
- package/reference/autogen/packages/uploads-image-web.md +0 -1
- package/reference/autogen/packages/uploads-runtime.md +3 -3
- package/reference/autogen/packages/users-core.md +45 -90
- package/reference/autogen/packages/users-web.md +5 -7
- package/reference/autogen/packages/workspaces-core.md +53 -74
- package/reference/autogen/packages/workspaces-web.md +15 -16
- package/reference/autogen/tooling/jskit-catalog.md +34 -0
- package/reference/autogen/tooling/testUtils.md +4 -4
- package/skills/jskit/SKILL.md +38 -31
- package/skills/jskit/references/app-operations.md +68 -53
- package/skills/jskit/references/crud-operations.md +58 -106
- package/skills/jskit/references/material-3.md +1 -1
- package/skills/jskit/references/ui-operations.md +41 -44
- package/templates/app/AGENTS.md +7 -3
- package/guide/agent/app-setup/upgrade-beta-1-to-final.md +0 -252
- package/guide/agent/app-setup/working-with-the-jskit-cli.md +0 -325
- package/guide/agent/generators/advanced-cruds.md +0 -1935
- package/guide/agent/generators/crud-generators.md +0 -948
- package/guide/agent/generators/intro.md +0 -65
- package/guide/agent/generators/row-policies.md +0 -537
- package/guide/agent/generators/ui-generators.md +0 -690
- package/patterns/crud-scaffolding.md +0 -198
- package/patterns/generated-ui-contract-tracking.md +0 -66
- package/reference/autogen/packages/assistant.md +0 -68
- package/reference/autogen/packages/crud-server-generator.md +0 -215
- package/reference/autogen/packages/crud-ui-generator.md +0 -192
- package/reference/autogen/packages/feature-server-generator.md +0 -65
- package/reference/autogen/packages/ui-generator.md +0 -127
- package/reference/autogen/tooling/create-app.md +0 -317
- package/reference/autogen/tooling/jskit-cli.md +0 -933
- package/reference/autogen/tooling/test-support.md +0 -27
|
@@ -1,315 +1,43 @@
|
|
|
1
1
|
<!-- Generated by `npm run agent-docs:build` from `packages/agent-docs/site/guide/app-setup/console.md`. Do not edit manually. -->
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# Owner console
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
The important architectural change is simple:
|
|
8
|
-
|
|
9
|
-
- `users-web` owns account UI
|
|
10
|
-
- `console-web` owns console UI
|
|
11
|
-
- `console-core` owns the console schema, bootstrap flag, routes, and services behind it
|
|
12
|
-
|
|
13
|
-
## Installing `console-web`
|
|
14
|
-
|
|
15
|
-
From inside `exampleapp`, run:
|
|
5
|
+
Use a console when the product needs an owner-only or operator-only surface
|
|
6
|
+
separate from normal account and workspace administration.
|
|
16
7
|
|
|
17
8
|
```bash
|
|
18
|
-
|
|
9
|
+
npm install @jskit-ai/console-web
|
|
19
10
|
npm run db:migrate
|
|
20
11
|
```
|
|
21
12
|
|
|
22
|
-
`console-
|
|
23
|
-
|
|
24
|
-
- `console-core` owns the console schema, owner check, bootstrap flag, and API routes
|
|
25
|
-
- `console-web` owns the console surface scaffold, settings shell, and menu placement
|
|
26
|
-
|
|
27
|
-
The console is a real vertical slice. The users packages do not own it.
|
|
28
|
-
|
|
29
|
-
## What the console is for
|
|
30
|
-
|
|
31
|
-
The console is not a second home page, and it is not the same as account settings.
|
|
32
|
-
|
|
33
|
-
Its role is much lower-level than that.
|
|
34
|
-
|
|
35
|
-
- `account` is for the current user's own profile and settings
|
|
36
|
-
- `console` is for the people who run the app as a whole
|
|
37
|
-
|
|
38
|
-
So when you think about the console, think in terms of app runtime and operations, not personal preferences.
|
|
39
|
-
|
|
40
|
-
This is the surface where you would expect to put things like:
|
|
41
|
-
|
|
42
|
-
- site-wide bans or other cross-user moderation controls
|
|
43
|
-
- server error logging and inspection
|
|
44
|
-
- operational diagnostics
|
|
45
|
-
- maintenance or repair scripts
|
|
46
|
-
- global feature switches
|
|
47
|
-
- whole-app settings that affect every user, not just the current one
|
|
48
|
-
|
|
49
|
-
In other words, the console is the place for configuring and inspecting the runtime of the application as a whole.
|
|
50
|
-
|
|
51
|
-
That is why the starter console page describes itself as:
|
|
52
|
-
|
|
53
|
-
- operator tools
|
|
54
|
-
- scripts
|
|
55
|
-
- diagnostics
|
|
56
|
-
|
|
57
|
-
It is also why the console surface has stricter access rules than `/account`. `/account` is for any signed-in user. `console` is for trusted operators with low-level control over the running app.
|
|
58
|
-
|
|
59
|
-
## Running it
|
|
60
|
-
|
|
61
|
-
Start both processes:
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
npm run dev
|
|
65
|
-
npm run server
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Then sign in.
|
|
69
|
-
|
|
70
|
-
Once you are authenticated, two things matter:
|
|
71
|
-
|
|
72
|
-
- the app knows who you are as a persistent JSKIT user
|
|
73
|
-
- the console bootstrap logic can determine whether you are the console owner
|
|
74
|
-
|
|
75
|
-
Open:
|
|
76
|
-
|
|
77
|
-
```text
|
|
78
|
-
http://localhost:5173/console
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
In a fresh app, the console is intentionally simple.
|
|
82
|
-
|
|
83
|
-
- `/console` is the surface landing page
|
|
84
|
-
- `/console/settings` is the first nested shell route under it
|
|
85
|
-
|
|
86
|
-
That simplicity is useful. It shows the surface boundary clearly before later modules add real console tools.
|
|
87
|
-
|
|
88
|
-
## Why console access is stricter than account access
|
|
89
|
-
|
|
90
|
-
This is the most important idea in the chapter.
|
|
91
|
-
|
|
92
|
-
The account surface only requires authentication. The console surface requires a specific access flag: `console_owner`.
|
|
93
|
-
|
|
94
|
-
That means the guide has two different kinds of authenticated routes:
|
|
95
|
-
|
|
96
|
-
- normal authenticated routes such as `/account`
|
|
97
|
-
- privileged authenticated routes such as `/console`
|
|
98
|
-
|
|
99
|
-
This is a very useful distinction for junior developers to see early, because many real apps need both:
|
|
100
|
-
|
|
101
|
-
- somewhere for every signed-in user
|
|
102
|
-
- somewhere only for the app owner or operators
|
|
103
|
-
|
|
104
|
-
## The first console owner
|
|
105
|
-
|
|
106
|
-
In a fresh app, the console owner is not configured by hand in a seed file. Instead, JSKIT assigns the first console owner lazily during authenticated bootstrap.
|
|
107
|
-
|
|
108
|
-
The rule is simple:
|
|
109
|
-
|
|
110
|
-
- when the users bootstrap contributor has already identified a signed-in user
|
|
111
|
-
- and the later console bootstrap contributor runs for that same request
|
|
112
|
-
- and the singleton console settings record has no owner yet
|
|
113
|
-
- **that user becomes the initial console owner**
|
|
114
|
-
|
|
115
|
-
So the first real authenticated user to pass through that path claims the console. After that, the console owner check becomes strict.
|
|
116
|
-
|
|
117
|
-
This is why the console chapter belongs after the users chapter:
|
|
118
|
-
|
|
119
|
-
- before persistent users exist, there is nobody to own the console
|
|
120
|
-
- once persistent users exist, JSKIT can finally attach console ownership to a real user id
|
|
121
|
-
|
|
122
|
-
## What `console-web` adds to the app
|
|
123
|
-
|
|
124
|
-
The console surface is spread across surface config, access policy config, the placement registry, and the persistent `console_settings` table.
|
|
125
|
-
|
|
126
|
-
### `config/public.js` defines the surface
|
|
127
|
-
|
|
128
|
-
The console surface definition is small, but very important:
|
|
129
|
-
|
|
130
|
-
```js
|
|
131
|
-
config.surfaceDefinitions.console = {
|
|
132
|
-
id: "console",
|
|
133
|
-
label: "Console",
|
|
134
|
-
pagesRoot: "console",
|
|
135
|
-
enabled: true,
|
|
136
|
-
requiresAuth: true,
|
|
137
|
-
requiresWorkspace: false,
|
|
138
|
-
accessPolicyId: "console_owner",
|
|
139
|
-
origin: ""
|
|
140
|
-
};
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Two details matter most:
|
|
144
|
-
|
|
145
|
-
- `requiresAuth: true`
|
|
146
|
-
- `accessPolicyId: "console_owner"`
|
|
147
|
-
|
|
148
|
-
So this is not just a named route tree. It is a surface with its own access contract.
|
|
149
|
-
|
|
150
|
-
### `config/surfaceAccessPolicies.js` defines the rule
|
|
151
|
-
|
|
152
|
-
The matching access policy is:
|
|
153
|
-
|
|
154
|
-
```js
|
|
155
|
-
surfaceAccessPolicies.console_owner = {
|
|
156
|
-
requireAuth: true,
|
|
157
|
-
requireFlagsAll: ["console_owner"]
|
|
158
|
-
};
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
This is the first clear example in the guide of a surface guarded by a named flag rather than only by authentication.
|
|
162
|
-
|
|
163
|
-
### The starter console routes are app-owned
|
|
164
|
-
|
|
165
|
-
After the previous chapter, the app has:
|
|
166
|
-
|
|
167
|
-
```text
|
|
168
|
-
src/pages/console.vue
|
|
169
|
-
src/pages/console/index.vue
|
|
170
|
-
src/pages/console/settings.vue
|
|
171
|
-
src/pages/console/settings/index.vue
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
This follows the same route-owner pattern the guide has already shown on `home` and `settings`.
|
|
175
|
-
|
|
176
|
-
- `src/pages/console.vue` is the console surface wrapper
|
|
177
|
-
- `src/pages/console/index.vue` is the console landing page
|
|
178
|
-
- `src/pages/console/settings.vue` is the nested settings shell
|
|
179
|
-
- `src/pages/console/settings/index.vue` is the initial developer-owned stub
|
|
180
|
-
|
|
181
|
-
That last file is intentionally empty, because later modules are expected to add real console settings sections through `page.section-nav` with owner `console-settings`.
|
|
182
|
-
|
|
183
|
-
### `src/placement.js` wires the first console menu entry
|
|
184
|
-
|
|
185
|
-
The starter placement block is:
|
|
186
|
-
|
|
187
|
-
```js
|
|
188
|
-
addPlacement({
|
|
189
|
-
id: "console.web.menu.settings",
|
|
190
|
-
target: "shell.primary-nav",
|
|
191
|
-
kind: "link",
|
|
192
|
-
surfaces: ["console"],
|
|
193
|
-
order: 100,
|
|
194
|
-
props: {
|
|
195
|
-
label: "Settings",
|
|
196
|
-
to: "/console/settings",
|
|
197
|
-
icon: "mdi-cog-outline"
|
|
198
|
-
},
|
|
199
|
-
when: ({ auth }) => Boolean(auth?.authenticated)
|
|
200
|
-
});
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
This is why the console drawer immediately has a `Settings` entry.
|
|
204
|
-
|
|
205
|
-
The important design point is the same as in earlier chapters:
|
|
206
|
-
|
|
207
|
-
- the shell layout stays generic
|
|
208
|
-
- the placement registry decides what appears in that surface
|
|
209
|
-
|
|
210
|
-
## Under the hood
|
|
211
|
-
|
|
212
|
-
### `console-core` installs the `console_settings` schema
|
|
213
|
-
|
|
214
|
-
The console migration creates a singleton console settings table:
|
|
215
|
-
|
|
216
|
-
```js
|
|
217
|
-
await knex.schema.createTable("console_settings", (table) => {
|
|
218
|
-
table.bigInteger("id").primary();
|
|
219
|
-
table.bigInteger("owner_user_id").unsigned().nullable().references("id").inTable("users").onDelete("SET NULL");
|
|
220
|
-
table.timestamp("created_at", { useTz: false }).notNullable().defaultTo(knex.fn.now());
|
|
221
|
-
table.timestamp("updated_at", { useTz: false }).notNullable().defaultTo(knex.fn.now());
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
await knex("console_settings").insert({
|
|
225
|
-
id: 1,
|
|
226
|
-
created_at: knex.fn.now(),
|
|
227
|
-
updated_at: knex.fn.now()
|
|
228
|
-
});
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
That table is the anchor for console ownership.
|
|
232
|
-
|
|
233
|
-
There is only one console settings record, and it can point at exactly one `owner_user_id`.
|
|
234
|
-
|
|
235
|
-
### The console service claims the first owner lazily
|
|
236
|
-
|
|
237
|
-
The core console service is small enough to read in one glance:
|
|
238
|
-
|
|
239
|
-
```js
|
|
240
|
-
async function ensureInitialConsoleMember(userId, options = {}) {
|
|
241
|
-
const normalizedUserId = normalizeRecordId(userId, { fallback: null });
|
|
242
|
-
if (!normalizedUserId) {
|
|
243
|
-
throw new AppError(400, "Invalid console user.");
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return consoleSettingsRepository.ensureOwnerUserId(normalizedUserId, options);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
async function requireConsoleOwner(context = {}, options = {}) {
|
|
250
|
-
const actorUserId = normalizeRecordId(context?.actor?.id, { fallback: null });
|
|
251
|
-
if (!actorUserId) {
|
|
252
|
-
throw new AppError(401, "Authentication required.");
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
const ownerUserId = await ensureInitialConsoleMember(actorUserId, options);
|
|
256
|
-
if (actorUserId !== ownerUserId) {
|
|
257
|
-
throw new AppError(403, "Forbidden.");
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
That explains the whole startup story.
|
|
263
|
-
|
|
264
|
-
- if no console owner exists yet, the first authenticated user can become it
|
|
265
|
-
- once an owner exists, everyone else fails the ownership check
|
|
266
|
-
|
|
267
|
-
So the console is seeded lazily, not through a hard-coded seed user.
|
|
268
|
-
|
|
269
|
-
### `console-core` adds the console access flag to the bootstrap payload
|
|
270
|
-
|
|
271
|
-
After the users bootstrap contributor has already built the authenticated session payload, the later `console-core` bootstrap contributor extends it with the console flag:
|
|
272
|
-
|
|
273
|
-
```js
|
|
274
|
-
surfaceAccess: {
|
|
275
|
-
...surfaceAccess,
|
|
276
|
-
consoleowner: consoleOwner
|
|
277
|
-
}
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
This detail is easy to miss, but it matters:
|
|
281
|
-
|
|
282
|
-
- `users-core` identifies the authenticated user and writes `session.userId`
|
|
283
|
-
- `console-core` reads that authenticated user id
|
|
284
|
-
- `console-core` seeds or checks the singleton console owner record
|
|
285
|
-
- then `console-core` writes `surfaceAccess.consoleowner` into the bootstrap payload
|
|
286
|
-
|
|
287
|
-
That is how JSKIT can reason about console access at surface level without making the users packages know anything about the console.
|
|
288
|
-
|
|
289
|
-
So the console chapter is really about a three-part contract:
|
|
290
|
-
|
|
291
|
-
- a surface definition in public config
|
|
292
|
-
- an ownership check on the server
|
|
293
|
-
- a persistent owner slot in the database
|
|
13
|
+
The installed graph supplies `console-core`. Its migration and feature runtime
|
|
14
|
+
are discovered normally; no console generator is involved.
|
|
294
15
|
|
|
295
|
-
|
|
16
|
+
Use the `console/console-surface` pattern for the route tree, surface policy,
|
|
17
|
+
settings navigation, profile switch, and responsive shell placements.
|
|
296
18
|
|
|
297
|
-
##
|
|
19
|
+
## Product decisions
|
|
298
20
|
|
|
299
|
-
|
|
21
|
+
Choose who can enter the console, its route and label, which operations and
|
|
22
|
+
settings it owns, and how authorized people switch back to the normal product.
|
|
23
|
+
Do not create a console merely to host one ordinary settings page.
|
|
300
24
|
|
|
301
|
-
|
|
302
|
-
- `console-core` added the console schema, services, bootstrap contributor, and ownership rules
|
|
303
|
-
- the app gained a new surface that is stricter than `/account`
|
|
25
|
+
## Invariants
|
|
304
26
|
|
|
305
|
-
|
|
27
|
+
- Server policy authorizes console actions before product logic runs.
|
|
28
|
+
- The surface definition and route pages use the same stable surface id.
|
|
29
|
+
- The console switch appears only for authorized authenticated users.
|
|
30
|
+
- Settings navigation uses semantic placements and topology.
|
|
31
|
+
- Loading uses skeletons and preserves shell geometry.
|
|
306
32
|
|
|
307
|
-
-
|
|
308
|
-
|
|
33
|
+
The first-owner policy, if the product selects it, is a runtime product rule;
|
|
34
|
+
it is not a hard-coded seed account.
|
|
309
35
|
|
|
310
|
-
|
|
36
|
+
## Verification
|
|
311
37
|
|
|
312
|
-
|
|
313
|
-
|
|
38
|
+
Test authorized and forbidden direct entry, first-owner behavior, switching,
|
|
39
|
+
refresh, console settings, compact navigation, and the production build.
|
|
314
40
|
|
|
315
|
-
|
|
41
|
+
Do not treat hidden navigation as authorization, reuse normal-user pages by
|
|
42
|
+
changing only their prefix, or introduce generator ownership and appended
|
|
43
|
+
source fragments.
|