@cosmicdrift/kumiko-framework 0.386.0 → 0.388.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 (468) hide show
  1. package/AGENTS.md +6 -1
  2. package/LICENSE +21 -57
  3. package/README.md +2 -2
  4. package/agents/examples/anonymous-access.md +1 -1
  5. package/agents/examples/apex-landing.md +204 -0
  6. package/agents/examples/api-worker-split.md +64 -0
  7. package/agents/examples/app-config.md +14 -0
  8. package/agents/examples/auth-mfa.md +115 -0
  9. package/agents/examples/env-composition.md +28 -1
  10. package/agents/examples/legal-pages.md +1 -1
  11. package/agents/examples/prod-boot-options.md +16 -0
  12. package/agents/examples/rate-limiting.md +48 -0
  13. package/agents/examples/record-detail-layout.md +692 -0
  14. package/agents/examples/seed-migration.md +212 -0
  15. package/agents/examples/wizard-form.md +941 -0
  16. package/agents/examples/writeform-section.md +548 -0
  17. package/agents/features.md +19 -2
  18. package/agents/widgets.md +40 -39
  19. package/dist/api/api-constants.js +2 -2
  20. package/dist/api/auth-middleware.js +7 -7
  21. package/dist/api/auth-rate-limiters.js +7 -3
  22. package/dist/api/auth-routes-mfa.js +1 -1
  23. package/dist/api/auth-routes-session.js +1 -1
  24. package/dist/api/auth-routes-shared.js +7 -3
  25. package/dist/api/auth-routes-signup.js +1 -1
  26. package/dist/api/client-error-route.js +8 -2
  27. package/dist/api/client-ip.js +3 -1
  28. package/dist/api/extra-route.js +1 -1
  29. package/dist/api/index.d.ts +3 -1
  30. package/dist/api/index.js +3 -1
  31. package/dist/api/pii-leak-guard.js +4 -2
  32. package/dist/api/readiness.js +5 -5
  33. package/dist/api/redis-sse-broker.js +8 -6
  34. package/dist/api/request-context.d.ts +1 -1
  35. package/dist/api/request-context.js +1 -1
  36. package/dist/api/routes.js +2 -2
  37. package/dist/api/server-boot-checks.d.ts +10 -0
  38. package/dist/api/server-boot-checks.js +157 -0
  39. package/dist/api/server-event-dispatcher.d.ts +26 -0
  40. package/dist/api/server-event-dispatcher.js +208 -0
  41. package/dist/api/server-extra-routes.d.ts +11 -0
  42. package/dist/api/server-extra-routes.js +203 -0
  43. package/dist/api/server-middleware.d.ts +20 -0
  44. package/dist/api/server-middleware.js +211 -0
  45. package/dist/api/server-routes.d.ts +19 -0
  46. package/dist/api/server-routes.js +293 -0
  47. package/dist/api/server-websocket-routes.d.ts +4 -0
  48. package/dist/api/server-websocket-routes.js +108 -0
  49. package/dist/api/server-wiring.d.ts +32 -0
  50. package/dist/api/server-wiring.js +236 -0
  51. package/dist/api/server.d.ts +10 -15
  52. package/dist/api/server.js +48 -1250
  53. package/dist/api/session-cookies.js +4 -4
  54. package/dist/api/sse-broker.js +1 -1
  55. package/dist/api/sse-route.d.ts +13 -13
  56. package/dist/api/sse-route.js +31 -27
  57. package/dist/auth/index.js +4 -4
  58. package/dist/auth/roles.d.ts +4 -4
  59. package/dist/auth/roles.js +24 -24
  60. package/dist/compliance/duration-spec.js +18 -20
  61. package/dist/compliance/index.js +2 -3
  62. package/dist/compliance/override-schema.d.ts +4 -4
  63. package/dist/compliance/override-schema.js +19 -22
  64. package/dist/compliance/profiles.d.ts +26 -29
  65. package/dist/compliance/profiles.js +62 -69
  66. package/dist/compliance/sub-processors.d.ts +28 -30
  67. package/dist/compliance/sub-processors.js +17 -21
  68. package/dist/consumer-cli.js +4 -4
  69. package/dist/crypto/blind-index.js +18 -17
  70. package/dist/crypto/ciphertext-pattern.js +1 -1
  71. package/dist/crypto/event-pii.js +3 -3
  72. package/dist/crypto/kek-source.d.ts +1 -1
  73. package/dist/crypto/kek-source.js +3 -2
  74. package/dist/crypto/kms-adapter.d.ts +1 -1
  75. package/dist/crypto/kms-adapter.js +4 -6
  76. package/dist/crypto/kms-wiring.d.ts +1 -2
  77. package/dist/crypto/kms-wiring.js +2 -2
  78. package/dist/crypto/owner-transition-rekey.d.ts +5 -1
  79. package/dist/crypto/owner-transition-rekey.js +1 -1
  80. package/dist/crypto/pg-kms-adapter.js +2 -6
  81. package/dist/crypto/pii-field-encryption.d.ts +5 -1
  82. package/dist/crypto/pii-field-encryption.js +7 -5
  83. package/dist/crypto/subject-resolver.d.ts +1 -1
  84. package/dist/crypto/subject-resolver.js +2 -2
  85. package/dist/db/aggregate-sql.d.ts +21 -0
  86. package/dist/db/aggregate-sql.js +155 -0
  87. package/dist/db/apply-entity-event.d.ts +6 -6
  88. package/dist/db/apply-entity-event.js +55 -55
  89. package/dist/db/blind-index-cleanup.js +7 -7
  90. package/dist/db/closed-connection.d.ts +9 -0
  91. package/dist/db/closed-connection.js +95 -0
  92. package/dist/db/collect-table-metas.js +10 -11
  93. package/dist/db/compound-types.d.ts +1 -1
  94. package/dist/db/compound-types.js +12 -12
  95. package/dist/db/cursor.js +3 -4
  96. package/dist/db/dialect.d.ts +2 -2
  97. package/dist/db/dialect.js +3 -3
  98. package/dist/db/distinct-on.d.ts +1 -1
  99. package/dist/db/driver-row-coercion.d.ts +2 -0
  100. package/dist/db/driver-row-coercion.js +186 -0
  101. package/dist/db/driver-value-preparation.d.ts +16 -0
  102. package/dist/db/driver-value-preparation.js +99 -0
  103. package/dist/db/eagerload.d.ts +3 -3
  104. package/dist/db/eagerload.js +21 -12
  105. package/dist/db/entity-field-encryption.d.ts +1 -0
  106. package/dist/db/entity-field-encryption.js +1 -1
  107. package/dist/db/entity-table-meta.d.ts +2 -2
  108. package/dist/db/entity-table-meta.js +105 -112
  109. package/dist/db/event-store-executor-context.d.ts +3 -2
  110. package/dist/db/event-store-executor-context.js +13 -13
  111. package/dist/db/event-store-executor-read-aggregate.d.ts +8 -0
  112. package/dist/db/event-store-executor-read-aggregate.js +112 -0
  113. package/dist/db/event-store-executor-read-filter.d.ts +31 -0
  114. package/dist/db/event-store-executor-read-filter.js +203 -0
  115. package/dist/db/event-store-executor-read-paging.d.ts +14 -0
  116. package/dist/db/event-store-executor-read-paging.js +99 -0
  117. package/dist/db/event-store-executor-read-rows.d.ts +6 -0
  118. package/dist/db/event-store-executor-read-rows.js +32 -0
  119. package/dist/db/event-store-executor-read-search.d.ts +28 -0
  120. package/dist/db/event-store-executor-read-search.js +221 -0
  121. package/dist/db/event-store-executor-read-sort.d.ts +41 -0
  122. package/dist/db/event-store-executor-read-sort.js +130 -0
  123. package/dist/db/event-store-executor-read-where.d.ts +24 -0
  124. package/dist/db/event-store-executor-read-where.js +81 -0
  125. package/dist/db/event-store-executor-read.d.ts +2 -9
  126. package/dist/db/event-store-executor-read.js +50 -704
  127. package/dist/db/event-store-executor-write-steps.d.ts +20 -0
  128. package/dist/db/event-store-executor-write-steps.js +100 -0
  129. package/dist/db/event-store-executor-write.js +401 -510
  130. package/dist/db/index.d.ts +6 -2
  131. package/dist/db/index.js +5 -1
  132. package/dist/db/list-aggregate-labels.d.ts +14 -0
  133. package/dist/db/list-aggregate-labels.js +26 -0
  134. package/dist/db/located-timestamp.d.ts +11 -11
  135. package/dist/db/located-timestamp.js +29 -30
  136. package/dist/db/migrate-generator.d.ts +1 -1
  137. package/dist/db/migrate-generator.js +97 -105
  138. package/dist/db/migrate-runner.js +29 -26
  139. package/dist/db/money.d.ts +6 -6
  140. package/dist/db/money.js +29 -27
  141. package/dist/db/queries/backfill-pii.js +5 -5
  142. package/dist/db/queries/ddl.js +1 -1
  143. package/dist/db/queries/es-ops.d.ts +1 -1
  144. package/dist/db/queries/es-ops.js +1 -1
  145. package/dist/db/queries/event-consumer.js +3 -3
  146. package/dist/db/queries/event-store.js +4 -2
  147. package/dist/db/queries/projection-rebuild.js +3 -3
  148. package/dist/db/queries/raw-sql.d.ts +2 -2
  149. package/dist/db/queries/raw-sql.js +2 -2
  150. package/dist/db/queries/shadow-swap.js +19 -19
  151. package/dist/db/query.d.ts +3 -16
  152. package/dist/db/query.js +8 -761
  153. package/dist/db/rebuild-marker.js +20 -21
  154. package/dist/db/reference-data.js +6 -1
  155. package/dist/db/replay-migration-sql.js +2 -2
  156. package/dist/db/schema-inspection.js +4 -5
  157. package/dist/db/table-builder.d.ts +1 -2
  158. package/dist/db/table-builder.js +137 -190
  159. package/dist/db/table-info.d.ts +10 -0
  160. package/dist/db/table-info.js +45 -0
  161. package/dist/db/temporal-value-guards.d.ts +6 -0
  162. package/dist/db/temporal-value-guards.js +15 -0
  163. package/dist/db/tenant-db-runner.d.ts +1 -0
  164. package/dist/db/tenant-db-runner.js +3 -0
  165. package/dist/db/tenant-db.d.ts +2 -2
  166. package/dist/db/tenant-db.js +48 -11
  167. package/dist/db/where-clause.d.ts +6 -0
  168. package/dist/db/where-clause.js +236 -0
  169. package/dist/derivatives/delete-stored-file.js +6 -2
  170. package/dist/derivatives/derivatives-context.js +1 -1
  171. package/dist/engine/boot-validator/access-roles.js +4 -3
  172. package/dist/engine/boot-validator/api-ext.js +14 -14
  173. package/dist/engine/boot-validator/boot-check.js +1 -1
  174. package/dist/engine/boot-validator/config-deps.js +7 -6
  175. package/dist/engine/boot-validator/detail-screens.js +4 -4
  176. package/dist/engine/boot-validator/entity-handler.d.ts +1 -0
  177. package/dist/engine/boot-validator/entity-handler.js +77 -61
  178. package/dist/engine/boot-validator/form-derivations.js +35 -1
  179. package/dist/engine/boot-validator/gdpr-storage.js +4 -4
  180. package/dist/engine/boot-validator/i18n-keys.js +6 -4
  181. package/dist/engine/boot-validator/index.d.ts +2 -2
  182. package/dist/engine/boot-validator/index.js +22 -20
  183. package/dist/engine/boot-validator/nav.js +5 -5
  184. package/dist/engine/boot-validator/ownership.js +12 -9
  185. package/dist/engine/boot-validator/parent-ref.js +1 -1
  186. package/dist/engine/boot-validator/pii-retention.js +258 -187
  187. package/dist/engine/boot-validator/projection-list-screens.js +7 -7
  188. package/dist/engine/boot-validator/query-refs.js +1 -1
  189. package/dist/engine/boot-validator/screens-actions.d.ts +1 -0
  190. package/dist/engine/boot-validator/screens-actions.js +23 -17
  191. package/dist/engine/boot-validator/screens-dashboard.js +2 -5
  192. package/dist/engine/boot-validator/screens-forms.js +12 -17
  193. package/dist/engine/boot-validator/screens-kind-config-edit.d.ts +3 -0
  194. package/dist/engine/boot-validator/screens-kind-config-edit.js +88 -0
  195. package/dist/engine/boot-validator/screens-kind-entity-edit.d.ts +3 -0
  196. package/dist/engine/boot-validator/screens-kind-entity-edit.js +55 -0
  197. package/dist/engine/boot-validator/screens-kind-entity-list.d.ts +3 -0
  198. package/dist/engine/boot-validator/screens-kind-entity-list.js +228 -0
  199. package/dist/engine/boot-validator/screens-kind-projection-detail.d.ts +3 -0
  200. package/dist/engine/boot-validator/screens-kind-projection-detail.js +235 -0
  201. package/dist/engine/boot-validator/screens-kind-projection-list.d.ts +3 -0
  202. package/dist/engine/boot-validator/screens-kind-projection-list.js +52 -0
  203. package/dist/engine/boot-validator/screens-kind-secret-mint.d.ts +3 -0
  204. package/dist/engine/boot-validator/screens-kind-secret-mint.js +28 -0
  205. package/dist/engine/boot-validator/screens-kind-shared.d.ts +37 -0
  206. package/dist/engine/boot-validator/screens-kind-shared.js +142 -0
  207. package/dist/engine/boot-validator/screens-lists.d.ts +2 -1
  208. package/dist/engine/boot-validator/screens-lists.js +26 -24
  209. package/dist/engine/boot-validator/screens.d.ts +0 -2
  210. package/dist/engine/boot-validator/screens.js +102 -869
  211. package/dist/engine/boot-validator/security-baseline.js +3 -2
  212. package/dist/engine/boot-validator/transfer-graph.js +2 -2
  213. package/dist/engine/boot-validator/workspaces.js +3 -3
  214. package/dist/engine/bridge-stub.js +3 -4
  215. package/dist/engine/build-app-schema.js +130 -170
  216. package/dist/engine/build-config-feature-schema.js +50 -50
  217. package/dist/engine/build-target.js +20 -23
  218. package/dist/engine/codemod/pipeline-codemod.js +20 -13
  219. package/dist/engine/config-helpers.js +4 -4
  220. package/dist/engine/constants.js +2 -2
  221. package/dist/engine/create-app.js +2 -2
  222. package/dist/engine/define-feature.js +21 -13
  223. package/dist/engine/define-handler.js +13 -11
  224. package/dist/engine/define-step.js +1 -1
  225. package/dist/engine/define-workflow.d.ts +5 -5
  226. package/dist/engine/define-workflow.js +6 -6
  227. package/dist/engine/entity-handlers.d.ts +13 -0
  228. package/dist/engine/entity-handlers.js +22 -34
  229. package/dist/engine/entity-list-runtime-options.d.ts +8 -0
  230. package/dist/engine/entity-list-runtime-options.js +18 -0
  231. package/dist/engine/event-def.js +2 -2
  232. package/dist/engine/extension-names.d.ts +16 -17
  233. package/dist/engine/extension-names.js +37 -38
  234. package/dist/engine/extensions/escape-hatch-usage.js +1 -1
  235. package/dist/engine/extensions/tenant-data.js +2 -2
  236. package/dist/engine/extensions/user-data.d.ts +23 -24
  237. package/dist/engine/factories.d.ts +14 -13
  238. package/dist/engine/factories.js +38 -37
  239. package/dist/engine/feature-ast/entity-field-types.js +1 -1
  240. package/dist/engine/feature-ast/extractors/handlers.js +2 -1
  241. package/dist/engine/feature-ast/extractors/hooks.js +1 -1
  242. package/dist/engine/feature-ast/extractors/round2.js +25 -6
  243. package/dist/engine/feature-ast/extractors/shared.d.ts +2 -3
  244. package/dist/engine/feature-ast/extractors/shared.js +2 -3
  245. package/dist/engine/feature-ast/parse.js +13 -13
  246. package/dist/engine/feature-ast/patch.js +4 -182
  247. package/dist/engine/feature-ast/pattern-change-schema.d.ts +3 -0
  248. package/dist/engine/feature-ast/pattern-change-schema.js +2 -1
  249. package/dist/engine/feature-ast/pattern-id-matchers.d.ts +7 -0
  250. package/dist/engine/feature-ast/pattern-id-matchers.js +210 -0
  251. package/dist/engine/feature-ast/patterns.d.ts +11 -2
  252. package/dist/engine/feature-ast/patterns.js +43 -51
  253. package/dist/engine/feature-ast/render.js +50 -89
  254. package/dist/engine/feature-config-events-jobs.js +15 -12
  255. package/dist/engine/feature-entity-handlers.js +12 -5
  256. package/dist/engine/feature-manifest.d.ts +9 -9
  257. package/dist/engine/feature-manifest.js +6 -7
  258. package/dist/engine/feature-ui-extensions.d.ts +3 -3
  259. package/dist/engine/feature-ui-extensions.js +30 -22
  260. package/dist/engine/field-access.js +5 -6
  261. package/dist/engine/form-derivations.js +18 -7
  262. package/dist/engine/handler-field-references.js +1 -1
  263. package/dist/engine/index.d.ts +1 -0
  264. package/dist/engine/index.js +4 -4
  265. package/dist/engine/object-form.d.ts +1 -0
  266. package/dist/engine/object-form.js +14 -4
  267. package/dist/engine/ownership.js +3 -3
  268. package/dist/engine/parse-ref-target.js +5 -7
  269. package/dist/engine/pattern-library/index.js +2 -2
  270. package/dist/engine/pattern-library/library.js +2 -2
  271. package/dist/engine/pattern-library/types.js +3 -3
  272. package/dist/engine/pipeline.js +2 -2
  273. package/dist/engine/project-app-schema-for-roles.d.ts +2 -0
  274. package/dist/engine/project-app-schema-for-roles.js +7 -5
  275. package/dist/engine/projection-helpers.js +9 -9
  276. package/dist/engine/qualified-name.js +2 -2
  277. package/dist/engine/registry-facade.js +1 -1
  278. package/dist/engine/registry-ingest.js +13 -13
  279. package/dist/engine/registry-state.js +17 -19
  280. package/dist/engine/registry-validate.js +12 -12
  281. package/dist/engine/run-in.js +2 -2
  282. package/dist/engine/run-pipeline.js +7 -0
  283. package/dist/engine/schema-builder.js +251 -233
  284. package/dist/engine/screen-filter-ops.js +17 -20
  285. package/dist/engine/screen-helpers.js +4 -3
  286. package/dist/engine/screen-kind.d.ts +7 -0
  287. package/dist/engine/screen-kind.js +1 -0
  288. package/dist/engine/state-machine.d.ts +12 -12
  289. package/dist/engine/state-machine.js +7 -7
  290. package/dist/engine/steps/_resolver-utils.js +4 -3
  291. package/dist/engine/steps/for-each.js +4 -4
  292. package/dist/engine/steps/unsafe-projection-delete.js +1 -1
  293. package/dist/engine/steps/unsafe-projection-upsert.js +4 -4
  294. package/dist/engine/steps/wait-for-event.js +4 -4
  295. package/dist/engine/steps/workflow-system-events.js +3 -3
  296. package/dist/engine/strip-disabled-features-from-app-schema.js +51 -14
  297. package/dist/engine/tier-resolver-extension.d.ts +29 -27
  298. package/dist/engine/tier-resolver-extension.js +26 -26
  299. package/dist/engine/transfer-adjacency.js +2 -2
  300. package/dist/engine/validate-projection-allowlist.js +9 -28
  301. package/dist/engine/walk-step-instances.d.ts +2 -0
  302. package/dist/engine/walk-step-instances.js +38 -0
  303. package/dist/engine/where-rule-lint.js +1 -1
  304. package/dist/engine/write-handler-qn-extract.js +1 -1
  305. package/dist/entrypoint/index.d.ts +4 -1
  306. package/dist/entrypoint/index.js +10 -4
  307. package/dist/env/index.d.ts +7 -6
  308. package/dist/env/index.js +10 -9
  309. package/dist/errors/docs-url.d.ts +1 -1
  310. package/dist/errors/docs-url.js +22 -2
  311. package/dist/errors/transition-details.js +7 -7
  312. package/dist/errors/write-error-info.d.ts +6 -6
  313. package/dist/errors/write-error-info.js +6 -6
  314. package/dist/es-ops/context.d.ts +9 -9
  315. package/dist/es-ops/context.js +29 -29
  316. package/dist/es-ops/index.js +7 -9
  317. package/dist/es-ops/operations-schema.js +4 -10
  318. package/dist/es-ops/runner.d.ts +11 -11
  319. package/dist/es-ops/runner.js +49 -53
  320. package/dist/es-ops/types.d.ts +55 -55
  321. package/dist/es-ops/types.js +11 -11
  322. package/dist/event-store/admin-api.js +7 -8
  323. package/dist/event-store/errors.js +1 -1
  324. package/dist/event-store/event-store.js +12 -6
  325. package/dist/event-store/rebuild-dead-letter.js +1 -1
  326. package/dist/files/bind-pending-file-refs.js +3 -3
  327. package/dist/files/create-file-ref-from-bytes.js +4 -1
  328. package/dist/files/feature.js +9 -10
  329. package/dist/files/file-handle.js +7 -9
  330. package/dist/files/file-ref-entity.js +15 -15
  331. package/dist/files/file-ref-table.js +7 -8
  332. package/dist/files/file-routes.d.ts +7 -0
  333. package/dist/files/file-routes.js +22 -13
  334. package/dist/files/in-memory-provider.js +8 -9
  335. package/dist/files/local-provider.js +18 -25
  336. package/dist/files/provider-resolver.d.ts +7 -7
  337. package/dist/files/resolve-content-type.js +43 -0
  338. package/dist/files/storage-tracking.js +2 -2
  339. package/dist/files/upload-ledger.js +7 -0
  340. package/dist/files/zip-stream.d.ts +12 -19
  341. package/dist/files/zip-stream.js +44 -63
  342. package/dist/i18n/required-surface-keys.d.ts +1 -1
  343. package/dist/i18n/required-surface-keys.js +188 -212
  344. package/dist/internal/stack-support.d.ts +2 -1
  345. package/dist/internal/stack-support.js +1 -1
  346. package/dist/jobs/job-runner-context.d.ts +32 -0
  347. package/dist/jobs/job-runner-context.js +305 -0
  348. package/dist/jobs/job-runner-execution.d.ts +7 -0
  349. package/dist/jobs/job-runner-execution.js +160 -0
  350. package/dist/jobs/job-runner-gates.d.ts +19 -0
  351. package/dist/jobs/job-runner-gates.js +198 -0
  352. package/dist/jobs/job-runner-helpers.d.ts +17 -3
  353. package/dist/jobs/job-runner-helpers.js +69 -4
  354. package/dist/jobs/job-runner-schedulers.d.ts +1 -1
  355. package/dist/jobs/job-runner-schedulers.js +3 -4
  356. package/dist/jobs/job-runner-scope.d.ts +44 -0
  357. package/dist/jobs/job-runner-scope.js +102 -0
  358. package/dist/jobs/job-runner-types.d.ts +12 -0
  359. package/dist/jobs/job-runner.d.ts +0 -1
  360. package/dist/jobs/job-runner.js +57 -669
  361. package/dist/lifecycle/lifecycle.js +3 -5
  362. package/dist/lifecycle/signal-handlers.js +5 -4
  363. package/dist/logging/utils.d.ts +2 -1
  364. package/dist/logging/utils.js +38 -10
  365. package/dist/migrations/index.js +1 -1
  366. package/dist/migrations/kumiko-drift.js +14 -13
  367. package/dist/migrations/pending-rebuilds.d.ts +21 -20
  368. package/dist/migrations/pending-rebuilds.js +27 -27
  369. package/dist/migrations/projection-table-index.d.ts +3 -3
  370. package/dist/migrations/projection-table-index.js +8 -8
  371. package/dist/observability/escape-hatch-report.d.ts +3 -0
  372. package/dist/observability/escape-hatch-report.js +12 -1
  373. package/dist/observability/metric-validator.js +1 -1
  374. package/dist/observability/metrics-handle.js +3 -3
  375. package/dist/pipeline/append-event-core.js +11 -2
  376. package/dist/pipeline/cascade-handler.d.ts +1 -1
  377. package/dist/pipeline/cascade-handler.js +165 -138
  378. package/dist/pipeline/dispatch-batch.js +2 -2
  379. package/dist/pipeline/dispatch-query.js +20 -13
  380. package/dist/pipeline/dispatch-shared.d.ts +14 -3
  381. package/dist/pipeline/dispatch-shared.js +67 -721
  382. package/dist/pipeline/dispatch-stream.js +1 -1
  383. package/dist/pipeline/dispatch-write.js +297 -190
  384. package/dist/pipeline/dispatcher-utils.d.ts +1 -1
  385. package/dist/pipeline/dispatcher-utils.js +1 -1
  386. package/dist/pipeline/event-consumer-state.js +2 -2
  387. package/dist/pipeline/event-dispatcher-admin.js +2 -1
  388. package/dist/pipeline/event-dispatcher-delivery.js +4 -6
  389. package/dist/pipeline/event-dispatcher.js +17 -28
  390. package/dist/pipeline/handler-context-auth.d.ts +9 -0
  391. package/dist/pipeline/handler-context-auth.js +54 -0
  392. package/dist/pipeline/handler-context-config.d.ts +14 -0
  393. package/dist/pipeline/handler-context-config.js +113 -0
  394. package/dist/pipeline/handler-context-db.d.ts +24 -0
  395. package/dist/pipeline/handler-context-db.js +149 -0
  396. package/dist/pipeline/handler-context-dispatch.d.ts +21 -0
  397. package/dist/pipeline/handler-context-dispatch.js +89 -0
  398. package/dist/pipeline/handler-context-events.d.ts +43 -0
  399. package/dist/pipeline/handler-context-events.js +237 -0
  400. package/dist/pipeline/handler-context-notify.d.ts +12 -0
  401. package/dist/pipeline/handler-context-notify.js +55 -0
  402. package/dist/pipeline/handler-context-observability.d.ts +7 -0
  403. package/dist/pipeline/handler-context-observability.js +21 -0
  404. package/dist/pipeline/handler-context-scope.d.ts +48 -0
  405. package/dist/pipeline/handler-context-scope.js +88 -0
  406. package/dist/pipeline/irreversible-operation-gate.js +1 -1
  407. package/dist/pipeline/lifecycle-pipeline.js +9 -9
  408. package/dist/pipeline/member-read-only-transaction.js +1 -3
  409. package/dist/pipeline/msp-rebuild.js +1 -1
  410. package/dist/pipeline/notify-scope.js +12 -1
  411. package/dist/pipeline/pre-handler-gates.js +20 -4
  412. package/dist/pipeline/pre-transaction-reservations.d.ts +1 -0
  413. package/dist/pipeline/pre-transaction-reservations.js +9 -3
  414. package/dist/pipeline/projection-rebuild.js +15 -13
  415. package/dist/pipeline/system-hooks.js +39 -41
  416. package/dist/pipeline/system-identity-switch.js +1 -3
  417. package/dist/pipeline/tenant-timezone-cache.js +1 -1
  418. package/dist/random/generate.d.ts +29 -29
  419. package/dist/random/generate.js +30 -30
  420. package/dist/random/words.js +20 -20
  421. package/dist/rate-limit/middleware.js +9 -5
  422. package/dist/redis/client.js +2 -2
  423. package/dist/redis/pubsub-signal.js +14 -17
  424. package/dist/schema-cli/apply-command.d.ts +2 -0
  425. package/dist/schema-cli/apply-command.js +97 -0
  426. package/dist/schema-cli/baseline-command.d.ts +2 -0
  427. package/dist/schema-cli/baseline-command.js +33 -0
  428. package/dist/schema-cli/generate-command.d.ts +2 -0
  429. package/dist/schema-cli/generate-command.js +90 -0
  430. package/dist/schema-cli/shared.d.ts +39 -0
  431. package/dist/schema-cli/shared.js +95 -0
  432. package/dist/schema-cli/status-command.d.ts +2 -0
  433. package/dist/schema-cli/status-command.js +73 -0
  434. package/dist/schema-cli/validate-boot-input.d.ts +5 -0
  435. package/dist/schema-cli/validate-boot-input.js +130 -0
  436. package/dist/schema-cli/validate-command.d.ts +2 -0
  437. package/dist/schema-cli/validate-command.js +130 -0
  438. package/dist/schema-cli.d.ts +2 -18
  439. package/dist/schema-cli.js +47 -510
  440. package/dist/search/index.js +4 -4
  441. package/dist/search/meilisearch-adapter.js +2 -1
  442. package/dist/search/purge-subject.js +4 -5
  443. package/dist/search/reindex-entity.js +6 -9
  444. package/dist/time/boot-tz-warning.d.ts +2 -2
  445. package/dist/time/boot-tz-warning.js +8 -8
  446. package/dist/time/iana.js +10 -10
  447. package/dist/time/index.js +9 -9
  448. package/dist/time/legacy-date.d.ts +2 -2
  449. package/dist/time/legacy-date.js +6 -8
  450. package/dist/time/polyfill.js +1 -1
  451. package/dist/time/tz-context.d.ts +1 -1
  452. package/dist/time/tz-context.js +1 -1
  453. package/dist/ui-types/app-schema.js +7 -7
  454. package/dist/ui-types/list-row-meta.js +4 -4
  455. package/dist/upgrade-cli.js +159 -130
  456. package/dist/utils/compare.js +1 -1
  457. package/package.json +5 -5
  458. package/src/changes.json +358 -0
  459. package/src/scripts/codemod/crypto-shredding-testing-move.ts +2 -2
  460. package/src/scripts/codemod/feature-layout.ts +10 -2
  461. package/src/scripts/codemod/migrate-cross-tenant.ts +1 -1
  462. package/src/scripts/codemod/migrate-open-to-all.ts +1 -1
  463. package/src/scripts/codemod/object-form.ts +41 -4
  464. package/src/scripts/codemod/package-merge.ts +58 -8
  465. package/src/scripts/codemod/pii-personal-migration.ts +192 -153
  466. package/src/scripts/codemod/testing-injection.ts +122 -42
  467. package/src/scripts/codemod/testing-move.ts +29 -7
  468. package/src/scripts/codemod/unprocessable-error-details-reason.ts +2 -2
