@cosmicdrift/kumiko-framework 0.258.0 → 0.259.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.
Files changed (121) hide show
  1. package/package.json +3 -3
  2. package/src/__tests__/anonymous-access.integration.test.ts +3 -3
  3. package/src/__tests__/derived-fields.integration.test.ts +1 -1
  4. package/src/__tests__/entity-list-limits.integration.test.ts +1 -1
  5. package/src/__tests__/error-contract.integration.test.ts +1 -1
  6. package/src/__tests__/ownership-where-write-path.integration.test.ts +1 -1
  7. package/src/__tests__/ownership.integration.test.ts +7 -3
  8. package/src/__tests__/schema-cli-rebuild.integration.test.ts +2 -2
  9. package/src/__tests__/transition-guard.integration.test.ts +3 -3
  10. package/src/api/__tests__/api.test.ts +21 -3
  11. package/src/api/__tests__/batch.integration.test.ts +3 -3
  12. package/src/api/__tests__/body-limit.test.ts +7 -1
  13. package/src/api/__tests__/dispatcher-live.integration.test.ts +1 -1
  14. package/src/api/__tests__/http-route-rate-limit.integration.test.ts +7 -1
  15. package/src/api/__tests__/metrics-endpoint.test.ts +7 -1
  16. package/src/api/__tests__/nested-write.integration.test.ts +3 -3
  17. package/src/api/__tests__/server-boot-guards.test.ts +11 -4
  18. package/src/bun-db/__tests__/write-brand.test.ts +4 -1
  19. package/src/changes.json +6 -0
  20. package/src/db/__tests__/apply-entity-event-tenant.integration.test.ts +1 -1
  21. package/src/db/__tests__/assert-exists-in.integration.test.ts +1 -1
  22. package/src/db/__tests__/assert-no-unreachable-live-rows.integration.test.ts +2 -2
  23. package/src/db/__tests__/collect-table-metas.test.ts +9 -5
  24. package/src/db/__tests__/compound-types.test.ts +1 -1
  25. package/src/db/__tests__/config-seed.integration.test.ts +3 -3
  26. package/src/db/__tests__/eagerload.integration.test.ts +7 -7
  27. package/src/db/__tests__/entity-table-from-registry.test.ts +8 -2
  28. package/src/db/__tests__/entity-table-meta-source.test.ts +7 -3
  29. package/src/db/__tests__/entity-table-types.test.ts +4 -4
  30. package/src/db/__tests__/event-store-executor-list.integration.test.ts +9 -2
  31. package/src/db/__tests__/event-store-executor-reference-search.integration.test.ts +4 -4
  32. package/src/db/__tests__/event-store-executor-reference-sort.integration.test.ts +3 -3
  33. package/src/db/__tests__/event-store-executor-write-verbs.integration.test.ts +4 -4
  34. package/src/db/__tests__/event-store-executor.integration.test.ts +11 -6
  35. package/src/db/__tests__/event-store-system-stream.integration.test.ts +2 -2
  36. package/src/db/__tests__/implicit-projection-equivalence.integration.test.ts +6 -4
  37. package/src/db/__tests__/located-timestamp.test.ts +1 -1
  38. package/src/db/__tests__/money.test.ts +1 -1
  39. package/src/db/__tests__/multi-row-insert.integration.test.ts +3 -3
  40. package/src/db/__tests__/schema-migration.integration.test.ts +30 -14
  41. package/src/db/__tests__/source-shadow-create.integration.test.ts +1 -1
  42. package/src/db/__tests__/table-builder-indexes.test.ts +14 -12
  43. package/src/db/__tests__/table-builder-required.test.ts +2 -2
  44. package/src/db/__tests__/tenant-db-where-merge.integration.test.ts +1 -1
  45. package/src/db/__tests__/tenant-db-where-merge.test.ts +5 -2
  46. package/src/db/__tests__/tenant-db.integration.test.ts +2 -2
  47. package/src/db/__tests__/unique-violation-mapping.integration.test.ts +2 -2
  48. package/src/engine/__tests__/boot-validator-action-wiring.test.ts +50 -8
  49. package/src/engine/__tests__/boot-validator-dashboard.test.ts +138 -1
  50. package/src/engine/__tests__/boot-validator-detail-for.test.ts +28 -4
  51. package/src/engine/__tests__/boot-validator-entity-list.test.ts +20 -4
  52. package/src/engine/__tests__/boot-validator-i18n-keys.test.ts +9 -3
  53. package/src/engine/__tests__/boot-validator.test.ts +488 -91
  54. package/src/engine/__tests__/define-feature-entity-mapping.test.ts +2 -2
  55. package/src/engine/__tests__/engine.test.ts +128 -37
  56. package/src/engine/__tests__/entity-handlers.test.ts +3 -3
  57. package/src/engine/__tests__/entity-presave-wiring.integration.test.ts +4 -4
  58. package/src/engine/__tests__/entity-restore-tenant-isolation.integration.test.ts +1 -1
  59. package/src/engine/__tests__/entity-write-crosstenant.integration.test.ts +1 -1
  60. package/src/engine/__tests__/extend-entity-projection.test.ts +1 -1
  61. package/src/engine/__tests__/extends-registrar.test.ts +13 -3
  62. package/src/engine/__tests__/factories-long-text.test.ts +10 -6
  63. package/src/engine/__tests__/feature-crud-shorthand.test.ts +1 -1
  64. package/src/engine/__tests__/feature-crud-verb-access.integration.test.ts +1 -1
  65. package/src/engine/__tests__/multiselect-filter.integration.test.ts +1 -1
  66. package/src/engine/__tests__/nav.test.ts +1 -1
  67. package/src/engine/__tests__/pipeline-handler.integration.test.ts +1 -1
  68. package/src/engine/__tests__/pipeline-observability.integration.test.ts +1 -1
  69. package/src/engine/__tests__/pipeline-performance.integration.test.ts +1 -1
  70. package/src/engine/__tests__/projection-detail-actions.test.ts +6 -1
  71. package/src/engine/__tests__/projection-detail-singleton.test.ts +6 -1
  72. package/src/engine/__tests__/projection-detail-tabs.test.ts +6 -1
  73. package/src/engine/__tests__/projection-list-filter.integration.test.ts +7 -2
  74. package/src/engine/__tests__/projection.test.ts +1 -1
  75. package/src/engine/__tests__/registry.test.ts +13 -3
  76. package/src/engine/__tests__/schema-builder.test.ts +39 -11
  77. package/src/engine/__tests__/screen.test.ts +21 -15
  78. package/src/engine/__tests__/search-payload-extension.test.ts +15 -3
  79. package/src/engine/__tests__/store-table.test.ts +6 -3
  80. package/src/engine/__tests__/validate-projection-allowlist.test.ts +12 -4
  81. package/src/engine/__tests__/validation-hooks.test.ts +7 -1
  82. package/src/engine/boot-validator/__tests__/ownership.test.ts +2 -2
  83. package/src/engine/boot-validator/query-refs.ts +11 -0
  84. package/src/engine/boot-validator/screens.ts +45 -2
  85. package/src/engine/build-config-feature-schema.ts +2 -2
  86. package/src/engine/index.ts +2 -0
  87. package/src/engine/types/index.ts +2 -0
  88. package/src/es-ops/__tests__/runner.integration.test.ts +1 -1
  89. package/src/event-store/__tests__/upcaster.integration.test.ts +1 -1
  90. package/src/files/__tests__/file-field-pipeline.integration.test.ts +1 -1
  91. package/src/files/__tests__/files.integration.test.ts +1 -1
  92. package/src/files/file-ref-entity.ts +9 -9
  93. package/src/i18n/__tests__/i18n.test.ts +7 -1
  94. package/src/migrations/__tests__/kumiko-drift.integration.test.ts +3 -1
  95. package/src/migrations/__tests__/pending-rebuilds.integration.test.ts +2 -2
  96. package/src/pipeline/__tests__/archive-stream.integration.test.ts +1 -1
  97. package/src/pipeline/__tests__/cascade-handler.integration.test.ts +23 -8
  98. package/src/pipeline/__tests__/cascade-handler.test.ts +18 -3
  99. package/src/pipeline/__tests__/causation-chain.integration.test.ts +1 -1
  100. package/src/pipeline/__tests__/ctx-bridge.integration.test.ts +5 -3
  101. package/src/pipeline/__tests__/dispatcher.test.ts +42 -6
  102. package/src/pipeline/__tests__/domain-events-projections.integration.test.ts +2 -2
  103. package/src/pipeline/__tests__/fetch-for-writing.integration.test.ts +1 -1
  104. package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +42 -6
  105. package/src/pipeline/__tests__/load-aggregate-query.integration.test.ts +2 -2
  106. package/src/pipeline/__tests__/msp-multi-hop.integration.test.ts +1 -1
  107. package/src/pipeline/__tests__/msp-rebuild.integration.test.ts +6 -2
  108. package/src/pipeline/__tests__/multi-stream-projection.integration.test.ts +6 -2
  109. package/src/pipeline/__tests__/perf-rebuild.integration.test.ts +1 -1
  110. package/src/pipeline/__tests__/post-query-hook.integration.test.ts +3 -3
  111. package/src/pipeline/__tests__/projection-rebuild.integration.test.ts +3 -3
  112. package/src/pipeline/__tests__/query-projection.integration.test.ts +1 -1
  113. package/src/pipeline/__tests__/rebuild-poison-quarantine.integration.test.ts +2 -2
  114. package/src/pipeline/__tests__/search-consumer-named-events.integration.test.ts +13 -2
  115. package/src/pipeline/__tests__/try-append-event.integration.test.ts +1 -1
  116. package/src/search/__tests__/reindex-entity.integration.test.ts +6 -1
  117. package/src/search/__tests__/search-pii-derived-index.integration.test.ts +7 -1
  118. package/src/stack/__tests__/ownership-boot-guard.integration.test.ts +1 -1
  119. package/src/testing/__tests__/e2e-generator.test.ts +15 -5
  120. package/src/testing/shared-entities.ts +4 -2
  121. package/src/ui-types/index.ts +2 -0
