@cosmicdrift/kumiko-framework 0.269.2 → 0.273.0
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/README.md +5 -1
- package/package.json +3 -3
- package/src/__tests__/anonymous-access.integration.test.ts +1 -1
- package/src/__tests__/error-contract.integration.test.ts +1 -1
- package/src/__tests__/fixtures/migrate-cross-tenant/manual-only.expected.ts +44 -0
- package/src/__tests__/fixtures/migrate-cross-tenant/manual-only.input.ts +44 -0
- package/src/__tests__/fixtures/migrate-cross-tenant/rewrite.expected.ts +41 -0
- package/src/__tests__/fixtures/migrate-cross-tenant/rewrite.input.ts +41 -0
- package/src/__tests__/fixtures/migrate-open-to-all/manual-only.expected.ts +16 -0
- package/src/__tests__/fixtures/migrate-open-to-all/manual-only.input.ts +16 -0
- package/src/__tests__/fixtures/migrate-open-to-all/test-nested-shorthand.expected.ts +12 -0
- package/src/__tests__/fixtures/migrate-open-to-all/test-nested-shorthand.input.ts +12 -0
- package/src/__tests__/fixtures/migrate-open-to-all/test-simple.expected.ts +7 -0
- package/src/__tests__/fixtures/migrate-open-to-all/test-simple.input.ts +7 -0
- package/src/__tests__/full-stack.integration.test.ts +2 -2
- package/src/__tests__/migrate-cross-tenant-codemod.test.ts +106 -0
- package/src/__tests__/migrate-open-to-all-codemod.test.ts +84 -0
- package/src/__tests__/related-list-parent-filter.integration.test.ts +103 -0
- package/src/__tests__/transition-guard.integration.test.ts +7 -7
- package/src/api/__tests__/api.test.ts +2 -2
- package/src/api/__tests__/body-limit.test.ts +1 -1
- package/src/api/__tests__/nested-write-ownership.integration.test.ts +268 -0
- package/src/api/__tests__/pii-leak-guard.integration.test.ts +2 -2
- package/src/api/__tests__/request-locale.integration.test.ts +1 -1
- package/src/api/__tests__/server-error-logging.test.ts +1 -1
- package/src/api/server.ts +7 -20
- package/src/bun-db/__tests__/query-guards.test.ts +60 -3
- package/src/bun-db/query.ts +24 -21
- package/src/changes.json +99 -0
- package/src/db/__tests__/event-store-executor-write-verbs.integration.test.ts +77 -0
- package/src/db/__tests__/event-store-executor.integration.test.ts +1 -1
- package/src/db/__tests__/list-filter-field-access.integration.test.ts +1 -1
- package/src/db/__tests__/replay-migration-sql.test.ts +17 -0
- package/src/db/__tests__/tenant-db-convention-cross-tenant.test.ts +72 -0
- package/src/db/__tests__/tenant-db-declared-unsafe-raw.test.ts +104 -0
- package/src/db/__tests__/tenant-db-global.test.ts +92 -0
- package/src/db/__tests__/tenant-db-no-raw.test.ts +75 -0
- package/src/db/__tests__/tenant-db.integration.test.ts +3 -1
- package/src/db/__tests__/unchecked-system-db.test.ts +76 -0
- package/src/db/apply-entity-event.ts +1 -1
- package/src/db/assert-exists-in.ts +1 -1
- package/src/db/event-store-executor-context.ts +5 -2
- package/src/db/event-store-executor-read.ts +6 -4
- package/src/db/event-store-executor-write.ts +24 -18
- package/src/db/queries/shadow-swap.ts +36 -0
- package/src/db/replay-migration-sql.ts +5 -5
- package/src/db/tenant-db-runner.ts +23 -0
- package/src/db/tenant-db.ts +97 -24
- package/src/derivatives/__tests__/derivatives-context.integration.test.ts +2 -2
- package/src/derivatives/__tests__/derivatives-context.test.ts +0 -1
- package/src/engine/__tests__/boot-validator-dashboard.test.ts +5 -5
- package/src/engine/__tests__/boot-validator-nav-area.test.ts +116 -0
- package/src/engine/__tests__/boot-validator-pii-retention.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-projection-list.test.ts +108 -17
- package/src/engine/__tests__/boot-validator-query-output-schema.test.ts +161 -18
- package/src/engine/__tests__/boot-validator-query-refs.test.ts +3 -3
- package/src/engine/__tests__/boot-validator-s0-integration.test.ts +2 -2
- package/src/engine/__tests__/boot-validator.test.ts +69 -18
- package/src/engine/__tests__/build-app-schema.test.ts +10 -6
- package/src/engine/__tests__/build-config-feature-schema-secrets.test.ts +48 -0
- package/src/engine/__tests__/build-config-feature-schema.test.ts +34 -5
- package/src/engine/__tests__/engine.test.ts +39 -25
- package/src/engine/__tests__/entity-create-caller-id.integration.test.ts +87 -0
- package/src/engine/__tests__/entity-handlers-escape-hatch.test.ts +91 -0
- package/src/engine/__tests__/entity-handlers.test.ts +47 -8
- package/src/engine/__tests__/entity-presave-wiring.integration.test.ts +2 -2
- package/src/engine/__tests__/entity-restore-tenant-isolation.integration.test.ts +30 -5
- package/src/engine/__tests__/entity-write-crosstenant.integration.test.ts +206 -47
- package/src/engine/__tests__/extends-registrar.test.ts +3 -3
- package/src/engine/__tests__/feature-crud-shorthand.test.ts +9 -3
- package/src/engine/__tests__/feature-crud-verb-access.integration.test.ts +1 -1
- package/src/engine/__tests__/hook-phases.test.ts +5 -5
- package/src/engine/__tests__/lifecycle-hooks.test.ts +9 -3
- package/src/engine/__tests__/multiselect-filter.integration.test.ts +1 -1
- package/src/engine/__tests__/post-query-hook.test.ts +6 -2
- package/src/engine/__tests__/projection-detail-actions.test.ts +2 -2
- package/src/engine/__tests__/projection-detail-singleton.test.ts +3 -3
- package/src/engine/__tests__/projection-detail-tabs.test.ts +3 -3
- package/src/engine/__tests__/projection-list-filter.integration.test.ts +1 -1
- package/src/engine/__tests__/read-steps-tenant-filter.integration.test.ts +215 -0
- package/src/engine/__tests__/registry.test.ts +19 -13
- package/src/engine/__tests__/required-surface-keys.test.ts +16 -0
- package/src/engine/__tests__/screen.test.ts +176 -20
- package/src/engine/__tests__/soft-delete-cleanup.test.ts +0 -1
- package/src/engine/__tests__/steps-read.test.ts +204 -8
- package/src/engine/__tests__/steps-unsafe-projection-delete.test.ts +7 -4
- package/src/engine/__tests__/steps-unsafe-projection-upsert.test.ts +6 -3
- package/src/engine/boot-validator/__tests__/access-declarations.test.ts +5 -4
- package/src/engine/boot-validator/__tests__/global-tenancy.test.ts +16 -1
- package/src/engine/boot-validator/__tests__/parent-ref.test.ts +18 -6
- package/src/engine/boot-validator/__tests__/rate-limit-disabled-reason.test.ts +45 -0
- package/src/engine/boot-validator/access-declarations.ts +3 -5
- package/src/engine/boot-validator/entity-handler.ts +21 -0
- package/src/engine/boot-validator/global-tenancy.ts +13 -1
- package/src/engine/boot-validator/nav.ts +4 -3
- package/src/engine/boot-validator/parent-ref.ts +1 -1
- package/src/engine/boot-validator/projection-list-screens.ts +67 -2
- package/src/engine/boot-validator/query-output-columns.ts +33 -0
- package/src/engine/boot-validator/screens.ts +154 -31
- package/src/engine/build-config-feature-schema.ts +12 -2
- package/src/engine/entity-handlers.ts +72 -20
- package/src/engine/feature-ast/__tests__/canonical-form.test.ts +3 -1
- package/src/engine/feature-ast/__tests__/parse-happy-path.test.ts +2 -2
- package/src/engine/feature-ast/__tests__/parse.test.ts +106 -4
- package/src/engine/feature-ast/__tests__/patcher.test.ts +3 -3
- package/src/engine/feature-ast/__tests__/read-optional-access-rule.test.ts +4 -4
- package/src/engine/feature-ast/__tests__/render-roundtrip.test.ts +5 -1
- package/src/engine/feature-ast/extractors/handlers.ts +16 -2
- package/src/engine/feature-ast/extractors/hooks.ts +25 -4
- package/src/engine/feature-ast/patcher.ts +15 -3
- package/src/engine/feature-ast/patterns.ts +4 -0
- package/src/engine/feature-ast/render.ts +3 -0
- package/src/engine/feature-entity-handlers.ts +4 -4
- package/src/engine/index.ts +5 -0
- package/src/engine/pattern-library/shared-fields.ts +7 -3
- package/src/engine/registry-validate.ts +12 -4
- package/src/engine/schema-builder.ts +6 -0
- package/src/engine/screen-helpers.ts +52 -0
- package/src/engine/steps/_read-source.ts +12 -0
- package/src/engine/steps/read-find-many.ts +8 -2
- package/src/engine/steps/read-find-one.ts +11 -8
- package/src/engine/steps/unsafe-projection-delete.ts +2 -1
- package/src/engine/steps/unsafe-projection-upsert.ts +2 -1
- package/src/engine/types/index.ts +8 -1
- package/src/entrypoint/__tests__/entrypoint-attach-dispatcher.integration.test.ts +1 -1
- package/src/entrypoint/__tests__/entrypoint-job-wiring.integration.test.ts +3 -3
- package/src/entrypoint/__tests__/split-deploy.integration.test.ts +1 -1
- package/src/errors/i18n/de.yaml +14 -0
- package/src/errors/i18n/en.yaml +13 -0
- package/src/errors/reasons.ts +4 -0
- package/src/es-ops/__tests__/runner.integration.test.ts +2 -2
- package/src/i18n/required-surface-keys.ts +6 -2
- package/src/jobs/__tests__/job-event-trigger.integration.test.ts +2 -2
- package/src/jobs/__tests__/job-multi-trigger.integration.test.ts +2 -2
- package/src/jobs/__tests__/job-systemdb.integration.test.ts +5 -4
- package/src/jobs/__tests__/jobs.integration.test.ts +42 -1
- package/src/jobs/job-runner.ts +35 -5
- package/src/observability/__tests__/observability.integration.test.ts +7 -7
- package/src/pipeline/__tests__/archive-stream.integration.test.ts +2 -2
- package/src/pipeline/__tests__/dispatcher.test.ts +15 -15
- package/src/pipeline/__tests__/escape-hatch-audit.integration.test.ts +254 -0
- package/src/pipeline/__tests__/escape-hatch-report.test.ts +149 -0
- package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +10 -10
- package/src/pipeline/__tests__/load-aggregate-query.integration.test.ts +1 -1
- package/src/pipeline/__tests__/msp-rebuild.integration.test.ts +28 -0
- package/src/pipeline/__tests__/post-query-hook.integration.test.ts +3 -3
- package/src/pipeline/__tests__/projection-rebuild.integration.test.ts +94 -0
- package/src/pipeline/__tests__/projections-runner-systemscope.integration.test.ts +101 -0
- package/src/pipeline/__tests__/query-projection.integration.test.ts +172 -17
- package/src/pipeline/__tests__/rate-limit-default.integration.test.ts +118 -0
- package/src/pipeline/__tests__/rate-limit-default.test.ts +117 -0
- package/src/pipeline/__tests__/search-consumer-named-events.integration.test.ts +5 -2
- package/src/pipeline/__tests__/system-identity-switch.test.ts +240 -1
- package/src/pipeline/dispatch-query.ts +27 -8
- package/src/pipeline/dispatch-shared.ts +141 -57
- package/src/pipeline/dispatch-stream.ts +1 -3
- package/src/pipeline/dispatch-write.ts +62 -14
- package/src/pipeline/dispatcher.ts +20 -0
- package/src/pipeline/escape-hatch-report.ts +127 -0
- package/src/pipeline/index.ts +8 -0
- package/src/pipeline/member-read-only-transaction.ts +75 -0
- package/src/pipeline/msp-rebuild.ts +2 -0
- package/src/pipeline/projection-rebuild.ts +2 -0
- package/src/pipeline/projections-runner.ts +15 -13
- package/src/pipeline/system-identity-switch.ts +121 -9
- package/src/scripts/codemod/migrate-cross-tenant.ts +335 -0
- package/src/scripts/codemod/migrate-db-raw.ts +19 -6
- package/src/scripts/codemod/migrate-open-to-all.ts +249 -0
- package/src/secrets/__tests__/contains-secret.test.ts +5 -5
- package/src/stack/__tests__/request-helper.integration.test.ts +3 -3
- package/src/stack/__tests__/setup-test-stack-jobs.integration.test.ts +1 -1
- package/src/testing/__tests__/e2e-generator.test.ts +19 -5
- package/src/ui-types/index.ts +3 -0
- package/src/utils/__tests__/ids.test.ts +29 -1
- package/src/utils/ids.ts +10 -1
- package/src/utils/index.ts +1 -1
|
@@ -2,12 +2,13 @@ import { describe, expect, test } from "bun:test";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { validateBoot } from "../boot-validator";
|
|
4
4
|
import { defineFeature } from "../define-feature";
|
|
5
|
+
import { createEntity, createTextField } from "../factories";
|
|
5
6
|
|
|
6
7
|
describe("validateBoot — projectionList screens", () => {
|
|
7
8
|
test("rejects hand-written searchable:true when the query schema has no search param (3a)", () => {
|
|
8
9
|
const feature = defineFeature("ledger", (r) => {
|
|
9
10
|
r.queryHandler("schedule:list", z.object({}), async () => ({ rows: [], nextCursor: null }), {
|
|
10
|
-
access: { openToAll:
|
|
11
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
11
12
|
});
|
|
12
13
|
r.screen({
|
|
13
14
|
id: "schedule-list",
|
|
@@ -29,7 +30,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
29
30
|
"schedule:list",
|
|
30
31
|
z.object({ search: z.string().optional() }),
|
|
31
32
|
async () => ({ rows: [], nextCursor: null }),
|
|
32
|
-
{ access: { openToAll:
|
|
33
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
33
34
|
);
|
|
34
35
|
r.screen({
|
|
35
36
|
id: "schedule-list",
|
|
@@ -50,7 +51,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
50
51
|
"schedule:list",
|
|
51
52
|
z.object({ sort: z.string().optional() }),
|
|
52
53
|
async () => ({ rows: [], nextCursor: null }),
|
|
53
|
-
{ access: { openToAll:
|
|
54
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
54
55
|
);
|
|
55
56
|
r.screen({
|
|
56
57
|
id: "schedule-list",
|
|
@@ -71,7 +72,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
71
72
|
"schedule:list",
|
|
72
73
|
z.object({ search: z.string().optional(), sort: z.string().optional() }),
|
|
73
74
|
async () => ({ rows: [], nextCursor: null }),
|
|
74
|
-
{ access: { openToAll:
|
|
75
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
75
76
|
);
|
|
76
77
|
r.screen({
|
|
77
78
|
id: "schedule-list",
|
|
@@ -91,7 +92,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
91
92
|
test("passes when the schema offers neither search nor sort and no defaultSort is set", () => {
|
|
92
93
|
const feature = defineFeature("ledger", (r) => {
|
|
93
94
|
r.queryHandler("schedule:list", z.object({}), async () => ({ rows: [], nextCursor: null }), {
|
|
94
|
-
access: { openToAll:
|
|
95
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
95
96
|
});
|
|
96
97
|
r.screen({
|
|
97
98
|
id: "schedule-list",
|
|
@@ -112,7 +113,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
112
113
|
"schedule:list",
|
|
113
114
|
z.object({ search: z.string().optional() }),
|
|
114
115
|
async () => ({ rows: [], nextCursor: null }),
|
|
115
|
-
{ access: { openToAll:
|
|
116
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
116
117
|
);
|
|
117
118
|
r.screen({
|
|
118
119
|
id: "schedule-list",
|
|
@@ -135,7 +136,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
135
136
|
"schedule:list",
|
|
136
137
|
z.object({ search: z.string().optional() }),
|
|
137
138
|
async () => ({ rows: [], nextCursor: null }),
|
|
138
|
-
{ access: { openToAll:
|
|
139
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
139
140
|
);
|
|
140
141
|
r.screen({
|
|
141
142
|
id: "download-attempt-list",
|
|
@@ -154,7 +155,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
154
155
|
test("rejects hand-authored sortable on a projectionList screen (fw#2165 review)", () => {
|
|
155
156
|
const feature = defineFeature("ledger", (r) => {
|
|
156
157
|
r.queryHandler("schedule:list", z.object({}), async () => ({ rows: [], nextCursor: null }), {
|
|
157
|
-
access: { openToAll:
|
|
158
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
158
159
|
});
|
|
159
160
|
r.screen({
|
|
160
161
|
id: "schedule-list",
|
|
@@ -173,7 +174,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
173
174
|
test("rejects hand-authored paginated on a projectionList screen (fw#2165 review)", () => {
|
|
174
175
|
const feature = defineFeature("ledger", (r) => {
|
|
175
176
|
r.queryHandler("schedule:list", z.object({}), async () => ({ rows: [], nextCursor: null }), {
|
|
176
|
-
access: { openToAll:
|
|
177
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
177
178
|
});
|
|
178
179
|
r.screen({
|
|
179
180
|
id: "schedule-list",
|
|
@@ -202,7 +203,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
202
203
|
z.object({}),
|
|
203
204
|
async () => ({ rows: [], nextCursor: null }),
|
|
204
205
|
{
|
|
205
|
-
access: { openToAll:
|
|
206
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
206
207
|
},
|
|
207
208
|
);
|
|
208
209
|
r.screen({ id: "schedule-detail", type: "custom", renderer: { react: "stub" } });
|
|
@@ -251,7 +252,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
251
252
|
"schedule:list",
|
|
252
253
|
z.object({ filter: z.unknown().optional() }),
|
|
253
254
|
async () => ({ rows: [], nextCursor: null }),
|
|
254
|
-
{ access: { openToAll:
|
|
255
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
255
256
|
);
|
|
256
257
|
r.screen({
|
|
257
258
|
id: "schedule-list",
|
|
@@ -274,7 +275,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
274
275
|
z.object({}),
|
|
275
276
|
async () => ({ rows: [], nextCursor: null }),
|
|
276
277
|
{
|
|
277
|
-
access: { openToAll:
|
|
278
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
278
279
|
},
|
|
279
280
|
);
|
|
280
281
|
r.screen({
|
|
@@ -297,7 +298,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
297
298
|
"schedule:list",
|
|
298
299
|
z.object({ filters: z.unknown().optional() }),
|
|
299
300
|
async () => ({ rows: [], nextCursor: null }),
|
|
300
|
-
{ access: { openToAll:
|
|
301
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
301
302
|
);
|
|
302
303
|
r.screen({
|
|
303
304
|
id: "schedule-list",
|
|
@@ -326,7 +327,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
326
327
|
"schedule:list",
|
|
327
328
|
z.object({ filters: z.unknown().optional() }),
|
|
328
329
|
async () => ({ rows: [], nextCursor: null }),
|
|
329
|
-
{ access: { openToAll:
|
|
330
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
330
331
|
);
|
|
331
332
|
r.screen({
|
|
332
333
|
id: "schedule-list",
|
|
@@ -363,7 +364,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
363
364
|
"schedule:list",
|
|
364
365
|
z.object({ filters: z.unknown().optional() }),
|
|
365
366
|
async () => ({ rows: [], nextCursor: null }),
|
|
366
|
-
{ access: { openToAll:
|
|
367
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
367
368
|
);
|
|
368
369
|
r.screen({
|
|
369
370
|
id: "schedule-list",
|
|
@@ -386,7 +387,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
386
387
|
z.object({}),
|
|
387
388
|
async () => ({ rows: [], nextCursor: null }),
|
|
388
389
|
{
|
|
389
|
-
access: { openToAll:
|
|
390
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
390
391
|
},
|
|
391
392
|
);
|
|
392
393
|
r.screen({
|
|
@@ -417,7 +418,7 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
417
418
|
"schedule:list",
|
|
418
419
|
z.object({ filter: z.unknown().optional(), filters: z.unknown().optional() }),
|
|
419
420
|
async () => ({ rows: [], nextCursor: null }),
|
|
420
|
-
{ access: { openToAll:
|
|
421
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
421
422
|
);
|
|
422
423
|
r.screen({
|
|
423
424
|
id: "schedule-list",
|
|
@@ -441,5 +442,95 @@ describe("validateBoot — projectionList screens", () => {
|
|
|
441
442
|
});
|
|
442
443
|
expect(() => validateBoot([feature])).not.toThrow();
|
|
443
444
|
});
|
|
445
|
+
|
|
446
|
+
test("a reference facet targeting an unknown entity is rejected", () => {
|
|
447
|
+
const feature = defineFeature("ledger", (r) => {
|
|
448
|
+
r.queryHandler(
|
|
449
|
+
"schedule:list",
|
|
450
|
+
z.object({ filters: z.unknown().optional() }),
|
|
451
|
+
async () => ({ rows: [], nextCursor: null }),
|
|
452
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
453
|
+
);
|
|
454
|
+
r.screen({
|
|
455
|
+
id: "schedule-list",
|
|
456
|
+
type: "projectionList",
|
|
457
|
+
query: "ledger:query:schedule:list",
|
|
458
|
+
columns: ["tenant"],
|
|
459
|
+
facets: [{ field: "tenant", type: "reference", label: "Tenant", entity: "tenant" }],
|
|
460
|
+
});
|
|
461
|
+
r.translations({
|
|
462
|
+
keys: { "screen:schedule-list.title": { de: "Liste", en: "List" } },
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
expect(() => validateBoot([feature])).toThrow(/does not resolve to a registered entity/);
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
test("a reference facet targeting a known entity passes boot", () => {
|
|
469
|
+
const feature = defineFeature("ledger", (r) => {
|
|
470
|
+
r.entity(
|
|
471
|
+
"tenant",
|
|
472
|
+
createEntity({
|
|
473
|
+
table: "Tenants",
|
|
474
|
+
fields: { name: createTextField({ personal: false, reason: "test_fixture" }) },
|
|
475
|
+
}),
|
|
476
|
+
);
|
|
477
|
+
r.queryHandler(
|
|
478
|
+
"schedule:list",
|
|
479
|
+
z.object({ filters: z.unknown().optional() }),
|
|
480
|
+
async () => ({ rows: [], nextCursor: null }),
|
|
481
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
482
|
+
);
|
|
483
|
+
r.screen({
|
|
484
|
+
id: "schedule-list",
|
|
485
|
+
type: "projectionList",
|
|
486
|
+
query: "ledger:query:schedule:list",
|
|
487
|
+
columns: ["tenant"],
|
|
488
|
+
facets: [{ field: "tenant", type: "reference", label: "Tenant", entity: "tenant" }],
|
|
489
|
+
});
|
|
490
|
+
r.translations({
|
|
491
|
+
keys: {
|
|
492
|
+
"screen:schedule-list.title": { de: "Liste", en: "List" },
|
|
493
|
+
"ledger:entity:tenant:field:name": { de: "Name", en: "Name" },
|
|
494
|
+
},
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
expect(() => validateBoot([feature])).not.toThrow();
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
test("a reference facet filtering by an id field with no same-named column boots (displays a different label column)", () => {
|
|
501
|
+
const feature = defineFeature("ledger", (r) => {
|
|
502
|
+
r.entity(
|
|
503
|
+
"property",
|
|
504
|
+
createEntity({
|
|
505
|
+
table: "Properties",
|
|
506
|
+
fields: { name: createTextField({ personal: false, reason: "test_fixture" }) },
|
|
507
|
+
}),
|
|
508
|
+
);
|
|
509
|
+
r.queryHandler(
|
|
510
|
+
"schedule:list",
|
|
511
|
+
z.object({ filters: z.unknown().optional() }),
|
|
512
|
+
async () => ({ rows: [], nextCursor: null }),
|
|
513
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
514
|
+
);
|
|
515
|
+
r.screen({
|
|
516
|
+
id: "schedule-list",
|
|
517
|
+
type: "projectionList",
|
|
518
|
+
query: "ledger:query:schedule:list",
|
|
519
|
+
// Filters by propertyId, displays propertyLabel — no "propertyId"
|
|
520
|
+
// column exists, and none should be required for a reference facet.
|
|
521
|
+
columns: ["propertyLabel"],
|
|
522
|
+
facets: [
|
|
523
|
+
{ field: "propertyId", type: "reference", label: "Property", entity: "property" },
|
|
524
|
+
],
|
|
525
|
+
});
|
|
526
|
+
r.translations({
|
|
527
|
+
keys: {
|
|
528
|
+
"screen:schedule-list.title": { de: "Liste", en: "List" },
|
|
529
|
+
"ledger:entity:property:field:name": { de: "Name", en: "Name" },
|
|
530
|
+
},
|
|
531
|
+
});
|
|
532
|
+
});
|
|
533
|
+
expect(() => validateBoot([feature])).not.toThrow();
|
|
534
|
+
});
|
|
444
535
|
});
|
|
445
536
|
});
|
|
@@ -20,7 +20,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
20
20
|
test("projectionList column not in the paged query's row shape throws", () => {
|
|
21
21
|
const feature = defineFeature("catalog", (r) => {
|
|
22
22
|
r.queryHandler("items:list", z.object({}), async () => ({ rows: [], nextCursor: null }), {
|
|
23
|
-
access: { openToAll:
|
|
23
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
24
24
|
outputSchema: pagedSchema,
|
|
25
25
|
});
|
|
26
26
|
r.screen({
|
|
@@ -39,7 +39,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
39
39
|
test("projectionList column present in the row shape does not throw", () => {
|
|
40
40
|
const feature = defineFeature("catalog", (r) => {
|
|
41
41
|
r.queryHandler("items:list", z.object({}), async () => ({ rows: [], nextCursor: null }), {
|
|
42
|
-
access: { openToAll:
|
|
42
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
43
43
|
outputSchema: pagedSchema,
|
|
44
44
|
});
|
|
45
45
|
r.screen({
|
|
@@ -56,7 +56,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
56
56
|
test("projectionList column with a label is exempt as a virtual/computed column", () => {
|
|
57
57
|
const feature = defineFeature("catalog", (r) => {
|
|
58
58
|
r.queryHandler("items:list", z.object({}), async () => ({ rows: [], nextCursor: null }), {
|
|
59
|
-
access: { openToAll:
|
|
59
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
60
60
|
outputSchema: pagedSchema,
|
|
61
61
|
});
|
|
62
62
|
r.screen({
|
|
@@ -78,7 +78,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
78
78
|
test("projectionList without a declared outputSchema skips the column check entirely", () => {
|
|
79
79
|
const feature = defineFeature("catalog", (r) => {
|
|
80
80
|
r.queryHandler("items:list", z.object({}), async () => ({ rows: [], nextCursor: null }), {
|
|
81
|
-
access: { openToAll:
|
|
81
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
82
82
|
});
|
|
83
83
|
r.screen({
|
|
84
84
|
id: "items",
|
|
@@ -94,7 +94,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
94
94
|
test("projectionList outputSchema that isn't a ZodObject (e.g. a union) skips the column check", () => {
|
|
95
95
|
const feature = defineFeature("catalog", (r) => {
|
|
96
96
|
r.queryHandler("items:list", z.object({}), async () => ({ rows: [], nextCursor: null }), {
|
|
97
|
-
access: { openToAll:
|
|
97
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
98
98
|
outputSchema: z.union([pagedSchema, z.null()]),
|
|
99
99
|
});
|
|
100
100
|
r.screen({
|
|
@@ -111,11 +111,11 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
111
111
|
test("relatedList column not in the query's row shape throws", () => {
|
|
112
112
|
const feature = defineFeature("app", (r) => {
|
|
113
113
|
r.queryHandler("rent:detail", z.object({}), async () => ({ description: "x" }), {
|
|
114
|
-
access: { openToAll:
|
|
114
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
115
115
|
outputSchema: z.object({ description: z.string() }),
|
|
116
116
|
});
|
|
117
117
|
r.queryHandler("rent:payments", z.object({}), async () => ({ rows: [], nextCursor: null }), {
|
|
118
|
-
access: { openToAll:
|
|
118
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
119
119
|
outputSchema: z.object({
|
|
120
120
|
rows: z.array(z.object({ amount: z.number() })),
|
|
121
121
|
nextCursor: z.string().nullable(),
|
|
@@ -142,10 +142,153 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
142
142
|
);
|
|
143
143
|
});
|
|
144
144
|
|
|
145
|
+
test("relatedList toolbarAction visible.field not in the projectionDetail's own outputSchema throws", () => {
|
|
146
|
+
const feature = defineFeature("app", (r) => {
|
|
147
|
+
r.queryHandler("lease:detail", z.object({}), async () => ({ id: "1", status: "active" }), {
|
|
148
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
149
|
+
outputSchema: z.object({ id: z.string(), status: z.string() }),
|
|
150
|
+
});
|
|
151
|
+
r.queryHandler(
|
|
152
|
+
"lease:positions",
|
|
153
|
+
z.object({}),
|
|
154
|
+
async () => ({ rows: [], nextCursor: null }),
|
|
155
|
+
{
|
|
156
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
157
|
+
outputSchema: z.object({
|
|
158
|
+
rows: z.array(z.object({ id: z.string() })),
|
|
159
|
+
nextCursor: z.string().nullable(),
|
|
160
|
+
}),
|
|
161
|
+
},
|
|
162
|
+
);
|
|
163
|
+
r.screen({
|
|
164
|
+
id: "lease-detail",
|
|
165
|
+
type: "projectionDetail",
|
|
166
|
+
query: "app:query:lease:detail",
|
|
167
|
+
layout: {
|
|
168
|
+
sections: [
|
|
169
|
+
{
|
|
170
|
+
kind: "relatedList",
|
|
171
|
+
title: "Positions",
|
|
172
|
+
query: "app:query:lease:positions",
|
|
173
|
+
columns: ["id"],
|
|
174
|
+
toolbarActions: [
|
|
175
|
+
{
|
|
176
|
+
kind: "navigate",
|
|
177
|
+
id: "create",
|
|
178
|
+
label: "Add position",
|
|
179
|
+
screen: "position-create",
|
|
180
|
+
visible: { field: "ghost-status", eq: "active" },
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
expect(() => validateBoot([feature])).toThrow(
|
|
189
|
+
/toolbarAction "create" visible\.field references unknown field "ghost-status"/,
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test("relatedList toolbarAction navigate params source field not in the projectionDetail's own outputSchema throws", () => {
|
|
194
|
+
const feature = defineFeature("app", (r) => {
|
|
195
|
+
r.queryHandler("lease:detail", z.object({}), async () => ({ id: "1" }), {
|
|
196
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
197
|
+
outputSchema: z.object({ id: z.string() }),
|
|
198
|
+
});
|
|
199
|
+
r.queryHandler(
|
|
200
|
+
"lease:positions",
|
|
201
|
+
z.object({}),
|
|
202
|
+
async () => ({ rows: [], nextCursor: null }),
|
|
203
|
+
{
|
|
204
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
205
|
+
outputSchema: z.object({
|
|
206
|
+
rows: z.array(z.object({ id: z.string() })),
|
|
207
|
+
nextCursor: z.string().nullable(),
|
|
208
|
+
}),
|
|
209
|
+
},
|
|
210
|
+
);
|
|
211
|
+
r.screen({
|
|
212
|
+
id: "lease-detail",
|
|
213
|
+
type: "projectionDetail",
|
|
214
|
+
query: "app:query:lease:detail",
|
|
215
|
+
layout: {
|
|
216
|
+
sections: [
|
|
217
|
+
{
|
|
218
|
+
kind: "relatedList",
|
|
219
|
+
title: "Positions",
|
|
220
|
+
query: "app:query:lease:positions",
|
|
221
|
+
columns: ["id"],
|
|
222
|
+
toolbarActions: [
|
|
223
|
+
{
|
|
224
|
+
kind: "navigate",
|
|
225
|
+
id: "create",
|
|
226
|
+
label: "Add position",
|
|
227
|
+
screen: "position-create",
|
|
228
|
+
params: { map: { leaseId: "ghost-id" } },
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
expect(() => validateBoot([feature])).toThrow(
|
|
237
|
+
/toolbarAction "create" params references unknown field "ghost-id"/,
|
|
238
|
+
);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
test("relatedList toolbarAction visible/params present in the projectionDetail's own outputSchema does not throw", () => {
|
|
242
|
+
const feature = defineFeature("app", (r) => {
|
|
243
|
+
r.queryHandler("lease:detail", z.object({}), async () => ({ id: "1", status: "active" }), {
|
|
244
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
245
|
+
outputSchema: z.object({ id: z.string(), status: z.string() }),
|
|
246
|
+
});
|
|
247
|
+
r.queryHandler(
|
|
248
|
+
"lease:positions",
|
|
249
|
+
z.object({}),
|
|
250
|
+
async () => ({ rows: [], nextCursor: null }),
|
|
251
|
+
{
|
|
252
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
253
|
+
outputSchema: z.object({
|
|
254
|
+
rows: z.array(z.object({ id: z.string() })),
|
|
255
|
+
nextCursor: z.string().nullable(),
|
|
256
|
+
}),
|
|
257
|
+
},
|
|
258
|
+
);
|
|
259
|
+
r.screen({
|
|
260
|
+
id: "lease-detail",
|
|
261
|
+
type: "projectionDetail",
|
|
262
|
+
query: "app:query:lease:detail",
|
|
263
|
+
layout: {
|
|
264
|
+
sections: [
|
|
265
|
+
{
|
|
266
|
+
kind: "relatedList",
|
|
267
|
+
title: "Positions",
|
|
268
|
+
query: "app:query:lease:positions",
|
|
269
|
+
columns: ["id"],
|
|
270
|
+
toolbarActions: [
|
|
271
|
+
{
|
|
272
|
+
kind: "navigate",
|
|
273
|
+
id: "create",
|
|
274
|
+
label: "Add position",
|
|
275
|
+
screen: "position-create",
|
|
276
|
+
visible: { field: "status", eq: "active" },
|
|
277
|
+
params: { map: { leaseId: "id" } },
|
|
278
|
+
},
|
|
279
|
+
],
|
|
280
|
+
},
|
|
281
|
+
],
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
expect(() => validateBoot([feature])).not.toThrow();
|
|
286
|
+
});
|
|
287
|
+
|
|
145
288
|
test("projectionDetail header.title referencing an unknown field throws", () => {
|
|
146
289
|
const feature = defineFeature("app", (r) => {
|
|
147
290
|
r.queryHandler("tenant:detail", z.object({}), async () => ({ id: "1", name: "x" }), {
|
|
148
|
-
access: { openToAll:
|
|
291
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
149
292
|
outputSchema: z.object({ id: z.string(), name: z.string() }),
|
|
150
293
|
});
|
|
151
294
|
r.screen({
|
|
@@ -164,7 +307,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
164
307
|
test("projectionDetail header.status referencing an unknown field throws", () => {
|
|
165
308
|
const feature = defineFeature("app", (r) => {
|
|
166
309
|
r.queryHandler("tenant:detail", z.object({}), async () => ({ id: "1", name: "x" }), {
|
|
167
|
-
access: { openToAll:
|
|
310
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
168
311
|
outputSchema: z.object({ id: z.string(), name: z.string() }),
|
|
169
312
|
});
|
|
170
313
|
r.screen({
|
|
@@ -181,7 +324,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
181
324
|
test("projectionDetail metrics referencing an unknown field throws", () => {
|
|
182
325
|
const feature = defineFeature("app", (r) => {
|
|
183
326
|
r.queryHandler("tenant:detail", z.object({}), async () => ({ id: "1", balance: 0 }), {
|
|
184
|
-
access: { openToAll:
|
|
327
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
185
328
|
outputSchema: z.object({ id: z.string(), balance: z.number() }),
|
|
186
329
|
});
|
|
187
330
|
r.screen({
|
|
@@ -214,7 +357,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
214
357
|
z.object({}),
|
|
215
358
|
async () => ({ id: "1", name: "x", balance: 0 }),
|
|
216
359
|
{
|
|
217
|
-
access: { openToAll:
|
|
360
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
218
361
|
outputSchema: z.object({
|
|
219
362
|
id: z.string(),
|
|
220
363
|
name: z.string(),
|
|
@@ -241,7 +384,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
241
384
|
test("dashboard stat panel valueField referencing an unknown field throws", () => {
|
|
242
385
|
const feature = defineFeature("demo", (r) => {
|
|
243
386
|
r.queryHandler("open-count", z.object({}), async () => ({ value: "0" }), {
|
|
244
|
-
access: { openToAll:
|
|
387
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
245
388
|
outputSchema: z.object({ value: z.string() }),
|
|
246
389
|
});
|
|
247
390
|
r.screen({
|
|
@@ -269,7 +412,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
269
412
|
test("dashboard stat-group child deltaField referencing an unknown field throws", () => {
|
|
270
413
|
const feature = defineFeature("demo", (r) => {
|
|
271
414
|
r.queryHandler("net-worth", z.object({}), async () => ({ value: "0" }), {
|
|
272
|
-
access: { openToAll:
|
|
415
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
273
416
|
outputSchema: z.object({ value: z.string() }),
|
|
274
417
|
});
|
|
275
418
|
r.screen({
|
|
@@ -308,7 +451,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
308
451
|
test("dashboard list panel column not in the query's row shape throws", () => {
|
|
309
452
|
const feature = defineFeature("demo", (r) => {
|
|
310
453
|
r.queryHandler("next-events", z.object({}), async () => ({ rows: [], nextCursor: null }), {
|
|
311
|
-
access: { openToAll:
|
|
454
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
312
455
|
outputSchema: z.object({
|
|
313
456
|
rows: z.array(z.object({ title: z.string() })),
|
|
314
457
|
nextCursor: z.string().nullable(),
|
|
@@ -342,7 +485,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
342
485
|
defineQueryHandler({
|
|
343
486
|
name: "items:detail",
|
|
344
487
|
schema: z.object({ id: z.string() }),
|
|
345
|
-
access: { openToAll:
|
|
488
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
346
489
|
outputSchema: z.object({ id: z.string(), name: z.string() }),
|
|
347
490
|
handler: async () => ({ id: "1", name: "x" }),
|
|
348
491
|
}),
|
|
@@ -366,7 +509,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
366
509
|
definePagedQueryHandler({
|
|
367
510
|
name: "items:list",
|
|
368
511
|
schema: z.object({}),
|
|
369
|
-
access: { openToAll:
|
|
512
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
370
513
|
outputSchema: pagedSchema,
|
|
371
514
|
handler: async () => ({ rows: [], nextCursor: null }),
|
|
372
515
|
}),
|
|
@@ -390,7 +533,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
390
533
|
definePagedQueryHandler({
|
|
391
534
|
name: "items:list",
|
|
392
535
|
schema: z.object({}),
|
|
393
|
-
access: { openToAll:
|
|
536
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
394
537
|
// Row schema passed directly instead of wrapping it in
|
|
395
538
|
// { rows: [...], nextCursor } — the mistake fw#2493's follow-up
|
|
396
539
|
// check catches instead of silently skipping every column check.
|
|
@@ -417,7 +560,7 @@ describe("validateBoot — query output schema column refs (fw#2493)", () => {
|
|
|
417
560
|
definePagedQueryHandler({
|
|
418
561
|
name: "items:list",
|
|
419
562
|
schema: z.object({}),
|
|
420
|
-
access: { openToAll:
|
|
563
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
421
564
|
outputSchema: pagedSchema,
|
|
422
565
|
handler: async () => ({ rows: [], nextCursor: null }),
|
|
423
566
|
}),
|
|
@@ -36,7 +36,7 @@ describe("validateBoot — query QN refs (fw#2178)", () => {
|
|
|
36
36
|
test("projectionDetail relatedList section with a dead query QN throws (b)", () => {
|
|
37
37
|
const feature = defineFeature("app", (r) => {
|
|
38
38
|
r.queryHandler("rent:detail", z.object({}), async () => ({ description: "x" }), {
|
|
39
|
-
access: { openToAll:
|
|
39
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
40
40
|
});
|
|
41
41
|
r.screen({
|
|
42
42
|
id: "rent-detail",
|
|
@@ -96,7 +96,7 @@ describe("validateBoot — query QN refs (fw#2178)", () => {
|
|
|
96
96
|
test("dashboard filter optionsQuery with a dead query QN throws", () => {
|
|
97
97
|
const feature = defineFeature("demo", (r) => {
|
|
98
98
|
r.queryHandler("open-count", z.object({}), async () => ({ value: "0" }), {
|
|
99
|
-
access: { openToAll:
|
|
99
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
100
100
|
});
|
|
101
101
|
r.screen({
|
|
102
102
|
id: "overview",
|
|
@@ -132,7 +132,7 @@ describe("validateBoot — query QN refs (fw#2178)", () => {
|
|
|
132
132
|
test("a screen referencing a query registered by a different mounted feature does not throw (d)", () => {
|
|
133
133
|
const provider = defineFeature("catalog", (r) => {
|
|
134
134
|
r.queryHandler("items:list", z.object({}), async () => ({ rows: [], nextCursor: null }), {
|
|
135
|
-
access: { openToAll:
|
|
135
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
136
136
|
});
|
|
137
137
|
});
|
|
138
138
|
const consumer = defineFeature("storefront", (r) => {
|
|
@@ -44,7 +44,7 @@ describe("S0 Integration — full surface stack", () => {
|
|
|
44
44
|
name: "compliance:query:for-tenant",
|
|
45
45
|
schema: z.object({}),
|
|
46
46
|
handler: async () => ({ profile: "eu-dsgvo" }) as never,
|
|
47
|
-
access: { openToAll:
|
|
47
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
48
48
|
});
|
|
49
49
|
});
|
|
50
50
|
|
|
@@ -101,7 +101,7 @@ describe("S0 Integration — full surface stack", () => {
|
|
|
101
101
|
name: "user:list",
|
|
102
102
|
schema: z.object({}),
|
|
103
103
|
handler: async () => ({ rows: [], nextCursor: null }) as never,
|
|
104
|
-
access: { openToAll:
|
|
104
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
105
105
|
});
|
|
106
106
|
|
|
107
107
|
r.useExtension(EXT_USER_DATA, "user", {});
|