@@ -1,13 +1,16 @@
1
1
  import { ENTITY_CONVENTION_QUERY_BRAND } from "@cosmicdrift/kumiko-types/handlers";
2
+ import { listAggregatePayloadSchema, } from "@cosmicdrift/kumiko-types/list-aggregate-types";
2
3
  import * as z from "zod";
3
4
  import { collectReferenceFields, enrichRowWithReferences, enrichWithReferences, } from "../db/eagerload.js";
4
5
  import { createEventStoreExecutor } from "../db/event-store-executor.js";
6
+ import { answerListAggregate } from "../db/list-aggregate-labels.js";
5
7
  import { buildEntityTable } from "../db/table-builder.js";
6
8
  import { acknowledgeConventionCrossTenant, reportConventionCrossTenantUse, } from "../db/tenant-db.js";
7
9
  import { InternalError } from "../errors/index.js";
8
10
  import { isSystemIdentity } from "../pipeline/system-identity-switch.js";
9
11
  import { assertUnreachable } from "../utils/index.js";
10
12
  import { PAGED_QUERY_HANDLER_BRAND } from "./define-handler.js";
13
+ import { entityListRuntime } from "./entity-list-runtime-options.js";
11
14
  import { assertReason } from "./escape-hatch-reason.js";
12
15
  import { dropEmptyWriteOnlyValues } from "./field-access.js";