@@ -23,7 +23,7 @@ import { createTenantDb, type TenantDb } from "../tenant-db";
23
23
  const customerEntity = createEntity({
24
24
  table: "read_ref_search_customers",
25
25
  fields: {
26
- name: createTextField({ required: true }),
26
+ name: createTextField({ required: true, personal: false, reason: "test_fixture" }),
27
27
  },
28
28
  });
29
29
  const customerTable = buildEntityTable("refSearchCustomer", customerEntity);
@@ -31,7 +31,7 @@ const customerTable = buildEntityTable("refSearchCustomer", customerEntity);
31
31
  const orderEntity = createEntity({
32
32
  table: "read_ref_search_orders",
33
33
  fields: {
34
- note: createTextField({ searchable: true }),
34
+ note: createTextField({ searchable: true, personal: false, reason: "test_fixture" }),
35
35
  customerId: {
36
36
  type: "reference",
37
37
  entity: "refSearchCustomer",
@@ -48,7 +48,7 @@ const orderTable = buildEntityTable("refSearchOrder", orderEntity);
48
48
  const restrictedOrderEntity = createEntity({
49
49
  table: "read_ref_search_restricted_orders",
50
50
  fields: {
51
- note: createTextField({ searchable: true }),
51
+ note: createTextField({ searchable: true, personal: false, reason: "test_fixture" }),
52
52
  customerId: {
53
53
  type: "reference",
54
54
  entity: "refSearchCustomer",
@@ -66,7 +66,7 @@ const restrictedOrderTable = buildEntityTable("refSearchRestrictedOrder", restri
66
66
  // (LIST_ROW_META_REFERENCES) is what's under test, not tenant's full schema.
67
67
  const tenantMetaEntity = createEntity({
68
68
  table: "read_tenants",
69
- fields: { name: createTextField({ required: true }) },
69
+ fields: { name: createTextField({ required: true, personal: false, reason: "test_fixture" }) },
70
70
  });
71
71
  const tenantMetaTable = buildEntityTable("tenant", tenantMetaEntity);
72
72
 
@@ -19,14 +19,14 @@ import { createTenantDb, type TenantDb } from "../tenant-db";
19
19
 
20
20
  const customerEntity = createEntity({
21
21
  table: "read_ref_sort_customers",
22
- fields: { name: createTextField({ required: true }) },
22
+ fields: { name: createTextField({ required: true, personal: false, reason: "test_fixture" }) },
23
23
  });
24
24
  const customerTable = buildEntityTable("refSortCustomer", customerEntity);
25
25
 
26
26
  const orderEntity = createEntity({
27
27
  table: "read_ref_sort_orders",
28
28
  fields: {
29
- note: createTextField(),
29
+ note: createTextField({ personal: false, reason: "test_fixture" }),
30
30
  customerId: {
31
31
  type: "reference",
32
32
  entity: "refSortCustomer",
@@ -43,7 +43,7 @@ const orderTable = buildEntityTable("refSortOrder", orderEntity);
43
43
  const restrictedOrderEntity = createEntity({
44
44
  table: "read_ref_sort_restricted_orders",
45
45
  fields: {
46
- note: createTextField(),
46
+ note: createTextField({ personal: false, reason: "test_fixture" }),
47
47
  customerId: {
48
48
  type: "reference",
49
49
  entity: "refSortCustomer",
@@ -44,7 +44,7 @@ afterAll(async () => {
44
44
  const restrictedEntity = createEntity({
45
45
  table: "read_es_write_restricted",
46
46
  fields: {
47
- email: createTextField({ required: true }),
47
+ email: createTextField({ required: true, personal: false, reason: "test_fixture" }),
48
48
  },
49
49
  softDelete: true,
50
50
  access: { write: { Admin: "all" } },
@@ -189,7 +189,7 @@ describe("event-store-executor write-verbs — entity-level ownership_denied", (
189
189
  const hardDeleteEntity = createEntity({
190
190
  table: "read_es_write_hard",
191
191
  fields: {
192
- email: createTextField({ required: true }),
192
+ email: createTextField({ required: true, personal: false, reason: "test_fixture" }),
193
193
  },
194
194
  });
195
195
  const hardDeleteTable = buildEntityTable("esWriteHard", hardDeleteEntity);
@@ -340,7 +340,7 @@ describe("event-store-executor write-verbs — field-level ownership_denied", ()
340
340
  const versionEntity = createEntity({
341
341
  table: "read_es_write_version",
342
342
  fields: {
343
- email: createTextField({ required: true }),
343
+ email: createTextField({ required: true, personal: false, reason: "test_fixture" }),
344
344
  },
345
345
  });
346
346
  const versionTable = buildEntityTable("esWriteVersion", versionEntity);
@@ -394,7 +394,7 @@ describe("event-store-executor write-verbs — version_conflict edge cases", ()
394
394
  const raceEntity = createEntity({
395
395
  table: "read_es_write_race",
396
396
  fields: {
397
- email: createTextField({ required: true }),
397
+ email: createTextField({ required: true, personal: false, reason: "test_fixture" }),
398
398
  },
399
399
  softDelete: true,
400
400
  });
@@ -21,8 +21,13 @@ import { createTenantDb, type TenantDb } from "../tenant-db";
21
21
  const entity = createEntity({
22
22
  table: "read_es_exec_users",
23
23
  fields: {
24
- email: createTextField({ required: true, searchable: true }),
25
- firstName: createTextField(),
24
+ email: createTextField({
25
+ required: true,
26
+ searchable: true,
27
+ personal: false,
28
+ reason: "test_fixture",
29
+ }),
30
+ firstName: createTextField({ personal: false, reason: "test_fixture" }),
26
31
  isEnabled: createBooleanField({ default: true }),
27
32
  },
28
33
  softDelete: true,
@@ -133,7 +138,7 @@ const SENSITIVE_TEST_KEY = Buffer.from("s3nS!t1vE.kP9xQ2@wN!vL$hR5yT8eU0").toStr
133
138
  const sensitiveEntity = createEntity({
134
139
  table: "read_es_exec_sensitive",
135
140
  fields: {
136
- email: createTextField({ required: true }),
141
+ email: createTextField({ required: true, personal: false, reason: "test_fixture" }),
137
142
  passwordHash: createTextField({ sensitive: true, encrypted: true }),
138
143
  apiToken: createTextField({ sensitive: true, encrypted: true }),
139
144
  },
@@ -337,7 +342,7 @@ const ENCRYPTION_TEST_KEY = Buffer.from("a]bJm#kP9xQ2@wN!vL$hR5yT8eU0iO3f").toSt
337
342
  const encryptedEntity = createEntity({
338
343
  table: "read_es_exec_encrypted",
339
344
  fields: {
340
- email: createTextField({ required: true }),
345
+ email: createTextField({ required: true, personal: false, reason: "test_fixture" }),
341
346
  secretNote: createTextField({ encrypted: true }),
342
347
  },
343
348
  });
@@ -346,7 +351,7 @@ const encryptedTable = buildEntityTable("esExecEncrypted", encryptedEntity);
346
351
  const encryptedSoftDeleteEntity = createEntity({
347
352
  table: "read_es_exec_enc_soft",
348
353
  fields: {
349
- email: createTextField({ required: true }),
354
+ email: createTextField({ required: true, personal: false, reason: "test_fixture" }),
350
355
  secretNote: createTextField({ encrypted: true }),
351
356
  },
352
357
  softDelete: true,
@@ -699,7 +704,7 @@ const piiEntity = createEntity({
699
704
  find: "none",
700
705
  }),
701
706
  authorId: createTextField(),
702
- plain: createTextField(),
707
+ plain: createTextField({ personal: false, reason: "test_fixture" }),
703
708
  },
704
709
  });
705
710
  const piiTable = buildEntityTable("esExecPii", piiEntity);
@@ -22,11 +22,11 @@ import { createTenantDb } from "../tenant-db";
22
22
  const systemEntity = createEntity({
23
23
  table: "sstream_sys",
24
24
  systemStream: true,
25
- fields: { name: createTextField({ required: true }) },
25
+ fields: { name: createTextField({ required: true, personal: false, reason: "test_fixture" }) },
26
26
  });
27
27
  const tenantOwnedEntity = createEntity({
28
28
  table: "sstream_tn",
29
- fields: { name: createTextField({ required: true }) },
29
+ fields: { name: createTextField({ required: true, personal: false, reason: "test_fixture" }) },
30
30
  });
31
31
 
32
32
  const systemTable = buildEntityTable("sstreamSys", systemEntity);
@@ -31,8 +31,8 @@ import { createTenantDb, type TenantDb } from "../tenant-db";
31
31
  const userEntity = createEntity({
32
32
  table: "read_implicit_users",
33
33
  fields: {
34
- email: createTextField({ required: true }),
35
- firstName: createTextField(),
34
+ email: createTextField({ required: true, personal: false, reason: "test_fixture" }),
35
+ firstName: createTextField({ personal: false, reason: "test_fixture" }),
36
36
  isEnabled: createBooleanField({ default: true }),
37
37
  },
38
38
  softDelete: true,
@@ -204,7 +204,9 @@ describe("implicit-projection / Live==Rebuild equivalence", () => {
204
204
  test("ohne softDelete → keine restore-apply-key registriert", () => {
205
205
  const hardDeleteEntity = createEntity({
206
206
  table: "read_implicit_hard",
207
- fields: { name: createTextField({ required: true }) },
207
+ fields: {
208
+ name: createTextField({ required: true, personal: false, reason: "test_fixture" }),
209
+ },
208
210
  });
209
211
  const hardFeature = defineFeature("implicithard", (r) => {
210
212
  r.entity("widget", hardDeleteEntity);
@@ -249,7 +251,7 @@ const SENSITIVE_BIDX_KEY = decodeBlindIndexKey(SENSITIVE_BIDX_KEY_B64);
249
251
  const sensitiveEntity = createEntity({
250
252
  table: sensitiveTable,
251
253
  fields: {
252
- email: createTextField({ required: true }),
254
+ email: createTextField({ required: true, personal: false, reason: "test_fixture" }),
253
255
  apiKey: createTextField({ personal: "self", find: "exact" }),
254
256
  },
255
257
  });
@@ -8,7 +8,7 @@ import { flattenLocatedTimestamp, rehydrateLocatedTimestamp } from "../located-t
8
8
 
9
9
  const orderEntity: EntityDefinition = createEntity({
10
10
  fields: {
11
- clientName: createTextField(),
11
+ clientName: createTextField({ personal: false, reason: "test_fixture" }),
12
12
  pickup: createLocatedTimestampField(),
13
13
  delivery: createLocatedTimestampField(),
14
14
  },
@@ -12,7 +12,7 @@ import { flattenMoney, type MoneyRead, moneyPayloadToMinorUnits, rehydrateMoney
12
12
  const orderEntity: EntityDefinition = createEntity({
13
13
  defaultCurrency: "EUR",
14
14
  fields: {
15
- label: createTextField(),
15
+ label: createTextField({ personal: false, reason: "test_fixture" }),
16
16
  buyingPrice: createMoneyField(),
17
17
  sellingPrice: createMoneyField(),
18
18
  },
@@ -18,8 +18,8 @@ import { setupTestStack, type TestStack, unsafeCreateEntityTable } from "../../s
18
18
  const linkEntity = createEntity({
19
19
  table: "mri_links",
20
20
  fields: {
21
- leftId: createTextField({ required: true }),
22
- rightId: createTextField({ required: true }),
21
+ leftId: createTextField({ required: true, personal: false, reason: "test_fixture" }),
22
+ rightId: createTextField({ required: true, personal: false, reason: "test_fixture" }),
23
23
  },
24
24
  });
25
25
  const linkTable = buildEntityTable("link", linkEntity);
@@ -42,7 +42,7 @@ describe("instant() customType is forgiving with ISO strings", () => {
42
42
 
43
43
  const tsEntity = createEntity({
44
44
  table: "mri_ts",
45
- fields: { name: createTextField({ required: true }) },
45
+ fields: { name: createTextField({ required: true, personal: false, reason: "test_fixture" }) },
46
46
  });
47
47
  const tsTable = buildEntityTable("ts-row", tsEntity);
48
48
 
@@ -80,8 +80,8 @@ describe("schema migration workflows", () => {
80
80
  createEntity({
81
81
  table: "wf1_posts",
82
82
  fields: {
83
- title: createTextField({ required: true }),
84
- body: createTextField(),
83
+ title: createTextField({ required: true, personal: false, reason: "test_fixture" }),
84
+ body: createTextField({ personal: false, reason: "test_fixture" }),
85
85
  viewCount: createNumberField(),
86
86
  publishedAt: createDateField(),
87
87
  isDraft: createBooleanField({ default: true }),
@@ -121,7 +121,7 @@ describe("schema migration workflows", () => {
121
121
  "article",
122
122
  createEntity({
123
123
  table: "wf1b_articles",
124
- fields: { title: createTextField() },
124
+ fields: { title: createTextField({ personal: false, reason: "test_fixture" }) },
125
125
  }),
126
126
  );
127
127
  });
@@ -138,7 +138,7 @@ describe("schema migration workflows", () => {
138
138
  // Initial entity with just email
139
139
  const initialEntity = createEntity({
140
140
  table: "wf2_users",
141
- fields: { email: createTextField() },
141
+ fields: { email: createTextField({ personal: false, reason: "test_fixture" }) },
142
142
  });
143
143
  await unsafePushTables(testDb.db, { user: buildEntityTable("user", initialEntity) });
144
144
 
@@ -146,8 +146,8 @@ describe("schema migration workflows", () => {
146
146
  const updatedEntity = createEntity({
147
147
  table: "wf2_users",
148
148
  fields: {
149
- email: createTextField(),
150
- displayName: createTextField(), // NEW FIELD
149
+ email: createTextField({ personal: false, reason: "test_fixture" }),
150
+ displayName: createTextField({ personal: false, reason: "test_fixture" }), // NEW FIELD
151
151
  },
152
152
  });
153
153
 
@@ -168,7 +168,7 @@ describe("schema migration workflows", () => {
168
168
  // Initial entity with just name
169
169
  const initialEntity = createEntity({
170
170
  table: "wf3_projects",
171
- fields: { name: createTextField() },
171
+ fields: { name: createTextField({ personal: false, reason: "test_fixture" }) },
172
172
  });
173
173
  const initialTable = buildEntityTable("project", initialEntity);
174
174
  await unsafePushTables(testDb.db, { project: initialTable });
@@ -182,7 +182,10 @@ describe("schema migration workflows", () => {
182
182
  // Developer adds boolean field with default
183
183
  const updatedEntity = createEntity({
184
184
  table: "wf3_projects",
185
- fields: { name: createTextField(), isArchived: createBooleanField({ default: false }) },
185
+ fields: {
186
+ name: createTextField({ personal: false, reason: "test_fixture" }),
187
+ isArchived: createBooleanField({ default: false }),
188
+ },
186
189
  });
187
190
  const updatedTable = buildEntityTable("project", updatedEntity);
188
191
  await unsafePushTables(testDb.db, { project: updatedTable }, { project: initialTable });
@@ -202,7 +205,9 @@ describe("schema migration workflows", () => {
202
205
  // greift.
203
206
  const initialEntity = createEntity({
204
207
  table: "wf3b_users",
205
- fields: { email: createTextField({ required: true }) },
208
+ fields: {
209
+ email: createTextField({ required: true, personal: false, reason: "test_fixture" }),
210
+ },
206
211
  });
207
212
  const initialTable = buildEntityTable("user", initialEntity);
208
213
  await unsafePushTables(testDb.db, { user: initialTable });
@@ -215,8 +220,13 @@ describe("schema migration workflows", () => {
215
220
  const updatedEntity = createEntity({
216
221
  table: "wf3b_users",
217
222
  fields: {
218
- email: createTextField({ required: true }),
219
- roles: createTextField({ required: true, default: "[]" }),
223
+ email: createTextField({ required: true, personal: false, reason: "test_fixture" }),
224
+ roles: createTextField({
225
+ required: true,
226
+ default: "[]",
227
+ personal: false,
228
+ reason: "test_fixture",
229
+ }),
220
230
  },
221
231
  });
222
232
  const updatedTable = buildEntityTable("user", updatedEntity);
@@ -232,7 +242,7 @@ describe("schema migration workflows", () => {
232
242
  "task",
233
243
  createEntity({
234
244
  table: "wf4_tasks",
235
- fields: { title: createTextField() },
245
+ fields: { title: createTextField({ personal: false, reason: "test_fixture" }) },
236
246
  softDelete: true,
237
247
  }),
238
248
  );
@@ -253,7 +263,10 @@ describe("schema migration workflows", () => {
253
263
  const blogFeature = defineFeature("blog", (r) => {
254
264
  r.entity(
255
265
  "article",
256
- createEntity({ table: "wf5_articles", fields: { title: createTextField() } }),
266
+ createEntity({
267
+ table: "wf5_articles",
268
+ fields: { title: createTextField({ personal: false, reason: "test_fixture" }) },
269
+ }),
257
270
  );
258
271
  });
259
272
 
@@ -262,7 +275,10 @@ describe("schema migration workflows", () => {
262
275
  "product",
263
276
  createEntity({
264
277
  table: "wf5_products",
265
- fields: { name: createTextField(), price: createNumberField() },
278
+ fields: {
279
+ name: createTextField({ personal: false, reason: "test_fixture" }),
280
+ price: createNumberField(),
281
+ },
266
282
  }),
267
283
  );
268
284
  });
@@ -23,7 +23,7 @@ const sourceEntity = createEntity({
23
23
  table: "ssc_source",
24
24
  fields: {
25
25
  // `source` collides with the EntityTableMeta discriminator key.
26
- source: createTextField({ required: true }),
26
+ source: createTextField({ required: true, personal: false, reason: "test_fixture" }),
27
27
  },
28
28
  });
29
29
  const sourceTable = buildEntityTable("source-row", sourceEntity);
@@ -40,8 +40,8 @@ describe("buildEntityTable — entity.indexes", () => {
40
40
  test("composite unique-index landet als unique=true in Drizzle table-config", () => {
41
41
  const entity = createEntity({
42
42
  fields: {
43
- key: createTextField({ required: true }),
44
- userId: createTextField({}),
43
+ key: createTextField({ required: true, personal: false, reason: "test_fixture" }),
44
+ userId: createTextField({ personal: false, reason: "test_fixture" }),
45
45
  },
46
46
  indexes: [{ unique: true, columns: ["key", "tenantId", "userId"] }],
47
47
  });
@@ -62,8 +62,8 @@ describe("buildEntityTable — entity.indexes", () => {
62
62
  test("composite non-unique-index landet als unique=false in Drizzle table-config", () => {
63
63
  const entity = createEntity({
64
64
  fields: {
65
- startedAt: createTextField({}),
66
- endedAt: createTextField({}),
65
+ startedAt: createTextField({ personal: false, reason: "test_fixture" }),
66
+ endedAt: createTextField({ personal: false, reason: "test_fixture" }),
67
67
  },
68
68
  indexes: [{ columns: ["startedAt", "endedAt"] }],
69
69
  });
@@ -78,7 +78,9 @@ describe("buildEntityTable — entity.indexes", () => {
78
78
 
79
79
  test("custom name override wird respektiert", () => {
80
80
  const entity = createEntity({
81
- fields: { slug: createTextField({ required: true }) },
81
+ fields: {
82
+ slug: createTextField({ required: true, personal: false, reason: "test_fixture" }),
83
+ },
82
84
  indexes: [{ unique: true, columns: ["slug"], name: "my_custom_idx" }],
83
85
  });
84
86
  const tbl = buildEntityTable("page", entity);
@@ -91,7 +93,7 @@ describe("buildEntityTable — entity.indexes", () => {
91
93
  test("ohne indexes — keine zusätzlichen Indices, kein Error", () => {
92
94
  const entity = createEntity({
93
95
  fields: {
94
- title: createTextField({}),
96
+ title: createTextField({ personal: false, reason: "test_fixture" }),
95
97
  },
96
98
  });
97
99
  expect(() => buildEntityTable("widget", entity)).not.toThrow();
@@ -120,7 +122,7 @@ describe("validateBoot — entity.indexes", () => {
120
122
  test("Tippfehler im column-Namen wirft", () => {
121
123
  const feature = defineFeature("widgetFeature", (r) => {
122
124
  r.entity("widget", {
123
- fields: { title: createTextField({}) },
125
+ fields: { title: createTextField({ personal: false, reason: "test_fixture" }) },
124
126
  indexes: [{ columns: ["titel"] }], // typo
125
127
  });
126
128
  });
@@ -130,7 +132,7 @@ describe("validateBoot — entity.indexes", () => {
130
132
  test("leere column-Liste wirft", () => {
131
133
  const feature = defineFeature("widgetFeature", (r) => {
132
134
  r.entity("widget", {
133
- fields: { title: createTextField({}) },
135
+ fields: { title: createTextField({ personal: false, reason: "test_fixture" }) },
134
136
  indexes: [{ columns: [] as never }],
135
137
  });
136
138
  });
@@ -140,7 +142,7 @@ describe("validateBoot — entity.indexes", () => {
140
142
  test("single-column index nur auf tenantId ist redundant", () => {
141
143
  const feature = defineFeature("widgetFeature", (r) => {
142
144
  r.entity("widget", {
143
- fields: { title: createTextField({}) },
145
+ fields: { title: createTextField({ personal: false, reason: "test_fixture" }) },
144
146
  indexes: [{ columns: ["tenantId"] }],
145
147
  });
146
148
  });
@@ -155,7 +157,7 @@ describe("validateBoot — entity.indexes", () => {
155
157
  // sonst fliegt der Branch beim nächsten Revert/Refactor stumm raus.
156
158
  const feature = defineFeature("widgetFeature", (r) => {
157
159
  r.entity("widget", {
158
- fields: { title: createTextField({}) },
160
+ fields: { title: createTextField({ personal: false, reason: "test_fixture" }) },
159
161
  indexes: [{ unique: true, columns: ["tenantId"] }],
160
162
  });
161
163
  });
@@ -166,7 +168,7 @@ describe("validateBoot — entity.indexes", () => {
166
168
  const feature = defineFeature("widgetFeature", (r) => {
167
169
  r.entity("widget", {
168
170
  fields: {
169
- key: createTextField({ required: true }),
171
+ key: createTextField({ required: true, personal: false, reason: "test_fixture" }),
170
172
  archived: createBooleanField({}),
171
173
  },
172
174
  indexes: [{ unique: true, columns: ["key", "tenantId"] }],
@@ -178,7 +180,7 @@ describe("validateBoot — entity.indexes", () => {
178
180
  test("base columns (id, tenantId, version) sind erlaubt", () => {
179
181
  const feature = defineFeature("widgetFeature", (r) => {
180
182
  r.entity("widget", {
181
- fields: { key: createTextField({}) },
183
+ fields: { key: createTextField({ personal: false, reason: "test_fixture" }) },
182
184
  indexes: [{ columns: ["tenantId", "version"] }],
183
185
  });
184
186
  });
@@ -44,8 +44,8 @@ describe("buildEntityTable — required: true → NOT NULL", () => {
44
44
  test("text field — required true makes column NOT NULL", () => {
45
45
  const entity = createEntity({
46
46
  fields: {
47
- title: createTextField({ required: true }),
48
- subtitle: createTextField({}),
47
+ title: createTextField({ required: true, personal: false, reason: "test_fixture" }),
48
+ subtitle: createTextField({ personal: false, reason: "test_fixture" }),
49
49
  },
50
50
  });
51
51
  const tbl = buildEntityTable("widget", entity);
@@ -25,7 +25,7 @@ import { buildEntityTable } from "../table-builder";
25
25
 
26
26
  const noteEntity = createEntity({
27
27
  fields: {
28
- title: createTextField({ required: true }),
28
+ title: createTextField({ required: true, personal: false, reason: "test_fixture" }),
29
29
  },
30
30
  table: "where_merge_notes",
31
31
  });
@@ -14,7 +14,7 @@ import { createTenantDb } from "../tenant-db";
14
14
 
15
15
  const entity = createEntity({
16
16
  table: "merge_items",
17
- fields: { name: createTextField({ required: true }) },
17
+ fields: { name: createTextField({ required: true, personal: false, reason: "test_fixture" }) },
18
18
  });
19
19
  // Brand (#742) is compile-time-only; hold the handle at the unbranded TableColumns
20
20
  // view so the method-form scoping test still compiles (runtime shape is identical).
@@ -130,7 +130,10 @@ describe("tenant-db WHERE merge — narrowing within the enforced scope", () =>
130
130
  describe("tenant-db WHERE merge — unmanaged EntityTableMeta tables (deriveEntityTableMeta)", () => {
131
131
  const unmanagedEntity = createEntity({
132
132
  table: "merge_meta_items",
133
- fields: { tenantId: createTextField({ required: true }), name: createTextField() },
133
+ fields: {
134
+ tenantId: createTextField({ required: true, personal: false, reason: "test_fixture" }),
135
+ name: createTextField({ personal: false, reason: "test_fixture" }),
136
+ },
134
137
  });
135
138
  const unmanagedTable = deriveEntityTableMeta("merge-meta-item", unmanagedEntity);
136
139
 
@@ -19,8 +19,8 @@ import { createTenantDb } from "../tenant-db";
19
19
  const entity = createEntity({
20
20
  table: "tenant_db_items",
21
21
  fields: {
22
- name: createTextField({ required: true }),
23
- status: createTextField({ default: "draft" }),
22
+ name: createTextField({ required: true, personal: false, reason: "test_fixture" }),
23
+ status: createTextField({ default: "draft", personal: false, reason: "test_fixture" }),
24
24
  isActive: createBooleanField({ default: true }),
25
25
  },
26
26
  softDelete: true,
@@ -27,8 +27,8 @@ import { createTenantDb, type TenantDb } from "../tenant-db";
27
27
  const userEntity = createEntity({
28
28
  table: "read_unique_users",
29
29
  fields: {
30
- email: createTextField({ required: true }),
31
- displayName: createTextField({ required: true }),
30
+ email: createTextField({ required: true, personal: false, reason: "test_fixture" }),
31
+ displayName: createTextField({ required: true, personal: false, reason: "test_fixture" }),
32
32
  },
33
33
  // softDelete=true damit wir den restore-Pfad pinnen können (siehe
34
34
  // restore-Test unten — "kein 23505 möglich" claim).
@@ -7,7 +7,12 @@ import { createEntity, createTextField } from "../factories";
7
7
  describe("validateBoot — action wiring (no function values)", () => {
8
8
  test("rowAction writeHandler payload as function → Throw", () => {
9
9
  const feature = defineFeature("shop", (r) => {
10
- r.entity("product", createEntity({ fields: { name: createTextField() } }));
10
+ r.entity(
11
+ "product",
12
+ createEntity({
13
+ fields: { name: createTextField({ personal: false, reason: "test_fixture" }) },
14
+ }),
15
+ );
11
16
  r.screen({
12
17
  id: "product-list",
13
18
  type: "entityList",
@@ -33,7 +38,14 @@ describe("validateBoot — action wiring (no function values)", () => {
33
38
 
34
39
  test("rowAction writeHandler payload as declarative pick → kein Throw", () => {
35
40
  const feature = defineFeature("shop", (r) => {
36
- r.entity("product", createEntity({ fields: { name: createTextField({ sortable: true }) } }));
41
+ r.entity(
42
+ "product",
43
+ createEntity({
44
+ fields: {
45
+ name: createTextField({ sortable: true, personal: false, reason: "test_fixture" }),
46
+ },
47
+ }),
48
+ );
37
49
  r.screen({
38
50
  id: "product-list",
39
51
  type: "entityList",
@@ -65,7 +77,12 @@ describe("validateBoot — action wiring (no function values)", () => {
65
77
 
66
78
  test("rowAction navigate visible as function → Throw", () => {
67
79
  const feature = defineFeature("shop", (r) => {
68
- r.entity("product", createEntity({ fields: { name: createTextField() } }));
80
+ r.entity(
81
+ "product",
82
+ createEntity({
83
+ fields: { name: createTextField({ personal: false, reason: "test_fixture" }) },
84
+ }),
85
+ );
69
86
  r.screen({
70
87
  id: "product-list",
71
88
  type: "entityList",
@@ -88,7 +105,12 @@ describe("validateBoot — action wiring (no function values)", () => {
88
105
 
89
106
  test("toolbarAction writeHandler payload as function → Throw", () => {
90
107
  const feature = defineFeature("shop", (r) => {
91
- r.entity("product", createEntity({ fields: { name: createTextField() } }));
108
+ r.entity(
109
+ "product",
110
+ createEntity({
111
+ fields: { name: createTextField({ personal: false, reason: "test_fixture" }) },
112
+ }),
113
+ );
92
114
  r.screen({
93
115
  id: "product-list",
94
116
  type: "entityList",
@@ -136,7 +158,12 @@ describe("validateBoot — action wiring (no function values)", () => {
136
158
 
137
159
  test("entityList column renderer as function → Throw", () => {
138
160
  const feature = defineFeature("shop", (r) => {
139
- r.entity("product", createEntity({ fields: { name: createTextField() } }));
161
+ r.entity(
162
+ "product",
163
+ createEntity({
164
+ fields: { name: createTextField({ personal: false, reason: "test_fixture" }) },
165
+ }),
166
+ );
140
167
  r.screen({
141
168
  id: "product-list",
142
169
  type: "entityList",
@@ -152,7 +179,12 @@ describe("validateBoot — action wiring (no function values)", () => {
152
179
 
153
180
  test("entityEdit field visible as function → Throw", () => {
154
181
  const feature = defineFeature("shop", (r) => {
155
- r.entity("product", createEntity({ fields: { name: createTextField() } }));
182
+ r.entity(
183
+ "product",
184
+ createEntity({
185
+ fields: { name: createTextField({ personal: false, reason: "test_fixture" }) },
186
+ }),
187
+ );
156
188
  r.screen({
157
189
  id: "product-edit",
158
190
  type: "entityEdit",
@@ -173,7 +205,12 @@ describe("validateBoot — action wiring (no function values)", () => {
173
205
 
174
206
  test("entityEdit field renderer as function → Throw", () => {
175
207
  const feature = defineFeature("shop", (r) => {
176
- r.entity("product", createEntity({ fields: { name: createTextField() } }));
208
+ r.entity(
209
+ "product",
210
+ createEntity({
211
+ fields: { name: createTextField({ personal: false, reason: "test_fixture" }) },
212
+ }),
213
+ );
177
214
  r.screen({
178
215
  id: "product-edit",
179
216
  type: "entityEdit",
@@ -194,7 +231,12 @@ describe("validateBoot — action wiring (no function values)", () => {
194
231
 
195
232
  test("entityEdit field with declarative visible/readOnly/required → kein Throw", () => {
196
233
  const feature = defineFeature("shop", (r) => {
197
- r.entity("product", createEntity({ fields: { name: createTextField() } }));
234
+ r.entity(
235
+ "product",
236
+ createEntity({
237
+ fields: { name: createTextField({ personal: false, reason: "test_fixture" }) },
238
+ }),
239
+ );
198
240
  r.screen({
199
241
  id: "product-edit",
200
242
  type: "entityEdit",