@jskit-ai/agent-docs 0.1.205 → 0.1.207
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-conversation.md +51 -2
- package/guide/agent/app-setup/multi-homing.md +29 -0
- package/guide/agent/framework/crud-operations.md +162 -0
- package/package.json +1 -1
- package/patterns/feature-package/example/booking-engine/package.json +1 -1
- package/patterns/minimal-foundation/example/package.json +4 -4
- package/patterns/shell-foundation/example/package.json +5 -5
- package/patterns/shell-foundation/example/packages/main/package.json +1 -1
- package/patterns/ui-testing.md +7 -0
- package/reference/autogen/PATTERN_INDEX.md +35 -35
- package/reference/autogen/packages/assistant-core.md +1 -1
- package/reference/autogen/packages/assistant-voice-sherpa.md +1 -1
- package/reference/autogen/packages/workspaces-core.md +3 -3
- package/reference/autogen/packages/workspaces-web.md +11 -0
- package/skills/jskit/SKILL.md +9 -0
- package/skills/jskit/references/crud-operations.md +162 -0
- package/skills/jskit/references/multi-homing.md +29 -0
- package/skills/jskit/references/pattern-index.md +35 -35
- package/skills/jskit/references/patterns/app/minimal-foundation/example/package.json +4 -4
- package/skills/jskit/references/patterns/app/shell-foundation/example/package.json +5 -5
- package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/package.json +1 -1
- package/skills/jskit/references/patterns/auth/supabase-auth/example/package.json +1 -1
- package/skills/jskit/references/patterns/connectors/calendar-cli/example/package.json +4 -4
- package/skills/jskit/references/patterns/crud/crud-screen-set/PATTERN.md +30 -0
- package/skills/jskit/references/patterns/crud/crud-screen-set/example/books/BookEditPage.vue +1 -0
- package/skills/jskit/references/patterns/crud/crud-screen-set/example/books/BookNewPage.vue +1 -0
- package/skills/jskit/references/patterns/crud/json-api-resource-package/PATTERN.md +5 -0
- package/skills/jskit/references/patterns/crud/json-api-resource-package/example/packages/books/package.json +2 -2
- package/skills/jskit/references/patterns/database/mysql-application/example/package.json +1 -1
- package/skills/jskit/references/patterns/database/postgres-application/example/package.json +1 -1
- package/skills/jskit/references/patterns/realtime/realtime-application/example/package.json +2 -2
- package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/package.json +1 -1
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/package.json +2 -2
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/package.json +3 -3
- package/skills/jskit/references/patterns/workspaces/workspace-server/PATTERN.md +20 -0
- package/skills/jskit/references/patterns/workspaces/workspace-server/example/config/roles.js +2 -0
|
@@ -15,7 +15,7 @@ A concrete Fastify, Vue, and JSKIT application foundation for products that do n
|
|
|
15
15
|
|
|
16
16
|
- Id: `app/minimal-foundation`
|
|
17
17
|
- Keywords: `app`, `fastify`, `foundation`, `minimal`, `server`, `vite`, `vue`
|
|
18
|
-
- Owner: `@jskit-ai/agent-docs@0.1.
|
|
18
|
+
- Owner: `@jskit-ai/agent-docs@0.1.207`
|
|
19
19
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/app/minimal-foundation/PATTERN.md)
|
|
20
20
|
- Examples: [example/](../../skills/jskit/references/patterns/app/minimal-foundation/example/)
|
|
21
21
|
- Requires: `@jskit-ai/http-runtime`, `@jskit-ai/kernel`
|
|
@@ -26,7 +26,7 @@ A concrete JSKIT web application foundation with responsive shell navigation, se
|
|
|
26
26
|
|
|
27
27
|
- Id: `app/shell-foundation`
|
|
28
28
|
- Keywords: `app`, `foundation`, `material`, `navigation`, `placements`, `shell`, `vite`, `vue`
|
|
29
|
-
- Owner: `@jskit-ai/agent-docs@0.1.
|
|
29
|
+
- Owner: `@jskit-ai/agent-docs@0.1.207`
|
|
30
30
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/app/shell-foundation/PATTERN.md)
|
|
31
31
|
- Examples: [example/](../../skills/jskit/references/patterns/app/shell-foundation/example/)
|
|
32
32
|
- Requires: `@jskit-ai/http-runtime`, `@jskit-ai/kernel`, `@jskit-ai/shell-web`
|
|
@@ -37,7 +37,7 @@ Configure an assistant runtime for one application surface and expose its chat a
|
|
|
37
37
|
|
|
38
38
|
- Id: `assistant/assistant-surface`
|
|
39
39
|
- Keywords: `ai`, `assistant`, `chat`, `config`, `environment`, `page`, `placement`, `settings`, `surface`
|
|
40
|
-
- Owner: `@jskit-ai/assistant-runtime@0.1.
|
|
40
|
+
- Owner: `@jskit-ai/assistant-runtime@0.1.206`
|
|
41
41
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/assistant/assistant-surface/PATTERN.md)
|
|
42
42
|
- Examples: [example/](../../skills/jskit/references/patterns/assistant/assistant-surface/example/)
|
|
43
43
|
- Requires: `@jskit-ai/assistant-runtime`, `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`, `@jskit-ai/shell-web`
|
|
@@ -48,7 +48,7 @@ Compose JSKIT authentication routes, views, profile controls, and public surface
|
|
|
48
48
|
|
|
49
49
|
- Id: `auth/auth-surface`
|
|
50
50
|
- Keywords: `account`, `auth`, `login`, `logout`, `password`, `placement`, `profile`, `reset`, `surface`
|
|
51
|
-
- Owner: `@jskit-ai/auth-web@0.1.
|
|
51
|
+
- Owner: `@jskit-ai/auth-web@0.1.235`
|
|
52
52
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/auth/auth-surface/PATTERN.md)
|
|
53
53
|
- Examples: [example/](../../skills/jskit/references/patterns/auth/auth-surface/example/)
|
|
54
54
|
- Requires: `@jskit-ai/auth-core`, `@jskit-ai/auth-web`, `@jskit-ai/shell-web`
|
|
@@ -59,7 +59,7 @@ Add Supabase authentication through normal npm composition, explicit environment
|
|
|
59
59
|
|
|
60
60
|
- Id: `auth/supabase-auth`
|
|
61
61
|
- Keywords: `auth`, `authentication`, `oauth`, `sessions`, `supabase`
|
|
62
|
-
- Owner: `@jskit-ai/auth-provider-supabase-core@0.1.
|
|
62
|
+
- Owner: `@jskit-ai/auth-provider-supabase-core@0.1.232`
|
|
63
63
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/auth/supabase-auth/PATTERN.md)
|
|
64
64
|
- Examples: [example/](../../skills/jskit/references/patterns/auth/supabase-auth/example/)
|
|
65
65
|
- Requires: `@jskit-ai/auth-provider-supabase-core`
|
|
@@ -70,7 +70,7 @@ Resolve an administrator environment key or an individual user's grant, then use
|
|
|
70
70
|
|
|
71
71
|
- Id: `connectors/ai-connections`
|
|
72
72
|
- Keywords: `ai`, `api-key`, `big-pickle`, `cli`, `environment`, `free`, `models`, `ownership`, `zai`, `zen`
|
|
73
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
73
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
74
74
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/ai-connections/PATTERN.md)
|
|
75
75
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/ai-connections/example/)
|
|
76
76
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -81,7 +81,7 @@ Compose provider operations, authorization and encrypted file storage from a CLI
|
|
|
81
81
|
|
|
82
82
|
- Id: `connectors/api-key-connection`
|
|
83
83
|
- Keywords: `api-key`, `clay`, `cli`, `clickhouse`, `connectors`, `dbt`, `files`, `firecrawl`, `granola`, `integrations`, `metrics`, `prestashop`, `resend`, `semantic-layer`, `semrush`, `x-twitter`
|
|
84
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
84
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
85
85
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/api-key-connection/PATTERN.md)
|
|
86
86
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/api-key-connection/example/)
|
|
87
87
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -92,7 +92,7 @@ Compose token-based MCP discovery and explicitly authorized tool calls using the
|
|
|
92
92
|
|
|
93
93
|
- Id: `connectors/assistant-mcp`
|
|
94
94
|
- Keywords: `assistant`, `cli`, `connectors`, `files`, `integrations`, `mcp`, `n8n`, `sanity`
|
|
95
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
95
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
96
96
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/assistant-mcp/PATTERN.md)
|
|
97
97
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/assistant-mcp/example/)
|
|
98
98
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -103,7 +103,7 @@ Configure assistant OAuth clients, then compose existing state, encrypted file g
|
|
|
103
103
|
|
|
104
104
|
- Id: `connectors/assistant-mcp-oauth`
|
|
105
105
|
- Keywords: `amplitude`, `assistant`, `atlassian`, `canva`, `cli`, `client metadata`, `confidence`, `connectors`, `figma`, `files`, `granola`, `hex`, `mcp`, `miro`, `oauth`
|
|
106
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
106
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
107
107
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/assistant-mcp-oauth/PATTERN.md)
|
|
108
108
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/assistant-mcp-oauth/example/)
|
|
109
109
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -114,7 +114,7 @@ Compose signed AWS operations, file configuration and application authorization
|
|
|
114
114
|
|
|
115
115
|
- Id: `connectors/aws-storage-queries`
|
|
116
116
|
- Keywords: `athena`, `aws`, `cli`, `connectors`, `files`, `iam`, `queries`, `s3`, `storage`, `sts`
|
|
117
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
117
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
118
118
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/aws-storage-queries/PATTERN.md)
|
|
119
119
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/aws-storage-queries/example/)
|
|
120
120
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -125,7 +125,7 @@ Compose reusable connection libraries with portable configuration, application o
|
|
|
125
125
|
|
|
126
126
|
- Id: `connectors/calendar-cli`
|
|
127
127
|
- Keywords: `calendar`, `cli`, `connectors`, `google`, `integrations`, `oauth`, `permissions`
|
|
128
|
-
- Owner: `@jskit-ai/connector-google-calendar@0.1.
|
|
128
|
+
- Owner: `@jskit-ai/connector-google-calendar@0.1.52`
|
|
129
129
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/calendar-cli/PATTERN.md)
|
|
130
130
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/calendar-cli/example/)
|
|
131
131
|
- Requires: `@jskit-ai/connector-google-calendar`, `@jskit-ai/connectors-core`, `@jskit-ai/database-runtime-mysql`
|
|
@@ -136,7 +136,7 @@ Compose the shared connector runtime for event delivery while leaving workflow c
|
|
|
136
136
|
|
|
137
137
|
- Id: `connectors/event-delivery`
|
|
138
138
|
- Keywords: `cli`, `connectors`, `events`, `files`, `inngest`, `integrations`, `workflows`
|
|
139
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
139
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
140
140
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/event-delivery/PATTERN.md)
|
|
141
141
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/event-delivery/example/)
|
|
142
142
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -147,7 +147,7 @@ Wire service-account grants, file storage, explicit message actions and public b
|
|
|
147
147
|
|
|
148
148
|
- Id: `connectors/firebase-messaging`
|
|
149
149
|
- Keywords: `cli`, `connectors`, `fcm`, `files`, `firebase`, `integrations`, `jwt`, `notifications`, `push`, `service-account`, `vapid`
|
|
150
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
150
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
151
151
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/firebase-messaging/PATTERN.md)
|
|
152
152
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/firebase-messaging/example/)
|
|
153
153
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -158,7 +158,7 @@ Compose reviewed Search campaigns with project-owned Google OAuth and portable s
|
|
|
158
158
|
|
|
159
159
|
- Id: `connectors/google-ads-search`
|
|
160
160
|
- Keywords: `ads`, `campaigns`, `cli`, `connectors`, `conversion`, `google`, `search`
|
|
161
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
161
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
162
162
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/google-ads-search/PATTERN.md)
|
|
163
163
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/google-ads-search/example/)
|
|
164
164
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -169,7 +169,7 @@ Compose provider consent, verification and encrypted file persistence from an ap
|
|
|
169
169
|
|
|
170
170
|
- Id: `connectors/oauth-connection`
|
|
171
171
|
- Keywords: `accounting`, `assistant permissions`, `books`, `cli`, `client credentials`, `connectors`, `consent`, `crm`, `databricks`, `developer token`, `fabric`, `files`, `gaql`, `google ads`, `graphql`, `integrations`, `linkedin`, `microsoft`, `oauth`, `powerpoint`, `salesforce`, `service principal`, `shopify`, `soql`, `staffing`, `tiktok`, `twitch`, `wave`, `word`, `wordpress`, `workday`, `xero`, `zoho`
|
|
172
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
172
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
173
173
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/oauth-connection/PATTERN.md)
|
|
174
174
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/oauth-connection/example/)
|
|
175
175
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -180,7 +180,7 @@ Compose a sequential catalogue batch and preserve partial success for applicatio
|
|
|
180
180
|
|
|
181
181
|
- Id: `connectors/paddle-catalogue`
|
|
182
182
|
- Keywords: `batch`, `paddle`, `payments`, `prices`, `products`
|
|
183
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
183
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
184
184
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/paddle-catalogue/PATTERN.md)
|
|
185
185
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/paddle-catalogue/example/)
|
|
186
186
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -191,7 +191,7 @@ Resolve a publishable image key deliberately and use the shared URL library in a
|
|
|
191
191
|
|
|
192
192
|
- Id: `connectors/public-image`
|
|
193
193
|
- Keywords: `cli`, `connectors`, `files`, `images`, `integrations`, `logo-dev`, `public-key`
|
|
194
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
194
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
195
195
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/public-image/PATTERN.md)
|
|
196
196
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/public-image/example/)
|
|
197
197
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -202,7 +202,7 @@ Compose file configuration, Redshift Data API operations and application query o
|
|
|
202
202
|
|
|
203
203
|
- Id: `connectors/redshift-queries`
|
|
204
204
|
- Keywords: `aws`, `cli`, `connectors`, `files`, `iam`, `provisioned`, `redshift`, `serverless`, `sql`, `warehouse`
|
|
205
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
205
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
206
206
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/redshift-queries/PATTERN.md)
|
|
207
207
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/redshift-queries/example/)
|
|
208
208
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -213,7 +213,7 @@ Use the shared scanner runtime from a CLI or a host worker with portable configu
|
|
|
213
213
|
|
|
214
214
|
- Id: `connectors/source-scanning`
|
|
215
215
|
- Keywords: `cancellation`, `cli`, `connectors`, `integrations`, `scanning`, `security`, `source`, `wiz`, `worker`
|
|
216
|
-
- Owner: `@jskit-ai/connectors-catalog@0.1.
|
|
216
|
+
- Owner: `@jskit-ai/connectors-catalog@0.1.52`
|
|
217
217
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/source-scanning/PATTERN.md)
|
|
218
218
|
- Examples: [example/](../../skills/jskit/references/patterns/connectors/source-scanning/example/)
|
|
219
219
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -224,7 +224,7 @@ Add a protected administration surface, settings shell, and semantic navigation
|
|
|
224
224
|
|
|
225
225
|
- Id: `console/console-surface`
|
|
226
226
|
- Keywords: `admin`, `console`, `navigation`, `owner`, `placement`, `settings`, `surface`
|
|
227
|
-
- Owner: `@jskit-ai/console-web@0.1.
|
|
227
|
+
- Owner: `@jskit-ai/console-web@0.1.203`
|
|
228
228
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/console/console-surface/PATTERN.md)
|
|
229
229
|
- Examples: [example/](../../skills/jskit/references/patterns/console/console-surface/example/)
|
|
230
230
|
- Requires: `@jskit-ai/console-core`, `@jskit-ai/console-web`, `@jskit-ai/shell-web`
|
|
@@ -235,7 +235,7 @@ Build a routed CRUD user interface as thin application pages over JSKIT's shared
|
|
|
235
235
|
|
|
236
236
|
- Id: `crud/crud-screen-set`
|
|
237
237
|
- Keywords: `actions`, `add`, `crud`, `delete`, `edit`, `filters`, `list`, `material`, `routes`, `view`, `vue`
|
|
238
|
-
- Owner: `@jskit-ai/http-web@0.1.
|
|
238
|
+
- Owner: `@jskit-ai/http-web@0.1.80`
|
|
239
239
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/crud/crud-screen-set/PATTERN.md)
|
|
240
240
|
- Examples: [example/](../../skills/jskit/references/patterns/crud/crud-screen-set/example/)
|
|
241
241
|
- Requires: `@jskit-ai/http-web`, `@jskit-ai/resource-crud-core`
|
|
@@ -246,7 +246,7 @@ Build a complete application-owned CRUD server package from a migration, resourc
|
|
|
246
246
|
|
|
247
247
|
- Id: `crud/json-api-resource-package`
|
|
248
248
|
- Keywords: `actions`, `crud`, `database`, `json-api`, `migration`, `permissions`, `provider`, `repository`, `routes`, `service`
|
|
249
|
-
- Owner: `@jskit-ai/crud-core@0.1.
|
|
249
|
+
- Owner: `@jskit-ai/crud-core@0.1.246`
|
|
250
250
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/crud/json-api-resource-package/PATTERN.md)
|
|
251
251
|
- Examples: [example/](../../skills/jskit/references/patterns/crud/json-api-resource-package/example/)
|
|
252
252
|
- Requires: `@jskit-ai/crud-core`, `@jskit-ai/resource-crud-core`
|
|
@@ -257,7 +257,7 @@ Define an authenticated application resource whose records belong to the current
|
|
|
257
257
|
|
|
258
258
|
- Id: `crud/resource-contract`
|
|
259
259
|
- Keywords: `authenticated`, `crud`, `database`, `owner-scoped`, `resource`, `user`
|
|
260
|
-
- Owner: `@jskit-ai/resource-crud-core@0.1.
|
|
260
|
+
- Owner: `@jskit-ai/resource-crud-core@0.1.177`
|
|
261
261
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/crud/resource-contract/PATTERN.md)
|
|
262
262
|
- Examples: [example/](../../skills/jskit/references/patterns/crud/resource-contract/example/)
|
|
263
263
|
- Requires: `@jskit-ai/resource-crud-core`
|
|
@@ -268,7 +268,7 @@ Configure a JSKIT application for MySQL with a fixed driver, ordinary environmen
|
|
|
268
268
|
|
|
269
269
|
- Id: `database/mysql-application`
|
|
270
270
|
- Keywords: `database`, `knex`, `mariadb`, `migrations`, `mysql`, `mysql2`
|
|
271
|
-
- Owner: `@jskit-ai/database-runtime-mysql@0.1.
|
|
271
|
+
- Owner: `@jskit-ai/database-runtime-mysql@0.1.233`
|
|
272
272
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/database/mysql-application/PATTERN.md)
|
|
273
273
|
- Examples: [example/](../../skills/jskit/references/patterns/database/mysql-application/example/)
|
|
274
274
|
- Requires: `@jskit-ai/database-runtime-mysql`
|
|
@@ -279,7 +279,7 @@ Configure a JSKIT application for PostgreSQL with a fixed driver, ordinary envir
|
|
|
279
279
|
|
|
280
280
|
- Id: `database/postgres-application`
|
|
281
281
|
- Keywords: `database`, `knex`, `migrations`, `pg`, `postgres`, `postgresql`
|
|
282
|
-
- Owner: `@jskit-ai/database-runtime-postgres@0.1.
|
|
282
|
+
- Owner: `@jskit-ai/database-runtime-postgres@0.1.232`
|
|
283
283
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/database/postgres-application/PATTERN.md)
|
|
284
284
|
- Examples: [example/](../../skills/jskit/references/patterns/database/postgres-application/example/)
|
|
285
285
|
- Requires: `@jskit-ai/database-runtime-postgres`
|
|
@@ -290,7 +290,7 @@ Wrap a JSKIT web application in a Capacitor Android shell using native Capacitor
|
|
|
290
290
|
|
|
291
291
|
- Id: `mobile/android-application`
|
|
292
292
|
- Keywords: `android`, `capacitor`, `device`, `mobile`, `native`, `shell`, `webview`
|
|
293
|
-
- Owner: `@jskit-ai/mobile-capacitor@0.1.
|
|
293
|
+
- Owner: `@jskit-ai/mobile-capacitor@0.1.170`
|
|
294
294
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/mobile/android-application/PATTERN.md)
|
|
295
295
|
- Examples: [example/](../../skills/jskit/references/patterns/mobile/android-application/example/)
|
|
296
296
|
- Requires: `@capacitor/android`, `@capacitor/app`, `@capacitor/cli`, `@jskit-ai/mobile-capacitor`
|
|
@@ -301,7 +301,7 @@ Add JSKIT realtime events with an optional Redis backplane and an explicit shell
|
|
|
301
301
|
|
|
302
302
|
- Id: `realtime/realtime-application`
|
|
303
303
|
- Keywords: `realtime`, `redis`, `socket.io`, `sockets`, `status`, `websocket`
|
|
304
|
-
- Owner: `@jskit-ai/realtime@0.1.
|
|
304
|
+
- Owner: `@jskit-ai/realtime@0.1.232`
|
|
305
305
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/realtime/realtime-application/PATTERN.md)
|
|
306
306
|
- Examples: [example/](../../skills/jskit/references/patterns/realtime/realtime-application/example/)
|
|
307
307
|
- Requires: `@jskit-ai/realtime`, `@jskit-ai/shell-web`
|
|
@@ -312,7 +312,7 @@ Compose application-owned Google Publisher Tag delivery with the generic rewarde
|
|
|
312
312
|
|
|
313
313
|
- Id: `rewards/google-rewarded`
|
|
314
314
|
- Keywords: `ads`, `google`, `publisher tag`, `rewarded`, `unlock`
|
|
315
|
-
- Owner: `@jskit-ai/rewarded-web@0.1.
|
|
315
|
+
- Owner: `@jskit-ai/rewarded-web@0.1.171`
|
|
316
316
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/rewards/google-rewarded/PATTERN.md)
|
|
317
317
|
- Examples: [example/](../../skills/jskit/references/patterns/rewards/google-rewarded/example/)
|
|
318
318
|
- Requires: `@jskit-ai/rewarded-web`
|
|
@@ -323,7 +323,7 @@ Define a server feature through explicit capabilities and first-class actions, a
|
|
|
323
323
|
|
|
324
324
|
- Id: `server/feature-package`
|
|
325
325
|
- Keywords: `actions`, `feature`, `json-rest`, `knex`, `orchestration`, `package`, `provider`, `repository`, `routes`, `server`
|
|
326
|
-
- Owner: `@jskit-ai/agent-docs@0.1.
|
|
326
|
+
- Owner: `@jskit-ai/agent-docs@0.1.207`
|
|
327
327
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/server/feature-package/PATTERN.md)
|
|
328
328
|
- Examples: [example/](../../skills/jskit/references/patterns/server/feature-package/example/)
|
|
329
329
|
- Requires: `@jskit-ai/kernel`
|
|
@@ -334,7 +334,7 @@ Compose the JSKIT responsive shell, semantic placements, settings navigation, an
|
|
|
334
334
|
|
|
335
335
|
- Id: `shell/application-shell`
|
|
336
336
|
- Keywords: `adaptive`, `app`, `layout`, `navigation`, `placement`, `responsive`, `settings`, `shell`
|
|
337
|
-
- Owner: `@jskit-ai/shell-web@0.1.
|
|
337
|
+
- Owner: `@jskit-ai/shell-web@0.1.239`
|
|
338
338
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/shell/application-shell/PATTERN.md)
|
|
339
339
|
- Examples: [example/](../../skills/jskit/references/patterns/shell/application-shell/example/)
|
|
340
340
|
- Requires: `@jskit-ai/kernel`, `@jskit-ai/shell-web`
|
|
@@ -345,7 +345,7 @@ Add product routes and shell extensions through file routing, semantic placement
|
|
|
345
345
|
|
|
346
346
|
- Id: `ui/page-and-placement`
|
|
347
347
|
- Keywords: `component`, `navigation`, `outlet`, `page`, `placement`, `routes`, `section`, `shell`, `subpages`, `vue`
|
|
348
|
-
- Owner: `@jskit-ai/shell-web@0.1.
|
|
348
|
+
- Owner: `@jskit-ai/shell-web@0.1.239`
|
|
349
349
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/ui/page-and-placement/PATTERN.md)
|
|
350
350
|
- Examples: [example/](../../skills/jskit/references/patterns/ui/page-and-placement/example/)
|
|
351
351
|
- Requires: `@jskit-ai/kernel`, `@jskit-ai/shell-web`
|
|
@@ -356,7 +356,7 @@ Compose an account settings route and profile, preference, and notification sect
|
|
|
356
356
|
|
|
357
357
|
- Id: `users/account-settings`
|
|
358
358
|
- Keywords: `account`, `notifications`, `preferences`, `profile`, `settings`, `user`, `vue`
|
|
359
|
-
- Owner: `@jskit-ai/users-web@0.1.
|
|
359
|
+
- Owner: `@jskit-ai/users-web@0.1.253`
|
|
360
360
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/users/account-settings/PATTERN.md)
|
|
361
361
|
- Examples: [example/](../../skills/jskit/references/patterns/users/account-settings/example/)
|
|
362
362
|
- Requires: `@jskit-ai/shell-web`, `@jskit-ai/users-core`, `@jskit-ai/users-web`
|
|
@@ -367,7 +367,7 @@ Expose user administration and workspace-scoped member operations through app-ow
|
|
|
367
367
|
|
|
368
368
|
- Id: `users/user-administration-server`
|
|
369
369
|
- Keywords: `account`, `admin`, `member`, `repository`, `resource`, `routes`, `service`, `user`, `workspace`
|
|
370
|
-
- Owner: `@jskit-ai/users-core@0.1.
|
|
370
|
+
- Owner: `@jskit-ai/users-core@0.1.248`
|
|
371
371
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/users/user-administration-server/PATTERN.md)
|
|
372
372
|
- Examples: [example/](../../skills/jskit/references/patterns/users/user-administration-server/example/)
|
|
373
373
|
- Requires: `@jskit-ai/crud-core`, `@jskit-ai/users-core`
|
|
@@ -378,7 +378,7 @@ Configure roles, workspace access policy, invitations, and app-owned invitation
|
|
|
378
378
|
|
|
379
379
|
- Id: `workspaces/workspace-server`
|
|
380
380
|
- Keywords: `access`, `invite`, `membership`, `multitenancy`, `policy`, `role`, `tenancy`, `workspace`
|
|
381
|
-
- Owner: `@jskit-ai/workspaces-core@0.1.
|
|
381
|
+
- Owner: `@jskit-ai/workspaces-core@0.1.213`
|
|
382
382
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/workspaces/workspace-server/PATTERN.md)
|
|
383
383
|
- Examples: [example/](../../skills/jskit/references/patterns/workspaces/workspace-server/example/)
|
|
384
384
|
- Requires: `@jskit-ai/users-core`, `@jskit-ai/workspaces-core`
|
|
@@ -389,7 +389,7 @@ Compose workspace selection, invitation, member administration, settings, and re
|
|
|
389
389
|
|
|
390
390
|
- Id: `workspaces/workspace-surfaces`
|
|
391
391
|
- Keywords: `admin`, `invite`, `member`, `navigation`, `settings`, `surface`, `switcher`, `workspace`
|
|
392
|
-
- Owner: `@jskit-ai/workspaces-web@0.1.
|
|
392
|
+
- Owner: `@jskit-ai/workspaces-web@0.1.214`
|
|
393
393
|
- Read: [PATTERN.md](../../skills/jskit/references/patterns/workspaces/workspace-surfaces/PATTERN.md)
|
|
394
394
|
- Examples: [example/](../../skills/jskit/references/patterns/workspaces/workspace-surfaces/example/)
|
|
395
395
|
- Requires: `@jskit-ai/shell-web`, `@jskit-ai/workspaces-core`, `@jskit-ai/workspaces-web`
|
|
@@ -331,7 +331,7 @@ Local functions
|
|
|
331
331
|
|
|
332
332
|
### `src/server/conversation/claudeTools.js`
|
|
333
333
|
Exports
|
|
334
|
-
- `claudeApplicationToolResponse(request, { schemas, turn, signal })`
|
|
334
|
+
- `claudeApplicationToolResponse(request, { schemas, turn, signal, assertCurrent, onExecutionFailure })`
|
|
335
335
|
- `CLAUDE_APPLICATION_TOOL_SERVER`
|
|
336
336
|
|
|
337
337
|
### `src/server/conversation/claudeTurn.js`
|
|
@@ -39,7 +39,7 @@ Exports
|
|
|
39
39
|
|
|
40
40
|
### `src/synthesisProcess.js`
|
|
41
41
|
Exports
|
|
42
|
-
- `createSynthesisProcess(configuration, { outputSampleRate, workerUrl = new URL("./synthesisWorker.js", import.meta.url) } = {})`
|
|
42
|
+
- `createSynthesisProcess(configuration, { outputSampleRate, signal = null, workerUrl = new URL("./synthesisWorker.js", import.meta.url) } = {})`
|
|
43
43
|
|
|
44
44
|
### `src/synthesisWorker.js`
|
|
45
45
|
Exports
|
|
@@ -34,7 +34,7 @@ Local functions
|
|
|
34
34
|
Exports
|
|
35
35
|
- `mapMembershipSummary(membership, workspace)`
|
|
36
36
|
- `mapWorkspaceSettingsPublic(workspaceSettings, { workspaceInvitationsEnabled = true } = {})`
|
|
37
|
-
- `mapWorkspaceSummary(workspace, membership)`
|
|
37
|
+
- `mapWorkspaceSummary(workspace, membership, roleCatalog = null)`
|
|
38
38
|
|
|
39
39
|
### `src/server/common/repositories/repositoryUtils.js`
|
|
40
40
|
Exports
|
|
@@ -172,7 +172,7 @@ Local functions
|
|
|
172
172
|
|
|
173
173
|
### `src/server/workspaceMembers/defaultWorkspaceInviteEmail.js`
|
|
174
174
|
Exports
|
|
175
|
-
- `renderDefaultWorkspaceInviteEmail({ inviteUrl = "", workspace = {}, inviter = null, roleSid = "member", expiresAt = "" } = {})`
|
|
175
|
+
- `renderDefaultWorkspaceInviteEmail({ inviteUrl = "", workspace = {}, inviter = null, roleSid = "member", roleLabel = "", expiresAt = "" } = {})`
|
|
176
176
|
Local functions
|
|
177
177
|
- `escapeHtml(value = "")`
|
|
178
178
|
|
|
@@ -207,7 +207,7 @@ Exports
|
|
|
207
207
|
|
|
208
208
|
### `src/server/workspacePendingInvitations/workspacePendingInvitationsService.js`
|
|
209
209
|
Exports
|
|
210
|
-
- `createService({ workspaceInvitesRepository, workspaceMembershipsRepository } = {})`
|
|
210
|
+
- `createService({ workspaceInvitesRepository, workspaceMembershipsRepository, roleCatalog = null } = {})`
|
|
211
211
|
|
|
212
212
|
### `src/server/workspaceSettings/bootWorkspaceSettings.js`
|
|
213
213
|
Exports
|
|
@@ -32,6 +32,7 @@ Exports
|
|
|
32
32
|
Exports
|
|
33
33
|
- None
|
|
34
34
|
Local functions
|
|
35
|
+
- `formatRole(roleSid, fallback = roleSid)`
|
|
35
36
|
- `formatDateTime(value)`
|
|
36
37
|
- `showOwnerChip(member)`
|
|
37
38
|
- `isMemberRoleLocked(member)`
|
|
@@ -299,6 +300,16 @@ Exports
|
|
|
299
300
|
Exports
|
|
300
301
|
- `ADMIN_COG_OUTLET`
|
|
301
302
|
|
|
303
|
+
### fixtures
|
|
304
|
+
|
|
305
|
+
### `fixtures/role-labels/main.js`
|
|
306
|
+
Exports
|
|
307
|
+
- None
|
|
308
|
+
|
|
309
|
+
### `fixtures/role-labels/vite.config.mjs`
|
|
310
|
+
Exports
|
|
311
|
+
- None
|
|
312
|
+
|
|
302
313
|
### patterns
|
|
303
314
|
|
|
304
315
|
### `patterns/workspace-surfaces/example/packages/main/src/client/components/AccountPendingInvitesCue.vue`
|
package/skills/jskit/SKILL.md
CHANGED
|
@@ -57,6 +57,15 @@ composables. JSKIT has no general authoring CLI: inspect current source and
|
|
|
57
57
|
installed packages directly, edit app-owned files deliberately, and use npm
|
|
58
58
|
for dependency installation.
|
|
59
59
|
|
|
60
|
+
Finish a dependency installation before inspecting the installed package or
|
|
61
|
+
changing the same manifest/lockfile; do not overlap npm operations on one app. Import
|
|
62
|
+
subpaths are package `exports` aliases, not physical file paths: a package may
|
|
63
|
+
map `client/...` to `src/client/...` and keep shared code outside `src`. If source
|
|
64
|
+
inspection is still needed, resolve the import with the installed `package.json`
|
|
65
|
+
`exports` or `import.meta.resolve()`, or locate the file with `rg --files` before
|
|
66
|
+
opening it. Do not guess a package's directory layout. Use the documented option
|
|
67
|
+
when the guide or pattern already explains the required behaviour.
|
|
68
|
+
|
|
60
69
|
## Implement a change
|
|
61
70
|
|
|
62
71
|
Read the matching pattern and reference, then implement the smallest complete
|
|
@@ -41,6 +41,168 @@ Add resource service methods with `decorateService`; expose commands such as
|
|
|
41
41
|
services and hooks orchestrate. Use a transactional outbox for durable
|
|
42
42
|
external work.
|
|
43
43
|
|
|
44
|
+
## Choose ownership, API access and client access independently
|
|
45
|
+
|
|
46
|
+
These controls answer different questions:
|
|
47
|
+
|
|
48
|
+
| Control | Purpose | Public records | Owner-scoped records |
|
|
49
|
+
| --- | --- | --- | --- |
|
|
50
|
+
| Resource `autofilter` | Which rows belong to the request scope | `"public"`; no ownership column | `"user"`; real non-null `userId` column |
|
|
51
|
+
| Resource `apiAccess` | Who may call the API | `"public"` | `"authenticated"` |
|
|
52
|
+
| Feature `ownershipFilter` | Server route/action ownership scope | `"public"` | `"user"` |
|
|
53
|
+
| Client `access` | Whether to require bootstrap permissions | Default `"auto"` with no permission requirements | Default `"auto"`; declare permissions when required |
|
|
54
|
+
|
|
55
|
+
`access` accepts `auto`, `always`, or `never`, not `public`. With `auto`, a
|
|
56
|
+
screen with no permission requirements does not require a permissions bootstrap.
|
|
57
|
+
`always` does require it. Do not add authentication or workspace machinery to
|
|
58
|
+
compensate for an unnecessary `always` override. Server access and ownership
|
|
59
|
+
remain authoritative.
|
|
60
|
+
|
|
61
|
+
The Books source patterns demonstrate user ownership. For an intentionally
|
|
62
|
+
public create/list resource, use the same patterns with this resource contract:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
const bookResource = defineCrudResource({
|
|
66
|
+
namespace: "books",
|
|
67
|
+
tableName: "books",
|
|
68
|
+
apiAccess: "public",
|
|
69
|
+
autofilter: "public",
|
|
70
|
+
crudOperations: ["list", "view", "create"],
|
|
71
|
+
schema: {
|
|
72
|
+
title: {
|
|
73
|
+
type: "string",
|
|
74
|
+
required: true,
|
|
75
|
+
minLength: 1,
|
|
76
|
+
maxLength: 255,
|
|
77
|
+
operations: {
|
|
78
|
+
output: { required: true },
|
|
79
|
+
create: { required: true }
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Import `defineCrudResource` from
|
|
87
|
+
`@jskit-ai/resource-crud-core/shared/crudResource`. Its app-owned migration
|
|
88
|
+
creates `books` with an integer primary key `id` and non-null `title`; omit
|
|
89
|
+
`userId` and its foreign key for this public variant. `list` requires `view`
|
|
90
|
+
in the shared resource contract, even when the UI has no detail page. A create
|
|
91
|
+
response uses the resource output contract. Keep operation names such as
|
|
92
|
+
`list`, `view` and `create`; do not invent output-operation aliases.
|
|
93
|
+
|
|
94
|
+
Bind `defineCrudJsonApiFeature()` with this resource, `ownershipFilter:
|
|
95
|
+
"public"`, `relativePath: "/books"` and the application's configured public
|
|
96
|
+
surface. Keep the existing package/provider and migration registration from
|
|
97
|
+
`crud/json-api-resource-package`.
|
|
98
|
+
|
|
99
|
+
For the list, keep `BookListPage.vue` thin: use `resourceNamespace: "books"`
|
|
100
|
+
in `useCrudListScreen()` on the configured public surface, remove unsupported
|
|
101
|
+
edit/delete actions and optional author/notes filters, and point **New** to
|
|
102
|
+
the create route. For the new page, use the title field only and set:
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
addEditOptions: {
|
|
106
|
+
apiSuffix: "/books",
|
|
107
|
+
ownershipFilter: "public",
|
|
108
|
+
queryKeyFactory: (surfaceId = "") => ["crud", "books", surfaceId, "new"],
|
|
109
|
+
readEnabled: false,
|
|
110
|
+
writeMethod: "POST",
|
|
111
|
+
listUrlTemplate: "/books"
|
|
112
|
+
},
|
|
113
|
+
saveSuccess: {
|
|
114
|
+
invalidateQueryKey: ["crud", "books"],
|
|
115
|
+
navigateToView: false,
|
|
116
|
+
listUrlTemplate: "/books"
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
List/view screen wrappers derive request scope from the configured surface;
|
|
121
|
+
they do not expose an `ownershipFilter` option. Use a surface without workspace
|
|
122
|
+
route parameters for this public example. Form options and lower-level request
|
|
123
|
+
composables accept `ownershipFilter` explicitly.
|
|
124
|
+
|
|
125
|
+
New/Edit form runtimes require `queryKeyFactory` even with reads disabled.
|
|
126
|
+
For editing, include the reactive record id; for workspace-scoped resources,
|
|
127
|
+
include the route scope too. List/view screen wrappers derive standard keys
|
|
128
|
+
from `resourceNamespace`. Leave `access` at its default when no permissions
|
|
129
|
+
are declared. Verify create, list, blank-name rejection and reload persistence
|
|
130
|
+
without signing in for this public variant; owner-scoped variants additionally
|
|
131
|
+
need cross-owner denial tests.
|
|
132
|
+
|
|
133
|
+
## Save navigation
|
|
134
|
+
|
|
135
|
+
`useCrudAddEditScreen()` accepts `saveSuccess` at the top level. After saving,
|
|
136
|
+
the default behaviour invalidates `saveSuccess.invalidateQueryKey`, navigates
|
|
137
|
+
to a configured record-view URL when one resolves, and otherwise falls back to
|
|
138
|
+
the list URL. For a create-and-list app, use `navigateToView: false` and the
|
|
139
|
+
configured `listUrlTemplate`, as in the public example above. The list URL may
|
|
140
|
+
also come from `addEditOptions.listUrlTemplate`.
|
|
141
|
+
|
|
142
|
+
To keep the saved form open, set both `saveSuccess.navigateToView` and
|
|
143
|
+
`saveSuccess.navigateToList` to `false`. `addEditOptions.onSaveSuccess` replaces
|
|
144
|
+
the default success handling, including query invalidation and navigation;
|
|
145
|
+
reserve it for custom success behaviour. Returning to the list needs only the
|
|
146
|
+
documented `saveSuccess` options, not a custom router callback or inspection of
|
|
147
|
+
the shared form implementation.
|
|
148
|
+
|
|
149
|
+
## Browser routes and responsive lists
|
|
150
|
+
|
|
151
|
+
`newUrlTemplate`, `viewUrlTemplate`, `editUrlTemplate`, `listUrlTemplate`, and
|
|
152
|
+
`cancelTo` describe browser routes, not surface-relative API suffixes. Include
|
|
153
|
+
the configured surface prefix: if a public library lives at `/library`, its new
|
|
154
|
+
page is `/library/new` and its list is `/library`, not `/new` and `/`. For links
|
|
155
|
+
without record placeholders, `paths.page()` can resolve the configured surface;
|
|
156
|
+
for record placeholders use the current CRUD runtime's `resolveParams()`.
|
|
157
|
+
Request-scope inference does not add missing prefixes to browser links.
|
|
158
|
+
|
|
159
|
+
`CrudListScreen` uses `createLabel` for its toolbar, empty-state and compact
|
|
160
|
+
create actions. Its card and table layouts coexist in the DOM, with CSS choosing
|
|
161
|
+
the visible layout. Browser assertions on record text must select the visible
|
|
162
|
+
match, for example `page.getByText(title, { exact: true }).filter({ visible: true })`.
|
|
163
|
+
When the same create action appears in more than one visible location, choose
|
|
164
|
+
one visible action deliberately; do not relax the expected label to accept an
|
|
165
|
+
unrelated fallback.
|
|
166
|
+
|
|
167
|
+
## Direct API tests use JSON:API documents
|
|
168
|
+
|
|
169
|
+
JSKIT's CRUD screens and HTTP client apply the resource's JSON:API transport
|
|
170
|
+
automatically. Direct Playwright `request` calls and other raw HTTP clients must
|
|
171
|
+
supply that transport themselves. An ordinary JSON body such as `{ title }`
|
|
172
|
+
with `Content-Type: application/json` does not test field validation on a
|
|
173
|
+
JSON:API route; it is rejected as an unsupported media type (HTTP 415).
|
|
174
|
+
|
|
175
|
+
Use the application's actual API base and scope, not its page URL. For the
|
|
176
|
+
public Books resource above, with API base `/api` and transport type `books`:
|
|
177
|
+
|
|
178
|
+
```js
|
|
179
|
+
const headers = {
|
|
180
|
+
"Content-Type": "application/vnd.api+json",
|
|
181
|
+
Accept: "application/vnd.api+json"
|
|
182
|
+
};
|
|
183
|
+
const response = await request.post("/api/books", {
|
|
184
|
+
headers,
|
|
185
|
+
data: {
|
|
186
|
+
data: {
|
|
187
|
+
type: "books",
|
|
188
|
+
attributes: { title: "Kindred" }
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
expect(response.status()).toBe(201);
|
|
193
|
+
const document = await response.json();
|
|
194
|
+
expect(document.data.attributes.title).toBe("Kindred");
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Keep the same headers and `data.type/attributes` envelope when testing invalid
|
|
198
|
+
field values; for this contract, an empty `title` or one over 255 characters
|
|
199
|
+
should return HTTP 400. Raw responses contain fields under `data.attributes`,
|
|
200
|
+
while the shared client simplifies resource responses. A collection response
|
|
201
|
+
has an array in `data`. Match `data.type` to the configured resource transport;
|
|
202
|
+
retain the application's existing identity and CSRF fixture for protected APIs.
|
|
203
|
+
Prefer the shared resource client for application requests rather than copying
|
|
204
|
+
this raw test encoding into page code.
|
|
205
|
+
|
|
44
206
|
## Record deletion
|
|
45
207
|
|
|
46
208
|
Deletion requires an explicit shared `DELETE` operation and confirmation
|
|
@@ -39,6 +39,35 @@ before an operation discloses records or record existence.
|
|
|
39
39
|
membership semantics exactly; do not synthesize memberships to compensate for
|
|
40
40
|
a policy/runtime mismatch.
|
|
41
41
|
|
|
42
|
+
## Role display labels
|
|
43
|
+
|
|
44
|
+
Set optional `label` strings in the existing `roleCatalog.roles` definitions,
|
|
45
|
+
usually exported by `config/roles.js` and composed into application config.
|
|
46
|
+
For example, the package-owned `workspaces/workspace-server` example labels
|
|
47
|
+
`admin` as **Administrator** and `member` as **Team member**. Any application
|
|
48
|
+
role id can have its own label.
|
|
49
|
+
|
|
50
|
+
Labels are trimmed; missing, blank or non-string labels use the previous
|
|
51
|
+
display fallback. Labels do not inherit. They survive catalogue creation,
|
|
52
|
+
cloning and descriptor listing, and the Members, Invitations and Workspace
|
|
53
|
+
Settings API response schemas preserve them. Descriptors have optional
|
|
54
|
+
`label`; pending/resolved invitation and workspace-list records have optional
|
|
55
|
+
`roleLabel` beside `roleSid`.
|
|
56
|
+
|
|
57
|
+
On **Members**, both the invitation **Role** selector and each member's role
|
|
58
|
+
selector display configured labels. Choose a label, enter the invite email
|
|
59
|
+
and select **Send invite**, or choose a member's new role. Requests and stored
|
|
60
|
+
memberships still use role ids. Reloading shows the selected role's label.
|
|
61
|
+
Pending invitation captions, workspace role captions and the default
|
|
62
|
+
invitation email use configured labels too. Custom email renderers receive
|
|
63
|
+
optional `roleLabel` in addition to `roleSid`.
|
|
64
|
+
|
|
65
|
+
Add labels without changing existing permissions, inheritance, assignability
|
|
66
|
+
or `workspace.defaultInviteRole`. This supports application-specific and
|
|
67
|
+
Training roles without renaming them. `owner` is never assignable. An
|
|
68
|
+
application whose default invitation role is `worker` keeps that default even
|
|
69
|
+
if its display label is **Member**. No database migration is needed.
|
|
70
|
+
|
|
42
71
|
## Transactional invitation participation
|
|
43
72
|
|
|
44
73
|
Use `workspaces.core` to connect application records during the built-in
|