13
16
  import { instructionFieldNames } from "./instruction-fields.js";
@@ -90,14 +93,14 @@ export const entityListSchema = z.object({
90
93
  .object({
91
94
  field: z.string(),
92
95
  op: z.enum(["eq", "ne", "lt", "gt", "lte", "gte", "in"]),
93
- // Value ist `unknown` zur Compile-Zeit; Server-Side prüft beim
94
- // Build der WHERE-Clause ob der Type zum Field passt. z.unknown()
95
- // lässt alles durch; Type-Check kommt im executor.list.
96
+ // `unknown` at compile time; the server checks while building the WHERE
97
+ // clause that the value's type matches the field. z.unknown() accepts
98
+ // everything, so the type check occurs in executor.list.
96
99
  value: z.unknown(),
97
100
  })
98
101
  .optional(),
99
- // User-gewählte Faceted-Filter (dynamisch). Additiv zum statischen
100
- // `filter` — executor.list verknüpft alle mit AND.
102
+ // User-selected faceted filters are dynamic and additive to the static
103
+ // `filter`; executor.list combines all of them with AND.
101
104
  filters: z
102
105
  .array(z.object({
103
106
  field: z.string(),
@@ -105,6 +108,7 @@ export const entityListSchema = z.object({
105
108
  value: z.unknown(),
106
109
  }))
107
110
  .optional(),
111
+ aggregate: listAggregatePayloadSchema.optional(),
108
112
  });
109
113
  function parseHandlerName(name, validVerbs) {
110
114
  const colonIdx = name.indexOf(":");
@@ -277,10 +281,10 @@ export function defineEntityWriteHandler(name, entity, options) {
277
281
  changes: dropEmptyWriteOnlyValues(entity, submitted.changes),
278
282
  };
279
283
  const streamTenantId = await foreignRowTenantFor(event.user, payload.id, db, ctx);
280
- // skipUnchanged (#464): API-driven updates diff against the stored
284
+ // skipUnchanged: API-driven updates diff against the stored
281
285
  // row so a resubmitted-but-identical field doesn't force a fresh
282
286
  // pii/encrypted ciphertext. Direct executor.update() callers (e.g.
283
- // KEK-rotation, the user-data-rights #494 backfill) don't go through
287
+ // KEK-rotation, the user-data-rights backfill) don't go through
284
288
  // this handler and keep today's always-re-encrypt behavior, which
285
289
  // they rely on to intentionally force a fresh event/ciphertext.
286
290
  return executor.update(payload, event.user, db, {
@@ -350,7 +354,7 @@ export function defineEntityQueryHandler(name, entity, options) {
350
354
  const executor = createEventStoreExecutor(table, entity, { entityName });
351
355
  let schema;
352
356
  let handler;
353
- // Tier 2.7e server-eagerload: when the entity has reference fields, the
357
+ // Server-side eager loading: when the entity has reference fields, the
354
358
  // handler resolves the UUIDs against the referenced entities after the
355
359
  // main query. The `_refs` property lands on every row; the renderer-side
356
360
  // useReferenceLookup stays as a fallback (for apps that write custom
@@ -384,35 +388,19 @@ export function defineEntityQueryHandler(name, entity, options) {
384
388
  case "list":
385
389
  schema = entityListSchema;
386
390
  handler = async (query, ctx) => {
387
- // Tier 2.7e Audit-Fix: SearchAdapter aus ctx durchreichen,
388
- // damit payload.search zur Laufzeit gegen Meilisearch/InMem
389
- // läuft (Remote-Combobox-Search). Der executor wird beim
390
- // Definition-Time gebaut, kennt den Adapter also nicht —
391
- // Runtime-Override holt das.
391
+ // Pass the SearchAdapter from ctx through so payload.search is executed
392
+ // against Meilisearch/InMem at runtime (remote combobox search). The
393
+ // executor is built at definition time and cannot know the adapter, so the
394
+ // runtime override supplies it.
392
395
  const listPayload = query.payload; // @cast-boundary engine-payload
393
396
  const db = dbFor(ctx);
394
- const result = await executor.list(listPayload, query.user, db, {
395
- ...(ctx.searchAdapter !== undefined && { searchAdapter: ctx.searchAdapter }),
396
- ...(ctx.includeDeleted === true && { includeDeleted: true }),
397
- // fw#2660 — registry access only exists at request time, so the
398
- // searchable-reference cache + entity resolver travel through the
399
- // same runtime-override extension point as searchAdapter above.
400
- referenceSearch: {
401
- fields: ctx.registry.getSearchableReferences(entityName),
402
- resolveEntity: (name) => ctx.registry.getEntity(name),
403
- },
404
- referenceSort: {
405
- fields: ctx.registry.getSortableReferences(entityName),
406
- resolveEntity: (name) => ctx.registry.getEntity(name),
407
- },
408
- parentVisibility: { entities: ctx.registry.getAllEntities() },
409
- });
410
- const eagerLoadViewer = {
411
- user: query.user,
412
- parentVisibility: { entities: ctx.registry.getAllEntities() },
413
- };
397
+ const { runtimeOptions, eagerLoadViewer, resolveEntity } = entityListRuntime(ctx, entityName, query.user);
398
+ if (listPayload.aggregate !== undefined) {
399
+ return answerListAggregate(executor, { ...listPayload, aggregate: listPayload.aggregate }, query.user, db, runtimeOptions, { entity, resolveEntity, viewer: eagerLoadViewer });
400
+ }
401
+ const result = await executor.list(listPayload, query.user, db, runtimeOptions);
414
402
  const enrichedRows = hasRefFields
415
- ? await enrichWithReferences(result.rows, entity, (name) => ctx.registry.getEntity(name), db, eagerLoadViewer)
403
+ ? await enrichWithReferences(result.rows, entity, resolveEntity, db, eagerLoadViewer)
416
404
  : result.rows;
417
405
  return { ...result, rows: augmentDerivedFields(enrichedRows, entity) };
418
406
  };
@@ -0,0 +1,8 @@
1
+ import type { ListRuntimeOptions } from "@cosmicdrift/kumiko-types/event-store-executor-types";
2
+ import type { EagerLoadEntityResolver, EagerLoadViewer } from "../db/eagerload.ts";
3
+ import type { HandlerContext, SessionUser } from "./types/index.ts";
4
+ export declare function entityListRuntime(ctx: HandlerContext, entityName: string, user: SessionUser): {
5
+ readonly runtimeOptions: ListRuntimeOptions;
6
+ readonly eagerLoadViewer: EagerLoadViewer;
7
+ readonly resolveEntity: EagerLoadEntityResolver;
8
+ };
@@ -0,0 +1,18 @@
1
+ // Registry access only exists at request time, so the searchable/sortable-reference
2
+ // caches, the entity resolver and the join-row read gate travel through the
3
+ // runtime-override extension point of the executor verbs.
4
+ export function entityListRuntime(ctx, entityName, user) {
5
+ const parentVisibility = { entities: ctx.registry.getAllEntities() };
6
+ const resolveEntity = (name) => ctx.registry.getEntity(name);
7
+ return {
8
+ runtimeOptions: {
9
+ ...(ctx.searchAdapter !== undefined && { searchAdapter: ctx.searchAdapter }),
10
+ ...(ctx.includeDeleted === true && { includeDeleted: true }),
11
+ referenceSearch: { fields: ctx.registry.getSearchableReferences(entityName), resolveEntity },
12
+ referenceSort: { fields: ctx.registry.getSortableReferences(entityName), resolveEntity },
13
+ parentVisibility,
14
+ },
15
+ eagerLoadViewer: { user, parentVisibility },
16
+ resolveEntity,
17
+ };
18
+ }
@@ -2,7 +2,7 @@ import { normalizeEventPiiSubject } from "@cosmicdrift/kumiko-types/handlers";
2
2
  import { ZodObject } from "zod";
3
3
  import { qn, toKebab } from "./qualified-name.js";
4
4
  // A payload field that still holds null/undefined after parsing — the case
5
- // where an event-PII owner field yields no subject at append time (fw#2776).
5
+ // where an event-PII owner field yields no subject at append time.
6
6
  // A `.default(...)` accepts undefined but parses to a value, so it is not
7
7
  // absentable.
8
8
  function isAbsentable(field) {
@@ -90,7 +90,7 @@ function validateEventPiiFields(featureName, eventName, schema, piiFields) {
90
90
  */
91
91
  export function createEventDef(options) {
92
92
  const { feature, name: eventName, schema } = options;
93
- // Fail-closed PII stance gate (fw#2558) — runs before anything else so
93
+ // Fail-closed PII stance gate — runs before anything else so
94
94
  // an untyped JS consumer (no compiler to stop it) still can't register
95
95
  // an event without declaring whether its payload carries personal data.
96
96
  const missingStanceError = () => new Error(`[Feature ${feature}] defineEvent("${eventName}") must declare an explicit PII stance. Pass { piiFields: { <payloadField>: { personal: { of: "<userIdField>" } } } } for payload fields owned by a user (or { personal: "tenant" } / { personal: "self" } for tenant- or record-scoped subjects), or { piiFields: "none" } when the payload holds none.`);
@@ -8,14 +8,14 @@ import type { UserDataExtensionOptions } from "./extensions/user-data.ts";
8
8
  import type { AssignableFromRole } from "./role-assignment.ts";
9
9
  import { TENANT_TIER_RESOLVER_EXT, type TierResolverPlugin } from "./tier-resolver-extension.ts";
10
10
  /**
11
- * `userData` — User-Daten-Rights-Hooks (DSGVO Art. 15 + 17 + 20).
11
+ * `userData` — user-data rights hooks (GDPR Articles 15, 17, and 20).
12
12
  *
13
- * Erwartete Hook-Methoden:
13
+ * Expected hook methods:
14
14
  * - `export(userId, ctx) => Promise<UserDataExport>`
15
15
  * - `delete(userId, strategy: "delete" | "anonymize", ctx) => Promise<void>`
16
16
  *
17
- * Registriert von: `user-data-rights` (Sprint 2).
18
- * Genutzt von: jedes Feature mit User-Referenzen (tasks, comments, files, ...).
17
+ * Registered by: `user-data-rights`.
18
+ * Used by: every feature with user references (tasks, comments, files, ...).
19
19
  */
20
20
  export declare const EXT_USER_DATA: "userData";
21
21
  export declare const EXT_USER_DATA_ORDER: {
@@ -41,17 +41,16 @@ export declare const EXT_TENANT_DATA: "tenantData";
41
41
  */
42
42
  export declare const EXT_STORAGE_PROVIDER: "storageProvider";
43
43
  /**
44
- * `fileProvider` — File-Storage-Provider-Plugin-Selection (file-foundation).
44
+ * `fileProvider` — file-storage provider plugin selection (file-foundation).
45
45
  *
46
- * Provider-Features (file-provider-s3, -inmemory, -s3-env) registrieren eine
47
- * Implementierung via `r.useExtension(EXT_FILE_PROVIDER, "<name>", { build })`;
48
- * der per-Tenant Config-Key `provider` waehlt zur Runtime eine aus. Der
49
- * Framework-Resolver (`createFileProviderForTenant`) liest das, damit Upload-
50
- * Routes, `ctx.files` UND die DSGVO-Jobs denselben Store treffen.
46
+ * Provider features (file-provider-s3, -inmemory, -s3-env) register an
47
+ * implementation via `r.useExtension(EXT_FILE_PROVIDER, "<name>", { build })`;
48
+ * the per-tenant config key `provider` selects one at runtime. The framework
49
+ * resolver (`createFileProviderForTenant`) reads it so upload routes,
50
+ * `ctx.files`, and GDPR jobs all use the same store.
51
51
  *
52
- * Framework-seitig besessen, damit kein String-Drift entsteht — file-
53
- * foundation MUSS Extension-Point + Config-Key unter genau diesen Namen
54
- * registrieren.
52
+ * The framework owns this contract to prevent string drift — file-foundation
53
+ * MUST register the extension point and config key under exactly these names.
55
54
  */
56
55
  export declare const EXT_FILE_PROVIDER: "fileProvider";
57
56
  export declare const FILE_PROVIDER_CONFIG_KEY: "file-foundation:config:provider";
@@ -85,7 +84,7 @@ export declare const EXT_DERIVATIVE_RENDERER: "derivativeRenderer";
85
84
  * serves nothing for that entityType, not even a 403 (404, so existence isn't
86
85
  * confirmed to an unauthorised caller).
87
86
  *
88
- * Registered/consumed by: `file-derivatives`' public variant route (#1951).
87
+ * Registered/consumed by: `file-derivatives`' public variant route.
89
88
  */
90
89
  export declare const EXT_DERIVATIVE_PUBLIC_PREDICATE: "derivativePublicPredicate";
91
90
  /**
@@ -150,9 +149,9 @@ export declare const EXT_TENANT_LIFECYCLE_STATUS: "tenantLifecycleStatus";
150
149
  export declare const EXT_ASSIGNABLE_ROLE: "assignableRole";
151
150
  export declare const TENANT_MEMBERSHIPS_QUERY: "tenant:query:memberships";
152
151
  /**
153
- * Union aller standardisierten Extension-Namen der Datenschutz-Surface.
154
- * Nicht alle Extensions im System sind in dieser Liste — andere
155
- * Features koennen weiterhin eigene Extension-Namen registrieren.
152
+ * Union of standardized extension names for the privacy surface.
153
+ * Not every extension in the system is included — other features can still
154
+ * register their own extension names.
156
155
  */
157
156
  export type KumikoExtensionName = typeof EXT_USER_DATA | typeof EXT_TENANT_DATA | typeof EXT_STORAGE_PROVIDER | typeof EXT_SEARCH_ADAPTER | typeof EXT_EXTERNAL_RESOURCE | typeof EXT_INFRA_RESOURCE | typeof EXT_FILE_PROVIDER | typeof EXT_DERIVATIVE_RENDERER | typeof EXT_DERIVATIVE_PUBLIC_PREDICATE | typeof EXT_DERIVATIVE_OVERLAY_RESOLVER | typeof EXT_PRINCIPAL_STATUS | typeof EXT_TENANT_LIFECYCLE_STATUS | typeof EXT_ASSIGNABLE_ROLE;
158
157
  /** The four `destroyTenant(tenantId, ctx)`-only resource-cleanup extension points. */
@@ -1,42 +1,42 @@
1
1
  import { TENANT_TIER_RESOLVER_EXT } from "./tier-resolver-extension.js";
2
- // Standardisierte Extension-Namen fuer Datenschutz-Hook-Achsen.
2
+ // Standardized extension names for privacy-hook axes.
3
3
  //
4
- // Features registrieren Extensions via:
4
+ // Features register extensions via:
5
5
  // r.extendsRegistrar(EXT_USER_DATA, { hooks: { ... } });
6
6
  //
7
- // Andere Features haengen sich ein via:
7
+ // Other features attach to them via:
8
8
  // r.useExtension(EXT_USER_DATA, "myEntity", { ...hookImpls });
9
9
  //
10
- // Hintergrund: Magic-Strings driften zwischen Bundled-Features (Beispiel:
11
- // text-content nutzt "Admin" als Rolle, tenant-handler nutzt "TenantAdmin").
12
- // Constants sind die einzige Quelle der Wahrheit; String-Literale werden
13
- // in den Sprint-Touchpoints schrittweise ersetzt. Boot-Validator
14
- // (validateExtensionUsages) checkt dass jedes useExtension einen
15
- // passenden extendsRegistrar findet — Tippfehler in Constants →
16
- // Compile-Time-Fail.
10
+ // Background: magic strings drift between bundled features (for example,
11
+ // text-content uses "Admin" as a role, while tenant-handler uses
12
+ // "TenantAdmin"). Constants are the single source of truth; string literals
13
+ // are gradually replaced at the relevant integration points. The boot
14
+ // validator (validateExtensionUsages) checks that every useExtension has a
15
+ // matching extendsRegistrar, so typos in constants cause a compile-time
16
+ // failure.
17
17
  //
18
- // Hook-Signaturen + Boot-Validation pro Extension-Achse kommen mit dem
19
- // jeweiligen registrierenden Sprint:
20
- // userData / tenantData → Sprint 2 (user-data-rights, retention)
21
- // storageProvider → Sprint 4 (storage-encryption)
22
- // searchAdapter / external / → Sprint 5 (tenant-lifecycle)
18
+ // Hook signatures and boot validation for each extension axis are added by
19
+ // the feature that registers that axis:
20
+ // userData / tenantData → (user-data-rights, retention)
21
+ // storageProvider → (storage-encryption)
22
+ // searchAdapter / external / → (tenant-lifecycle)
23
23
  // infraResource
24
24
  /**
25
- * `userData` — User-Daten-Rights-Hooks (DSGVO Art. 15 + 17 + 20).
25
+ * `userData` — user-data rights hooks (GDPR Articles 15, 17, and 20).
26
26
  *
27
- * Erwartete Hook-Methoden:
27
+ * Expected hook methods:
28
28
  * - `export(userId, ctx) => Promise<UserDataExport>`
29
29
  * - `delete(userId, strategy: "delete" | "anonymize", ctx) => Promise<void>`
30
30
  *
31
- * Registriert von: `user-data-rights` (Sprint 2).
32
- * Genutzt von: jedes Feature mit User-Referenzen (tasks, comments, files, ...).
31
+ * Registered by: `user-data-rights`.
32
+ * Used by: every feature with user references (tasks, comments, files, ...).
33
33
  */
34
34
  export const EXT_USER_DATA = "userData";
35
- // Order-Bänder für EXT_USER_DATA-Hooks (forget-Pipeline). Der Kontrakt war
36
- // implizit über zwei Packages verteilt (-100 in custom-fields, 0 in
37
- // user-data-rights) — ein Host-Hook mit order < REDACT_BEFORE_OWNER liefe
38
- // VOR den Redaktoren und brächte den Strip-nach-owner-null-Bug zurück
39
- // (DSGVO-Art.-17-Regression). Regel: Redaktoren < 0 <= owner-mutierende Hooks.
35
+ // Ordering bands for EXT_USER_DATA hooks (forget pipeline). The contract was
36
+ // implicit across two packages (-100 in custom-fields, 0 in
37
+ // user-data-rights), so a host hook with order < REDACT_BEFORE_OWNER would run
38
+ // BEFORE the redactors and reintroduce the strip-after-owner-null bug
39
+ // (GDPR Article 17 regression). Rule: redactors < 0 <= owner-mutating hooks.
40
40
  export const EXT_USER_DATA_ORDER = {
41
41
  REDACT_BEFORE_OWNER: -100,
42
42
  DEFAULT: 0,
@@ -60,23 +60,22 @@ export const EXT_TENANT_DATA = "tenantData";
60
60
  */
61
61
  export const EXT_STORAGE_PROVIDER = "storageProvider";
62
62
  /**
63
- * `fileProvider` — File-Storage-Provider-Plugin-Selection (file-foundation).
63
+ * `fileProvider` — file-storage provider plugin selection (file-foundation).
64
64
  *
65
- * Provider-Features (file-provider-s3, -inmemory, -s3-env) registrieren eine
66
- * Implementierung via `r.useExtension(EXT_FILE_PROVIDER, "<name>", { build })`;
67
- * der per-Tenant Config-Key `provider` waehlt zur Runtime eine aus. Der
68
- * Framework-Resolver (`createFileProviderForTenant`) liest das, damit Upload-
69
- * Routes, `ctx.files` UND die DSGVO-Jobs denselben Store treffen.
65
+ * Provider features (file-provider-s3, -inmemory, -s3-env) register an
66
+ * implementation via `r.useExtension(EXT_FILE_PROVIDER, "<name>", { build })`;
67
+ * the per-tenant config key `provider` selects one at runtime. The framework
68
+ * resolver (`createFileProviderForTenant`) reads it so upload routes,
69
+ * `ctx.files`, and GDPR jobs all use the same store.
70
70
  *
71
- * Framework-seitig besessen, damit kein String-Drift entsteht — file-
72
- * foundation MUSS Extension-Point + Config-Key unter genau diesen Namen
73
- * registrieren.
71
+ * The framework owns this contract to prevent string drift — file-foundation
72
+ * MUST register the extension point and config key under exactly these names.
74
73
  */
75
74
  export const EXT_FILE_PROVIDER = "fileProvider";
76
- // Qualifizierter Config-Key, den das file-foundation-Feature registriert
77
- // (Format `<feature>:config:<key>`). Akzeptierte Kopplung: der Framework-
78
- // Resolver liegt UNTER dem Feature und liest den Key per String. Umbenennen
79
- // des file-foundation-Features MUSS diese Konstante mitziehen.
75
+ // Qualified config key registered by the file-foundation feature
76
+ // (format `<feature>:config:<key>`). This coupling is intentional: the
77
+ // framework resolver is below the feature and reads the key by string. Renaming
78
+ // the file-foundation feature MUST be accompanied by changing this constant.
80
79
  export const FILE_PROVIDER_CONFIG_KEY = "file-foundation:config:provider";
81
80
  // Two roles: boot gate (validateBoot requires its presence once file/image
82
81
  // fields are in use) AND the ENV source of the config key above, bridged via
@@ -114,7 +113,7 @@ export const EXT_DERIVATIVE_RENDERER = "derivativeRenderer";
114
113
  * serves nothing for that entityType, not even a 403 (404, so existence isn't
115
114
  * confirmed to an unauthorised caller).
116
115
  *
117
- * Registered/consumed by: `file-derivatives`' public variant route (#1951).
116
+ * Registered/consumed by: `file-derivatives`' public variant route.
118
117
  */
119
118
  export const EXT_DERIVATIVE_PUBLIC_PREDICATE = "derivativePublicPredicate";
120
119
  /**
@@ -1,4 +1,4 @@
1
- // fw#2914 — reads the { escapeHatch: { reason } } convention off a
1
+ // reads the { escapeHatch: { reason } } convention off a
2
2
  // `r.useExtension(...)` registration's untyped options bag. Registration-time
3
3
  // validation (feature-ui-extensions.ts's useExtension) already rejects an
4
4
  // empty reason, but options stays `Record<string, unknown>`, so orchestrators
@@ -1,7 +1,7 @@
1
- // Hook-Signatur-Types für EXT_TENANT_DATA (DSGVO tenant-scoped destroy).
1
+ // Hook signature types for EXT_TENANT_DATA (GDPR tenant-scoped destruction).
2
2
  //
3
3
  // Mirror of engine/extensions/user-data.ts at tenant granularity.
4
- // tenant-lifecycle orchestrates destroy via registry.getExtensionUsages(EXT_TENANT_DATA).
4
+ // tenant-lifecycle orchestrates destruction via registry.getExtensionUsages(EXT_TENANT_DATA).
5
5
  export function isTenantDataExtensionHooks(o) {
6
6
  return typeof o === "object" && o !== null && "destroy" in o && typeof o.destroy === "function";
7
7
  }
@@ -2,15 +2,15 @@ import type { TenantDb } from "../../db/tenant-db.ts";
2
2
  import type { Registry, TenantId } from "../types/index.ts";
3
3
  type UserId = string;
4
4
  /**
5
- * Strategie für den Forget-Pfad pro Entity:
6
- * - "delete": Row physisch entfernen (Profil, Eigene Notizen, Sessions).
7
- * - "anonymize": User-Reference auf null + Display-Felder auf
8
- * "[Geloescht]" — typisch für geteilte Daten (Tasks,
9
- * Comments) damit andere User die History nicht verlieren.
5
+ * Strategy for the forget path per entity:
6
+ * - "delete": Physically remove the row (profile, personal notes, sessions).
7
+ * - "anonymize": Set the user reference to null and display fields to
8
+ * "[Geloescht]" — typical for shared data (tasks,
9
+ * comments) so other users do not lose the history.
10
10
  *
11
- * Cleanup-Job (Sprint 2 data-retention) entscheidet pro Entity über
12
- * Retention-Policy, welche Strategie greift. blockDelete-Entries lösen
13
- * IMMER `anonymize` aus damit Aufbewahrungs-Pflicht respektiert wird.
11
+ * The cleanup job applies the retention policy per entity to select the
12
+ * strategy. blockDelete entries ALWAYS use `anonymize` to respect retention
13
+ * obligations.
14
14
  */
15
15
  export type UserDataDeleteStrategy = "delete" | "anonymize";
16
16
  /**
@@ -27,7 +27,7 @@ export type UserDataDeleteStrategy = "delete" | "anonymize";
27
27
  */
28
28
  export type TenantUserModel = "single-user" | "multi-user";
29
29
  /**
30
- * fw#2914 — `db` is a tenant-filtered `TenantDb`, bound to `tenantId`
30
+ * `db` is a tenant-filtered `TenantDb`, bound to `tenantId`
31
31
  * (or the per-user sub-tx in the forget path). Unfiltered access needs
32
32
  * `escapeHatch: { reason }` on the `r.useExtension(...)` registration,
33
33
  * then `ctx.db.unsafeRaw()`.
@@ -82,15 +82,15 @@ export interface UserDataHookCtx {
82
82
  readonly userEmailBeforeDelete?: string | null;
83
83
  }
84
84
  /**
85
- * Pro Feature/Entity-Snippet das im Export-Bundle landet. Sprint 2
86
- * orchestriert die JSON-Serialisierung; Hooks geben Plain-Records.
85
+ * Feature/entity snippet included in the export bundle. The export job
86
+ * orchestrates JSON serialization; hooks return plain records.
87
87
  */
88
88
  export interface UserDataExportSnippet {
89
89
  readonly entity: string;
90
90
  readonly rows: ReadonlyArray<Record<string, unknown>>;
91
91
  /**
92
- * Optional: signed-URLs für File-Refs. user-data-rights packt sie
93
- * separat ins ZIP unter `files/`. Andere Hooks lassen das leer.
92
+ * Optional signed URLs for file references. user-data-rights puts them
93
+ * separately in the ZIP under `files/`. Other hooks leave this empty.
94
94
  */
95
95
  readonly fileRefs?: ReadonlyArray<{
96
96
  readonly fileRefId: string;
@@ -99,22 +99,21 @@ export interface UserDataExportSnippet {
99
99
  }>;
100
100
  }
101
101
  /**
102
- * Export-Hook: Sammelt alle Daten einer Entity die zu einem User
103
- * gehören. Wird im Daten-Export-Job pro registrierter Entity einmal
104
- * aufgerufen. Idempotent — kann mehrfach aufgerufen werden ohne
105
- * Side-Effects.
102
+ * Export hook: collects all data belonging to a user for an entity. It is
103
+ * called once per registered entity by the data export job. Idempotent — it
104
+ * can be called multiple times without side effects.
106
105
  *
107
- * Sprint 2 user-data-rights ruft das via Iteration über alle
108
- * `r.useExtension(EXT_USER_DATA, ...)`-Registrierungen.
106
+ * The data-rights runner invokes this by iterating over all
107
+ * `r.useExtension(EXT_USER_DATA, ...)` registrations.
109
108
  */
110
109
  export type UserDataExportHook = (ctx: UserDataHookCtx) => Promise<UserDataExportSnippet | null>;
111
110
  /**
112
- * Forget-Hook: Löscht oder anonymisiert die Entity-Rows die zu einem
113
- * User gehören. Strategy kommt vom Cleanup-Job (kann per Entity
114
- * unterschiedlich sein wegen Retention-Policy).
111
+ * Forget hook: deletes or anonymizes entity rows belonging to a user. The
112
+ * cleanup job supplies the strategy, which may differ by entity because of
113
+ * the retention policy.
115
114
  *
116
- * Idempotent — wenn der Job zweimal läuft (Crash-Recovery), darf der
117
- * Hook nicht crashen.
115
+ * Idempotent — if the job runs twice during crash recovery, the hook must not
116
+ * crash.
118
117
  *
119
118
  * Return additive to `void`: a hook can return `{status:"ok"}` or
120
119
  * `{status:"incomplete", reason}` to signal a partial success to the
@@ -7,13 +7,13 @@ export declare function createTextField<R extends true | false = false>(override
7
7
  };
8
8
  /**
9
9
  * Long-form text field for source-code, markdown, blog-posts, email-
10
- * templates — anything that can be megabytes large. Type-level differs
11
- * from `text`: keine sortable/searchable/filterable/format options.
12
- * DB-mapping ist identisch zu text (PG text ist unbounded).
10
+ * templates — anything that can be megabytes large. Its type-level API
11
+ * differs from `text`: it has no sortable/searchable/filterable/format options.
12
+ * The DB mapping is identical to text (`PG text` is unbounded).
13
13
  *
14
- * Soft-cap default: kein maxLength (PG text ist 1 GB hart begrenzt).
15
- * Setze einen explicit `maxLength` wenn du ein verirrtes Browser-Paste
16
- * früh ablehnen willst (z.B. 1_000_000 = 1 MB).
14
+ * Soft-cap default: no maxLength (`PG text` has a 1 GB hard limit).
15
+ * Set an explicit `maxLength` to reject an accidental browser paste early
16
+ * (for example, `1_000_000 = 1 MB`).
17
17
  */
18
18
  /**
19
19
  * Read-time computed field for `EntityDefinition.derivedFields` (NOT `fields`).
@@ -112,12 +112,12 @@ export declare function createDateField<R extends true | false = false>(override
112
112
  required: R;
113
113
  };
114
114
  /**
115
- * UTC-Instant — für Ereignisse die zu einem bestimmten Zeitpunkt passieren
116
- * (createdAt, loginAt, actualPickupAt). Temporal.Instant intern.
115
+ * UTC instant for events occurring at a specific point in time
116
+ * (createdAt, loginAt, actualPickupAt). Uses Temporal.Instant internally.
117
117
  *
118
- * Mit `locatedBy: "<name>Tz"` wird das Feld zum Wall-Clock-Pair eines
119
- * Termins an einem Ort — bevorzuge dafür `createLocatedTimestampField()`,
120
- * das EIN atomares Feld statt eines lose verdrahteten Pairs erzeugt.
118
+ * With `locatedBy: "<name>Tz"`, the field becomes a wall-clock pair for an
119
+ * appointment at a location — prefer `createLocatedTimestampField()` instead,
120
+ * which creates one atomic field rather than a loosely connected pair.
121
121
  */
122
122
  export declare function createTimestampField<R extends true | false = false>(overrides?: Partial<Omit<TimestampFieldDef, "type" | "required" | keyof ResolvedPiiFlags>> & PersonalAnnotationsNoFind & {
123
123
  required?: R;
@@ -125,8 +125,9 @@ export declare function createTimestampField<R extends true | false = false>(ove
125
125
  required: R;
126
126
  };
127
127
  /**
128
- * IANA-Zonenname (z.B. "Europe/Berlin"). Wird im Boot/Schema-Validator
129
- * via `Intl.supportedValuesOf("timeZone")` geprüft (kommt im Zod-Schritt).
128
+ * IANA time-zone name (for example, "Europe/Berlin"). The boot/schema
129
+ * validator checks it using `Intl.supportedValuesOf("timeZone")` during the
130
+ * Zod step.
130
131
  */
131
132
  export declare function createTzField<R extends true | false = false>(overrides?: Partial<Omit<TzFieldDef, "type" | "required" | keyof ResolvedPiiFlags>> & PersonalAnnotationsNoFind & {
132
133
  required?: R;