@cosmicdrift/kumiko-framework 1.0.0 → 2.0.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 (424) hide show
  1. package/README.md +9 -38
  2. package/package.json +21 -2
  3. package/src/__tests__/anonymous-access.integration.test.ts +185 -0
  4. package/src/__tests__/consumer-cli.integration.test.ts +172 -0
  5. package/src/__tests__/entity-permalink-open.integration.test.ts +94 -0
  6. package/src/__tests__/full-stack.integration.test.ts +1 -1
  7. package/src/__tests__/schema-cli-temporal-polyfill.test.ts +48 -0
  8. package/src/__tests__/schema-cli.integration.test.ts +50 -0
  9. package/src/__tests__/store-table.integration.test.ts +93 -0
  10. package/src/api/__tests__/api.test.ts +373 -0
  11. package/src/api/__tests__/auth-middleware-anonymous-access-boot.test.ts +40 -0
  12. package/src/api/__tests__/auth-routes-cookie.test.ts +17 -1
  13. package/src/api/__tests__/auth-routes-invalid-body-invite.test.ts +253 -0
  14. package/src/api/__tests__/auth-routes-mfa-preauth-confirm.test.ts +222 -0
  15. package/src/api/__tests__/auth-routes-mfa-preauth-enable-start.test.ts +249 -0
  16. package/src/api/__tests__/auth-routes-mfa-verify.test.ts +202 -0
  17. package/src/api/__tests__/auth-routes-trusted-proxy.test.ts +135 -0
  18. package/src/api/__tests__/batch.integration.test.ts +101 -11
  19. package/src/api/__tests__/csrf-constants-sync.test.ts +20 -0
  20. package/src/api/__tests__/dispatcher-live.integration.test.ts +74 -0
  21. package/src/api/__tests__/jwt.test.ts +200 -1
  22. package/src/api/__tests__/login-rate-limiter-sweep.test.ts +50 -0
  23. package/src/api/__tests__/pat-scope.test.ts +36 -0
  24. package/src/api/__tests__/pii-leak-guard.integration.test.ts +103 -0
  25. package/src/api/__tests__/redis-login-rate-limiter.integration.test.ts +138 -0
  26. package/src/api/__tests__/request-id-middleware.test.ts +51 -0
  27. package/src/api/__tests__/server-boot-guards.test.ts +71 -0
  28. package/src/api/__tests__/server-jwt-ttl.test.ts +58 -0
  29. package/src/api/__tests__/sse-broker.test.ts +57 -0
  30. package/src/api/__tests__/sse-route.test.ts +4 -0
  31. package/src/api/api-constants.ts +11 -0
  32. package/src/api/auth-middleware.ts +248 -40
  33. package/src/api/auth-routes.ts +576 -95
  34. package/src/api/index.ts +13 -4
  35. package/src/api/jwt.ts +170 -11
  36. package/src/api/pat-scope.ts +14 -0
  37. package/src/api/pii-leak-guard.ts +47 -0
  38. package/src/api/request-context.ts +3 -0
  39. package/src/api/request-id-middleware.ts +2 -0
  40. package/src/api/routes.ts +169 -2
  41. package/src/api/server.ts +112 -16
  42. package/src/api/sse-broker.ts +39 -0
  43. package/src/bun-db/__tests__/PATTERN.md +0 -1
  44. package/src/bun-db/__tests__/coerce-row-temporal.test.ts +41 -0
  45. package/src/bun-db/__tests__/select-many-retry.test.ts +79 -0
  46. package/src/bun-db/__tests__/write-brand.test.ts +21 -0
  47. package/src/bun-db/connection.ts +3 -3
  48. package/src/bun-db/index.ts +2 -0
  49. package/src/bun-db/query.ts +105 -32
  50. package/src/consumer-cli.ts +134 -0
  51. package/src/crypto/__tests__/blind-index.test.ts +130 -0
  52. package/src/crypto/__tests__/event-pii.test.ts +161 -0
  53. package/src/crypto/__tests__/kek-rotation.integration.test.ts +180 -0
  54. package/src/crypto/__tests__/kms-adapter-contract.ts +134 -0
  55. package/src/crypto/__tests__/kms-adapter.contract.test.ts +4 -0
  56. package/src/crypto/__tests__/pg-kms-adapter.integration.test.ts +117 -0
  57. package/src/crypto/__tests__/pii-field-encryption.test.ts +376 -0
  58. package/src/crypto/__tests__/request-kms-cache.test.ts +74 -0
  59. package/src/crypto/__tests__/subject-resolver.test.ts +108 -0
  60. package/src/crypto/blind-index.ts +118 -0
  61. package/src/crypto/event-pii.ts +70 -0
  62. package/src/crypto/in-memory-kms-adapter.ts +50 -0
  63. package/src/crypto/index.ts +67 -0
  64. package/src/crypto/kms-adapter.ts +2 -0
  65. package/src/crypto/pg-kms-adapter.ts +295 -0
  66. package/src/crypto/pii-field-encryption.ts +248 -0
  67. package/src/crypto/request-kms-cache.ts +38 -0
  68. package/src/crypto/subject-resolver.ts +91 -0
  69. package/src/db/__tests__/assert-no-unreachable-live-rows.integration.test.ts +191 -0
  70. package/src/db/__tests__/blind-index.integration.test.ts +248 -0
  71. package/src/db/__tests__/build-filter-where.test.ts +34 -0
  72. package/src/db/__tests__/collect-table-metas.test.ts +10 -10
  73. package/src/db/__tests__/config-seed.integration.test.ts +13 -5
  74. package/src/db/__tests__/dialect-instant.test.ts +1 -4
  75. package/src/db/__tests__/entity-field-encryption.test.ts +7 -7
  76. package/src/db/__tests__/entity-table-meta-source.test.ts +50 -0
  77. package/src/db/__tests__/event-store-executor-context.pii-roundtrip.test.ts +67 -0
  78. package/src/db/__tests__/event-store-executor-write-verbs.integration.test.ts +402 -0
  79. package/src/db/__tests__/event-store-executor.integration.test.ts +299 -29
  80. package/src/db/__tests__/feature-table-sources.test.ts +34 -0
  81. package/src/db/__tests__/implicit-projection-equivalence.integration.test.ts +118 -39
  82. package/src/db/__tests__/instant-to-driver-temporal.test.ts +21 -0
  83. package/src/db/__tests__/located-timestamp.test.ts +19 -0
  84. package/src/db/__tests__/migrate-generator.test.ts +21 -0
  85. package/src/db/__tests__/migrate-runner.test.ts +61 -0
  86. package/src/db/__tests__/number-field-fractional.integration.test.ts +58 -0
  87. package/src/db/__tests__/rebuild-marker.test.ts +13 -3
  88. package/src/db/__tests__/replay-migration-sql.test.ts +384 -0
  89. package/src/db/__tests__/schema-inspection.test.ts +7 -0
  90. package/src/db/__tests__/schema-migration.integration.test.ts +1 -1
  91. package/src/db/__tests__/table-builder-meta-lockstep.test.ts +39 -0
  92. package/src/db/__tests__/tenant-db-where-merge.test.ts +49 -3
  93. package/src/db/__tests__/tenant-db.integration.test.ts +6 -2
  94. package/src/db/api.ts +2 -2
  95. package/src/db/apply-entity-event.ts +18 -14
  96. package/src/db/blind-index-cleanup.ts +55 -0
  97. package/src/db/bun-provider.ts +2 -2
  98. package/src/db/collect-table-metas.ts +6 -7
  99. package/src/db/config-seed.ts +9 -9
  100. package/src/db/connection.ts +7 -12
  101. package/src/db/cursor.ts +1 -18
  102. package/src/db/dialect.ts +20 -26
  103. package/src/db/entity-field-encryption.ts +81 -24
  104. package/src/db/entity-table-meta-types.ts +2 -0
  105. package/src/db/entity-table-meta.ts +63 -90
  106. package/src/db/event-store-executor-context.ts +404 -0
  107. package/src/db/event-store-executor-read.ts +275 -0
  108. package/src/db/event-store-executor-write.ts +644 -0
  109. package/src/db/event-store-executor.ts +28 -1155
  110. package/src/db/feature-table-sources.ts +6 -5
  111. package/src/db/index.ts +20 -3
  112. package/src/db/located-timestamp.ts +4 -0
  113. package/src/db/migrate-generator.ts +39 -6
  114. package/src/db/migrate-runner.ts +107 -11
  115. package/src/db/pg-error.ts +9 -1
  116. package/src/db/postgres-provider.ts +2 -2
  117. package/src/db/queries/__tests__/event-store-idempotency-index.integration.test.ts +80 -0
  118. package/src/db/queries/backfill-pii.ts +277 -0
  119. package/src/db/queries/ddl.ts +45 -0
  120. package/src/db/queries/event-consumer.ts +35 -2
  121. package/src/db/queries/event-store.ts +126 -19
  122. package/src/db/queries/projection-rebuild.ts +22 -8
  123. package/src/db/queries/shadow-swap.ts +183 -0
  124. package/src/db/queries/test-stack.ts +4 -30
  125. package/src/db/query-api.ts +1 -0
  126. package/src/db/query.ts +1 -0
  127. package/src/db/rebuild-marker.ts +18 -2
  128. package/src/db/reference-data.ts +2 -3
  129. package/src/db/replay-migration-sql.ts +257 -0
  130. package/src/db/schema-inspection.ts +1 -1
  131. package/src/db/table-builder.ts +102 -71
  132. package/src/db/tenant-db.ts +15 -53
  133. package/src/engine/__tests__/boot-validator-action-wiring.test.ts +242 -0
  134. package/src/engine/__tests__/boot-validator-boot-check.test.ts +99 -0
  135. package/src/engine/__tests__/boot-validator-dashboard.test.ts +237 -0
  136. package/src/engine/__tests__/boot-validator-entity-list.test.ts +104 -0
  137. package/src/engine/__tests__/boot-validator-gdpr-storage.test.ts +7 -69
  138. package/src/engine/__tests__/boot-validator-i18n-keys.test.ts +26 -5
  139. package/src/engine/__tests__/boot-validator-located-timestamps.test.ts +3 -19
  140. package/src/engine/__tests__/boot-validator-pii-retention.test.ts +246 -4
  141. package/src/engine/__tests__/boot-validator.test.ts +219 -15
  142. package/src/engine/__tests__/build-app-schema.test.ts +82 -0
  143. package/src/engine/__tests__/build-config-feature-schema.test.ts +125 -0
  144. package/src/engine/__tests__/build-target.test.ts +3 -11
  145. package/src/engine/__tests__/codemod-pipeline.test.ts +152 -21
  146. package/src/engine/__tests__/config-helpers.test.ts +16 -0
  147. package/src/engine/__tests__/define-feature-entity-mapping.test.ts +6 -0
  148. package/src/engine/__tests__/define-roles.test.ts +21 -0
  149. package/src/engine/__tests__/engine.test.ts +163 -1
  150. package/src/engine/__tests__/entity-handlers.test.ts +80 -0
  151. package/src/engine/__tests__/event-migration-declarative.test.ts +65 -0
  152. package/src/engine/__tests__/event-type-map-augmentation.test.ts +24 -0
  153. package/src/engine/__tests__/extend-entity-projection.test.ts +123 -0
  154. package/src/engine/__tests__/factories-time.test.ts +2 -66
  155. package/src/engine/__tests__/feature-crud-shorthand.test.ts +28 -0
  156. package/src/engine/__tests__/feature-manifest.test.ts +31 -1
  157. package/src/engine/__tests__/field-access.test.ts +23 -1
  158. package/src/engine/__tests__/hook-phases.test.ts +5 -5
  159. package/src/engine/__tests__/membership-roles.test.ts +4 -10
  160. package/src/engine/__tests__/nav.test.ts +86 -1
  161. package/src/engine/__tests__/pipeline-engine.test.ts +9 -9
  162. package/src/engine/__tests__/pipeline-handler.integration.test.ts +18 -18
  163. package/src/engine/__tests__/pipeline-observability.integration.test.ts +2 -2
  164. package/src/engine/__tests__/pipeline-performance.integration.test.ts +3 -3
  165. package/src/engine/__tests__/pipeline-sub-pipelines.test.ts +9 -9
  166. package/src/engine/__tests__/post-query-hook.test.ts +7 -7
  167. package/src/engine/__tests__/registrar-object-form.test.ts +141 -0
  168. package/src/engine/__tests__/registry.test.ts +144 -0
  169. package/src/engine/__tests__/schema-builder.test.ts +18 -0
  170. package/src/engine/__tests__/screen.test.ts +147 -1
  171. package/src/engine/__tests__/soft-delete-cleanup.test.ts +3 -0
  172. package/src/engine/__tests__/store-table.test.ts +229 -0
  173. package/src/engine/__tests__/tier-resolver-extension.test.ts +19 -1
  174. package/src/engine/__tests__/{visual-tree-patterns.test.ts → tree-actions-patterns.test.ts} +7 -95
  175. package/src/engine/__tests__/validate-projection-allowlist.test.ts +15 -15
  176. package/src/engine/boot-validator/__tests__/config-deps.test.ts +92 -0
  177. package/src/engine/boot-validator/action-wiring.ts +149 -0
  178. package/src/engine/boot-validator/boot-check.ts +21 -0
  179. package/src/engine/boot-validator/config-deps.ts +40 -4
  180. package/src/engine/boot-validator/entity-handler.ts +20 -21
  181. package/src/engine/boot-validator/entity-list-screens.ts +88 -0
  182. package/src/engine/boot-validator/gdpr-storage.ts +0 -20
  183. package/src/engine/boot-validator/i18n-keys.ts +58 -4
  184. package/src/engine/boot-validator/index.ts +33 -12
  185. package/src/engine/boot-validator/nav.ts +125 -0
  186. package/src/engine/boot-validator/pii-retention.ts +95 -10
  187. package/src/engine/boot-validator/{screens-nav.ts → screens.ts} +214 -191
  188. package/src/engine/boot-validator/workspaces.ts +68 -0
  189. package/src/engine/build-app-schema.ts +16 -0
  190. package/src/engine/build-config-feature-schema.ts +44 -7
  191. package/src/engine/codemod/pipeline-codemod.ts +5 -5
  192. package/src/engine/config-helpers.ts +15 -0
  193. package/src/engine/constants.ts +32 -6
  194. package/src/engine/create-app.ts +11 -0
  195. package/src/engine/define-feature.ts +95 -947
  196. package/src/engine/define-handler.ts +28 -94
  197. package/src/engine/define-workflow.ts +1 -1
  198. package/src/engine/effective-features.ts +12 -2
  199. package/src/engine/entity-handlers.ts +76 -11
  200. package/src/engine/extensions/tenant-data.ts +19 -0
  201. package/src/engine/extensions/user-data.ts +29 -2
  202. package/src/engine/factories.ts +8 -49
  203. package/src/engine/feature-ast/__tests__/canonical-form.test.ts +26 -29
  204. package/src/engine/feature-ast/__tests__/fixtures/cross-file-registrar/feature.ts +9 -0
  205. package/src/engine/feature-ast/__tests__/fixtures/cross-file-registrar/screens.ts +4 -0
  206. package/src/engine/feature-ast/__tests__/parse-happy-path.test.ts +1 -2
  207. package/src/engine/feature-ast/__tests__/parse-real-features.test.ts +18 -8
  208. package/src/engine/feature-ast/__tests__/parse.test.ts +1640 -160
  209. package/src/engine/feature-ast/__tests__/patch.test.ts +206 -12
  210. package/src/engine/feature-ast/__tests__/patcher.test.ts +20 -23
  211. package/src/engine/feature-ast/__tests__/render-roundtrip.test.ts +380 -5
  212. package/src/engine/feature-ast/extractors/events.ts +322 -0
  213. package/src/engine/feature-ast/extractors/handlers.ts +234 -0
  214. package/src/engine/feature-ast/extractors/hooks.ts +243 -0
  215. package/src/engine/feature-ast/extractors/index.ts +34 -31
  216. package/src/engine/feature-ast/extractors/jobs-routes.ts +221 -0
  217. package/src/engine/feature-ast/extractors/projections-screens.ts +269 -0
  218. package/src/engine/feature-ast/extractors/round1.ts +3 -3
  219. package/src/engine/feature-ast/extractors/round5.ts +3 -3
  220. package/src/engine/feature-ast/extractors/round6.ts +2 -36
  221. package/src/engine/feature-ast/extractors/shared.ts +64 -6
  222. package/src/engine/feature-ast/index.ts +2 -4
  223. package/src/engine/feature-ast/parse.ts +130 -23
  224. package/src/engine/feature-ast/patch.ts +39 -50
  225. package/src/engine/feature-ast/patcher.ts +37 -38
  226. package/src/engine/feature-ast/patterns.ts +50 -62
  227. package/src/engine/feature-ast/render.ts +67 -44
  228. package/src/engine/feature-builder-state.ts +168 -0
  229. package/src/engine/feature-config-events-jobs.ts +403 -0
  230. package/src/engine/feature-entity-handlers.ts +208 -0
  231. package/src/engine/feature-manifest.ts +2 -1
  232. package/src/engine/feature-ui-extensions.ts +500 -0
  233. package/src/engine/field-access.ts +13 -2
  234. package/src/engine/field-helpers.ts +31 -0
  235. package/src/engine/handler-helpers.ts +26 -0
  236. package/src/engine/hook-helpers.ts +16 -0
  237. package/src/engine/index.ts +23 -7
  238. package/src/engine/membership-roles.ts +13 -0
  239. package/src/engine/object-form.ts +27 -0
  240. package/src/engine/ownership.ts +26 -79
  241. package/src/engine/pattern-library/__tests__/library.test.ts +7 -20
  242. package/src/engine/pattern-library/library.ts +44 -1152
  243. package/src/engine/pattern-library/mixed-schemas.ts +450 -0
  244. package/src/engine/pattern-library/opaque-schemas.ts +124 -0
  245. package/src/engine/pattern-library/shared-fields.ts +75 -0
  246. package/src/engine/pattern-library/static-schemas.ts +456 -0
  247. package/src/engine/pipeline.ts +6 -11
  248. package/src/engine/registry-facade.ts +362 -0
  249. package/src/engine/registry-ingest.ts +478 -0
  250. package/src/engine/registry-state.ts +388 -0
  251. package/src/engine/registry-validate.ts +642 -0
  252. package/src/engine/registry.ts +78 -1658
  253. package/src/engine/run-pipeline.ts +1 -1
  254. package/src/engine/schema-builder.ts +1 -0
  255. package/src/engine/screen-helpers.ts +54 -0
  256. package/src/engine/soft-delete-cleanup.ts +6 -2
  257. package/src/engine/steps/__tests__/duration-utils.test.ts +20 -0
  258. package/src/engine/steps/_duration-utils.ts +2 -0
  259. package/src/engine/steps/unsafe-projection-upsert.ts +1 -4
  260. package/src/engine/tier-resolver-extension.ts +3 -2
  261. package/src/engine/types/config.ts +2 -482
  262. package/src/engine/types/define-handler.ts +2 -0
  263. package/src/engine/types/entity-handlers.ts +2 -0
  264. package/src/engine/types/event-type-map.ts +1 -37
  265. package/src/engine/types/feature.ts +2 -972
  266. package/src/engine/types/fields.ts +2 -675
  267. package/src/engine/types/handlers.ts +2 -774
  268. package/src/engine/types/hooks.ts +2 -184
  269. package/src/engine/types/http-route.ts +1 -54
  270. package/src/engine/types/identifiers.ts +1 -47
  271. package/src/engine/types/index.ts +86 -40
  272. package/src/engine/types/nav.ts +2 -63
  273. package/src/engine/types/ownership.ts +2 -0
  274. package/src/engine/types/projection.ts +2 -138
  275. package/src/engine/types/relations.ts +1 -51
  276. package/src/engine/types/screen.ts +2 -574
  277. package/src/engine/types/step.ts +2 -334
  278. package/src/engine/types/target-ref.ts +1 -21
  279. package/src/engine/types/tree-node.ts +1 -132
  280. package/src/engine/types/workspace.ts +2 -49
  281. package/src/engine/validate-projection-allowlist.ts +6 -6
  282. package/src/entrypoint/__tests__/entrypoint-job-wiring.integration.test.ts +120 -1
  283. package/src/entrypoint/index.ts +49 -6
  284. package/src/errors/classes.ts +22 -1
  285. package/src/errors/field-issue.ts +0 -3
  286. package/src/errors/index.ts +1 -1
  287. package/src/errors/write-error-info.ts +10 -22
  288. package/src/es-ops/README.md +1 -1
  289. package/src/es-ops/__tests__/runner.integration.test.ts +74 -0
  290. package/src/es-ops/context.ts +4 -2
  291. package/src/es-ops/types.ts +8 -1
  292. package/src/event-store/__tests__/admin-api.integration.test.ts +27 -1
  293. package/src/event-store/__tests__/backfill-pii.integration.test.ts +279 -0
  294. package/src/event-store/__tests__/event-store.integration.test.ts +201 -0
  295. package/src/event-store/__tests__/row-to-stored-event.test.ts +2 -2
  296. package/src/event-store/__tests__/snapshot.integration.test.ts +86 -0
  297. package/src/event-store/__tests__/unscoped-stream-primitives.guard.test.ts +58 -0
  298. package/src/event-store/__tests__/upcaster.integration.test.ts +77 -45
  299. package/src/event-store/admin-api.ts +11 -4
  300. package/src/event-store/errors.ts +2 -35
  301. package/src/event-store/event-store.ts +64 -78
  302. package/src/event-store/events-schema.ts +11 -13
  303. package/src/event-store/index.ts +18 -3
  304. package/src/event-store/rebuild-dead-letter.ts +111 -0
  305. package/src/event-store/snapshot.ts +63 -40
  306. package/src/event-store/types.ts +2 -0
  307. package/src/files/__tests__/build-storage-key.test.ts +28 -0
  308. package/src/files/__tests__/file-ref-entity.test.ts +8 -0
  309. package/src/files/__tests__/files.integration.test.ts +24 -0
  310. package/src/files/__tests__/in-memory-provider.contract.test.ts +4 -0
  311. package/src/files/__tests__/local-provider.test.ts +31 -0
  312. package/src/files/__tests__/provider-resolver.test.ts +70 -0
  313. package/src/files/__tests__/write-stream.test.ts +13 -0
  314. package/src/files/file-handle.ts +2 -19
  315. package/src/files/file-ref-entity.ts +2 -2
  316. package/src/files/file-routes.ts +13 -0
  317. package/src/files/index.ts +1 -1
  318. package/src/files/local-provider.ts +27 -8
  319. package/src/files/provider-resolver.ts +31 -20
  320. package/src/files/types.ts +13 -55
  321. package/src/i18n/__tests__/required-surface-keys.test.ts +17 -0
  322. package/src/i18n/required-surface-keys.ts +120 -1
  323. package/src/jobs/__tests__/job-queue-depth.integration.test.ts +82 -0
  324. package/src/jobs/__tests__/jobs.integration.test.ts +329 -3
  325. package/src/jobs/job-runner.ts +82 -12
  326. package/src/logging/types.ts +1 -7
  327. package/src/migrations/pending-rebuilds.ts +1 -1
  328. package/src/observability/__tests__/observability.integration.test.ts +4 -1
  329. package/src/observability/__tests__/recording-tracer.test.ts +6 -4
  330. package/src/observability/index.ts +2 -0
  331. package/src/observability/noop-provider.ts +0 -9
  332. package/src/observability/recording-tracer.ts +0 -12
  333. package/src/observability/standard-metrics.ts +64 -2
  334. package/src/observability/types/index.ts +1 -29
  335. package/src/observability/types/metric.ts +1 -56
  336. package/src/observability/types/provider.ts +1 -32
  337. package/src/observability/types/span.ts +1 -64
  338. package/src/pipeline/__tests__/ctx-bridge.integration.test.ts +2 -2
  339. package/src/pipeline/__tests__/dispatcher.test.ts +366 -1
  340. package/src/pipeline/__tests__/event-consumer-state.integration.test.ts +31 -0
  341. package/src/pipeline/__tests__/event-dispatcher-delivery-max-attempts.test.ts +126 -0
  342. package/src/pipeline/__tests__/event-dispatcher-rearm.integration.test.ts +263 -0
  343. package/src/pipeline/__tests__/event-dispatcher.integration.test.ts +10 -0
  344. package/src/pipeline/__tests__/job-trigger-consumer.integration.test.ts +106 -0
  345. package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +308 -77
  346. package/src/pipeline/__tests__/load-aggregate-query.integration.test.ts +16 -8
  347. package/src/pipeline/__tests__/post-query-hook.integration.test.ts +3 -3
  348. package/src/pipeline/__tests__/projection-rebuild.integration.test.ts +80 -2
  349. package/src/pipeline/__tests__/rebuild-poison-quarantine.integration.test.ts +274 -0
  350. package/src/pipeline/__tests__/try-append-event.integration.test.ts +166 -0
  351. package/src/pipeline/dispatch-batch.ts +187 -0
  352. package/src/pipeline/dispatch-query.ts +165 -0
  353. package/src/pipeline/dispatch-shared.ts +826 -0
  354. package/src/pipeline/dispatch-stream.ts +90 -0
  355. package/src/pipeline/dispatch-write.ts +451 -0
  356. package/src/pipeline/dispatcher-utils.ts +1 -1
  357. package/src/pipeline/dispatcher.ts +44 -1372
  358. package/src/pipeline/entity-cache.ts +2 -33
  359. package/src/pipeline/event-consumer-state.ts +30 -2
  360. package/src/pipeline/event-dispatcher-admin.ts +293 -0
  361. package/src/pipeline/event-dispatcher-delivery.ts +305 -0
  362. package/src/pipeline/event-dispatcher.ts +85 -542
  363. package/src/pipeline/index.ts +2 -0
  364. package/src/pipeline/msp-rebuild.ts +42 -3
  365. package/src/pipeline/multi-stream-apply-context.ts +4 -42
  366. package/src/pipeline/projection-rebuild.ts +105 -3
  367. package/src/pipeline/system-hooks.ts +144 -1
  368. package/src/rate-limit/__tests__/resolver.integration.test.ts +18 -0
  369. package/src/rate-limit/resolver.ts +16 -32
  370. package/src/schema-cli.ts +76 -16
  371. package/src/search/__tests__/meilisearch-adapter.integration.test.ts +207 -185
  372. package/src/search/__tests__/meilisearch-ids.test.ts +30 -0
  373. package/src/search/__tests__/reindex-entity.integration.test.ts +144 -0
  374. package/src/search/index.ts +6 -0
  375. package/src/search/meilisearch-adapter.ts +13 -12
  376. package/src/search/reindex-entity.ts +177 -0
  377. package/src/search/types.ts +1 -39
  378. package/src/secrets/__tests__/contains-secret.test.ts +34 -0
  379. package/src/secrets/__tests__/envelope-cipher.test.ts +59 -0
  380. package/src/secrets/__tests__/envelope.test.ts +1 -1
  381. package/src/secrets/dek-cache.ts +26 -5
  382. package/src/secrets/envelope-cipher.ts +53 -0
  383. package/src/secrets/envelope.ts +5 -3
  384. package/src/secrets/index.ts +13 -1
  385. package/src/secrets/stored-envelope.ts +46 -0
  386. package/src/secrets/types.ts +2 -162
  387. package/src/stack/__tests__/event-collector.test.ts +42 -0
  388. package/src/stack/__tests__/setup-test-stack-jobs.integration.test.ts +125 -0
  389. package/src/stack/db.ts +2 -1
  390. package/src/stack/push-entity-projection-tables.ts +4 -3
  391. package/src/stack/redis.ts +8 -0
  392. package/src/stack/request-helper.ts +38 -2
  393. package/src/stack/table-helpers.ts +6 -4
  394. package/src/stack/test-stack.ts +249 -131
  395. package/src/testing/__tests__/late-bound.test.ts +32 -0
  396. package/src/testing/__tests__/wait-for.test.ts +59 -0
  397. package/src/testing/boot-validator-fixture.ts +121 -0
  398. package/src/testing/e2e-generator.ts +8 -0
  399. package/src/testing/file-provider-contract.ts +104 -0
  400. package/src/testing/handler-context.ts +3 -1
  401. package/src/testing/index.ts +5 -0
  402. package/src/testing/late-bound.ts +5 -3
  403. package/src/testing/mutable-master-key-provider.ts +29 -3
  404. package/src/testing/wait-for.ts +3 -0
  405. package/src/testing/without-ambient-temporal.ts +14 -0
  406. package/src/time/__tests__/tz-dateline.test.ts +8 -10
  407. package/src/time/geo-tz.ts +1 -32
  408. package/src/time/index.ts +1 -0
  409. package/src/time/legacy-date.ts +18 -0
  410. package/src/time/polyfill.ts +21 -38
  411. package/src/time/tz-context.ts +44 -85
  412. package/src/ui-types/app-schema.ts +12 -0
  413. package/src/ui-types/index.ts +20 -7
  414. package/src/utils/__tests__/safe-json-temporal.test.ts +18 -0
  415. package/src/utils/safe-json.ts +13 -1
  416. package/src/__tests__/raw-table.integration.test.ts +0 -116
  417. package/src/bun-db/__tests__/bun-test-stack.ts +0 -6
  418. package/src/db/__tests__/encryption.test.ts +0 -39
  419. package/src/db/encryption.ts +0 -39
  420. package/src/db/row-helpers.ts +0 -4
  421. package/src/engine/__tests__/raw-table.test.ts +0 -150
  422. package/src/engine/__tests__/unmanaged-table.test.ts +0 -127
  423. package/src/engine/feature-ast/__tests__/visual-tree-parse.test.ts +0 -184
  424. package/src/engine/feature-ast/extractors/round4.ts +0 -1366
@@ -1,334 +1,2 @@
1
- // Step-Vocabulary Typessee docs/plans/architecture/intern/step-vocabulary.md
2
- //
3
- // M.1 minimal scope:
4
- // - Steps execute against the existing HandlerContext (no per-step subset).
5
- // - steps-accumulator is Record<string, unknown> (no tuple-reduce typing).
6
- // - Resolvers receive the full PipelineCtx as one argument.
7
- //
8
- // Strict typing on appendEvent inside steps is deferred to a later pass
9
- // (see TS-typing notes in the design doc). M.1 uses unsafeAppendEvent
10
- // semantics under the hood for r.step.aggregate.appendEvent.
11
-
12
- import type { EventStoreExecutor } from "../../db/event-store-executor";
13
- import type { WhereObject } from "../../db/query";
14
- import type { KumikoEventTypeMap } from "./event-type-map";
15
- import type { HandlerContext, WriteEvent, WriteResult } from "./handlers";
16
- import type { SaveContext } from "./hooks";
17
- import type { EntityId } from "./identifiers";
18
-
19
- /**
20
- * The kind discriminator for a step instance — matches the step's
21
- * registration name in the step-registry (e.g. "return", "compute",
22
- * "aggregate.create"). Steps register themselves at module-load time
23
- * via defineStep().
24
- */
25
- export type StepKind = string;
26
-
27
- /**
28
- * Pipeline-side context handed to step argument resolvers.
29
- *
30
- * Contains the full HandlerContext (no per-step subset in M.1) plus
31
- * the accumulated `steps` map of prior step results, and a `scope`
32
- * record for forEach/branch-local bindings.
33
- *
34
- * `scope` is `Record<string, unknown>` — sub-step builders (forEach,
35
- * branch) populate it once they land in later M.1 slices. M.1.1 ships
36
- * with `r.step.return` only, which reads `event` and ignores both
37
- * `steps` and `scope`.
38
- */
39
- export type PipelineCtx<
40
- TPayload = unknown,
41
- TMap extends object = KumikoEventTypeMap,
42
- > = HandlerContext<TMap> & {
43
- readonly event: WriteEvent<TPayload>;
44
- readonly steps: Readonly<Record<string, unknown>>;
45
- readonly scope: Readonly<Record<string, unknown>>;
46
- // Workflow-run context — present only when running inside defineWorkflow.
47
- // Tier-3 steps use this to write suspension events onto the correct
48
- // aggregate stream and for the Resume-Loop to re-hydrate state.
49
- readonly workflow?: {
50
- readonly runId: string;
51
- readonly workflowName: string;
52
- /** Current step index in the pipeline — set by the executor before each step. */
53
- readonly stepIndex: number;
54
- /**
55
- * Retry attempt counter for the current workflow.retry step.
56
- * Set by the workflow-engine resume-loop on re-entry; starts at 1.
57
- * Absent (undefined) means first attempt.
58
- */
59
- readonly retryAttempt?: number;
60
- /**
61
- * Q7 Snapshot-at-Start fingerprint of the workflow definition that
62
- * started this run. Propagated into every suspension event payload so
63
- * the resume-loop can detect library-upgrades that changed the closure
64
- * source and surface them as a typed failure instead of running a
65
- * stale-vs-new mix of steps. Optional only for legacy callers; the
66
- * workflow-runner sets it on every newly-started run.
67
- */
68
- readonly definitionFingerprint?: string;
69
- };
70
- };
71
-
72
- /**
73
- * A resolver is either a static value or a function that derives the
74
- * value from the pipeline-context. M.1 keeps the resolver signature
75
- * uniform — every step accepts both forms via a normalise helper.
76
- */
77
- export type StepResolver<T, TPayload = unknown> = T | ((ctx: PipelineCtx<TPayload>) => T);
78
-
79
- /**
80
- * Per-step error strategy. M.1.1 only supports "throw" — the type is
81
- * deliberately narrowed so callers cannot pass an unsupported strategy
82
- * past the type-checker. The doc lists "return" / "skip" / fallback as
83
- * future strategies; each lands together with its own runtime support
84
- * + integration test in a later slice (no untested type expansion).
85
- */
86
- export type StepFailureStrategy = "throw";
87
-
88
- export type StepDef<TArgs = unknown, TResult = unknown> = {
89
- readonly kind: StepKind;
90
- readonly defaultFailureStrategy: StepFailureStrategy;
91
- // Returns the result-key for this step instance, or undefined when the
92
- // step doesn't surface a result. The first-position name on the call
93
- // (e.g. r.step.compute("startedAt", fn) → "startedAt") becomes the key.
94
- readonly resultKey?: (args: TArgs) => string | undefined;
95
- // Sub-pipeline arg-paths — names of `args.<path>` entries that hold a
96
- // readonly StepInstance[] (e.g. branch's `["onTrue", "onFalse"]`, forEach's
97
- // `["do"]`). The boot-validator reads these at registration time so it
98
- // can recurse into nested pipelines without a hardcoded kind-list. Steps
99
- // that don't carry sub-pipelines omit the field. Followup #15 self-
100
- // registration: prevents future sub-step-builders from silently bypassing
101
- // the unsafeProjection allowlist by forgetting to update a central map.
102
- readonly subPaths?: readonly string[];
103
- // Step-vocabulary tier (Q9). Tier-1 implicit, Tier-2+ requires
104
- // r.requires.step("<kind>") in the owning feature. Default 1 (implicit).
105
- // Tier-3 is only available inside defineWorkflow.
106
- readonly tier?: 1 | 2 | 3;
107
- // Runtime: resolve the args against the ctx, perform the work, return
108
- // the value to land in steps.{resultKey}. Thrown errors propagate to
109
- // the dispatcher's catch (M.1.1 supports "throw"-strategy only).
110
- readonly run: (args: TArgs, ctx: PipelineCtx) => Promise<TResult> | TResult;
111
- };
112
-
113
- /**
114
- * An instance of a step in a pipeline — what users build via the
115
- * step-builder (`r.step.compute(...)`). Carries the kind + resolved-or-
116
- * resolver args + the user-chosen onFailure override.
117
- *
118
- * `args` is `unknown` at this layer — the registered StepDef knows the
119
- * concrete shape and casts at run() time. Cross-step type-safety lives
120
- * in the per-step builder factories, not in this central type.
121
- */
122
- export type StepInstance = {
123
- readonly kind: StepKind;
124
- readonly args: unknown;
125
- readonly onFailure?: StepFailureStrategy;
126
- };
127
-
128
- /**
129
- * What `pipeline(closure)` returns. Carries the closure (instead of an
130
- * eagerly-built array) so each handler-call sees a fresh event ref and
131
- * the `r` step-builder is resolved at runtime, not at module-load time.
132
- *
133
- * `__kind: "pipeline"` lets defineWriteHandler distinguish a pipeline-
134
- * form `perform` from accidental other shapes.
135
- *
136
- * `_TData` is a phantom type-parameter — held in constraint position
137
- * only, never referenced in the type body. defineWriteHandler binds it
138
- * via `def.perform: PipelineDef<…, TData>` (the call-site uses TData
139
- * without underscore — phantom-prefix is purely a Biome
140
- * `noUnusedVariables` marker, not user-facing). _TData is NOT inferred
141
- * from the closure body (r.step.return has its own per-call TData), so
142
- * callers must spell it explicitly:
143
- * `pipeline<{ greeting: string }, { echoed: string }>(...)`
144
- * Better DX is a known follow-up — see step-vocabulary.md M.1-Followups.
145
- */
146
- export type PipelineDef<TPayload = unknown, _TData = unknown> = {
147
- readonly __kind: "pipeline";
148
- readonly build: (ctx: PipelineBuildCtx<TPayload>) => readonly StepInstance[];
149
- };
150
-
151
- /**
152
- * Argument bundle passed to the closure inside `pipeline(closure)`.
153
- * Build-time only — no `steps`, no `scope`, no `db`: at build time no
154
- * step has run yet.
155
- *
156
- * The closure is invoked ONCE per handler-call and returns the immutable
157
- * list of step instances. Values inside the closure that depend on prior
158
- * step results MUST go through resolvers (functions) — those receive the
159
- * resolver-side PipelineCtx which carries `steps` + `scope`.
160
- *
161
- * **Closure-body contract:** the closure must produce a deterministic
162
- * step-list that doesn't depend on `event.payload` — branching on payload
163
- * fields belongs inside resolvers (where they fire per-call), not in the
164
- * outer closure body. Boot-validation runs the closure once with a dummy
165
- * empty payload to scan unsafeProjection-* step targets; a closure that
166
- * conditionally builds different step-lists per payload would silently
167
- * skip validation. See validate-projection-allowlist.ts for the
168
- * boot-side mechanics.
169
- */
170
- export type PipelineBuildCtx<TPayload = unknown> = {
171
- readonly event: WriteEvent<TPayload>;
172
- readonly r: StepBuilder;
173
- };
174
-
175
- /**
176
- * Step-builder namespace handed to the pipeline closure. The fields
177
- * grow as M.1 adds more steps. Each is a thin factory that returns a
178
- * StepInstance — the runtime resolution happens later in run().
179
- *
180
- * Why nested under `step`: matches the doc-API surface and leaves room
181
- * for future sibling namespaces (`r.trigger`, `r.transform`) without
182
- * crowding the top-level r.
183
- */
184
- export type StepBuilder = {
185
- readonly step: StepNamespace;
186
- };
187
-
188
- /**
189
- * The collection of step factory functions. Grown incrementally —
190
- * landed: return (M.1.1), compute (M.1.2), unsafeProjectionUpsert
191
- * (M.1.3), aggregate.create (M.1.4). Pending: branch, forEach,
192
- * read.*, aggregate.update, aggregate.appendEvent,
193
- * unsafeProjectionDelete.
194
- */
195
- export type StepNamespace = {
196
- readonly return: <TData>(resolver: StepResolver<WriteResult<TData>>) => StepInstance;
197
- readonly compute: <TResult>(name: string, fn: (ctx: PipelineCtx) => TResult) => StepInstance;
198
- // Inline read-side projection write. Boot-validation enforces the
199
- // table is in the owning feature's r.requires.projection allowlist
200
- // and NOT registered as an aggregate-table via r.entity. See
201
- // step-vocabulary.md "Was unsafeProjection.* überspringt".
202
- readonly unsafeProjectionUpsert: (args: {
203
- readonly table: unknown;
204
- readonly on: readonly string[];
205
- readonly row: StepResolver<Record<string, unknown>>;
206
- }) => StepInstance;
207
- // Sibling: delete row(s) from a read-side projection table. Same
208
- // boot-validation contract as unsafeProjectionUpsert.
209
- readonly unsafeProjectionDelete: (args: {
210
- readonly table: unknown;
211
- readonly where: StepResolver<WhereObject>;
212
- }) => StepInstance;
213
- // Read sub-namespace — thin wrapper on selectMany/fetchOne (bun-db).
214
- // Caller-owned tenant-filter (does NOT auto-inject like ctx.queryProjection does).
215
- readonly read: {
216
- readonly findOne: (
217
- name: string,
218
- opts: {
219
- readonly table: unknown;
220
- readonly where: StepResolver<WhereObject | undefined>;
221
- },
222
- ) => StepInstance;
223
- readonly findMany: (
224
- name: string,
225
- opts: {
226
- readonly table: unknown;
227
- readonly where?: StepResolver<WhereObject | undefined>;
228
- readonly limit?: number;
229
- },
230
- ) => StepInstance;
231
- };
232
- // Aggregate-mutation sub-namespace — wraps the existing event-store-
233
- // executor surface. Every method goes through the full ES pipeline
234
- // (events + projections + lifecycle hooks + audit). The default and
235
- // intended path for domain mutation; contrast with unsafeProjection.*.
236
- readonly aggregate: {
237
- readonly create: (
238
- name: string,
239
- opts: {
240
- readonly executor: EventStoreExecutor;
241
- readonly data: StepResolver<Record<string, unknown>>;
242
- },
243
- ) => StepInstance;
244
- readonly update: (
245
- name: string,
246
- opts: {
247
- readonly executor: EventStoreExecutor;
248
- readonly id: StepResolver<EntityId>;
249
- readonly changes: StepResolver<Record<string, unknown>>;
250
- readonly version?: StepResolver<number | undefined>;
251
- readonly skipOptimisticLock?: boolean;
252
- },
253
- ) => StepInstance;
254
- readonly appendEvent: (args: {
255
- readonly aggregateId: StepResolver<string>;
256
- readonly aggregateType: string;
257
- readonly type: string;
258
- readonly payload: StepResolver<unknown>;
259
- readonly headers?: StepResolver<Readonly<Record<string, string | number | boolean>>>;
260
- }) => StepInstance;
261
- };
262
- // Conditional sub-pipeline. `onTrue` (required) and `onFalse`
263
- // (optional) are static StepInstance arrays; `r` for sub-step builders
264
- // is captured from the outer pipeline closure. Naming-Q14: `onTrue`/
265
- // `onFalse` over `then`/`else` because Biome's noThenProperty lint
266
- // flags `then` as a thenable-trap. Q12: r.step.return inside
267
- // onTrue/onFalse is rejected at build time (would trigger
268
- // discriminated-union TData trap). Q13: no resultKey — branch is
269
- // side-effect-only.
270
- readonly branch: (args: {
271
- readonly if: StepResolver<boolean>;
272
- readonly onTrue: readonly StepInstance[];
273
- readonly onFalse?: readonly StepInstance[];
274
- }) => StepInstance;
275
- // Iterate a sub-pipeline over an array. `as` is required (Q15);
276
- // current item lands under `scope[as]` for resolvers in `do`.
277
- // Sequential only in M.1.6; concurrency is Followup #12.
278
- readonly forEach: <TItem = unknown>(args: {
279
- readonly over: StepResolver<readonly TItem[]>;
280
- readonly as: string;
281
- readonly do: readonly StepInstance[];
282
- readonly concurrency?: 1;
283
- }) => StepInstance;
284
- // Tier-2 namespace. Each builder requires r.requires.step("<kind>")
285
- // in the owning feature; boot-validation enforces.
286
- readonly webhook: {
287
- readonly send: (args: {
288
- readonly url: StepResolver<string>;
289
- readonly method?: "POST" | "PUT" | "PATCH";
290
- readonly headers?: StepResolver<Readonly<Record<string, string>>>;
291
- readonly body?: StepResolver<unknown>;
292
- readonly auth?:
293
- | { readonly kind: "bearer"; readonly secretRef: string }
294
- | { readonly kind: "header"; readonly name: string; readonly secretRef: string };
295
- readonly mode: "deferred";
296
- readonly retry?: { readonly times: number; readonly backoff: "exponential" | "linear" };
297
- }) => StepInstance;
298
- };
299
- readonly mail: {
300
- readonly send: (args: {
301
- readonly to: StepResolver<string | readonly string[]>;
302
- readonly subject: StepResolver<string>;
303
- readonly body: StepResolver<string>;
304
- readonly from?: StepResolver<string>;
305
- readonly mode: "deferred";
306
- }) => StepInstance;
307
- };
308
- readonly callFeature: (
309
- name: string,
310
- opts: {
311
- readonly handler: string;
312
- readonly payload: StepResolver<unknown>;
313
- readonly as?: import("./handlers").SessionUser;
314
- },
315
- ) => StepInstance;
316
- // --- Tier-3 / Workflow-only steps ---
317
- // Only available inside defineWorkflow ({ steps: pipeline(...) }).
318
- // Runtime guard: throws when used inside sync defineWriteHandler.
319
- readonly wait: (args: { readonly for: StepResolver<string> }) => StepInstance;
320
- readonly waitForEvent: (args: {
321
- readonly event: string;
322
- readonly match?: StepResolver<(payload: unknown) => boolean>;
323
- readonly timeout: StepResolver<string>;
324
- }) => StepInstance;
325
- readonly retry: (args: {
326
- readonly times: number;
327
- readonly backoff: "exponential" | "linear";
328
- readonly do: readonly StepInstance[];
329
- }) => StepInstance;
330
- };
331
-
332
- // SaveContext is the result-type of aggregate.create / aggregate.update;
333
- // re-exported for step authors who want to type their resolver bindings.
334
- export type AggregateStepResult = SaveContext;
1
+ // Legacy pathre-exported for callers still importing this module directly.
2
+ export type * from "@cosmicdrift/kumiko-types/step";
@@ -1,21 +1 @@
1
- // TargetRef runtime-Repräsentation eines typed buildTarget-Outputs.
2
- // Wird vom Visual-Tree-Component (renderer-web) an einen Target-Resolver
3
- // dispatcht; der Resolver findet die Editor-Maske via featureId.
4
- //
5
- // **Compile-time-Safety:** TargetRef wird niemals hand-getippt. Stattdessen
6
- // erzeugt der typed buildTarget-Builder (engine/build-target.ts) einen
7
- // TargetRef, dessen action + args gegen die treeActions-Map des Ziel-
8
- // Features validiert sind.
9
- //
10
- // **Runtime:** args sind hier untyped (Record<string, unknown>), weil
11
- // TargetRef die erased-runtime-Version ist. Der Resolver kennt das
12
- // Ziel-Feature und kann args entsprechend casten — ähnlich wie Event-
13
- // Payloads im Event-Store.
14
- //
15
- // Siehe docs/plans/architecture/visual-tree.md A5.
16
-
17
- export type TargetRef = {
18
- readonly featureId: string;
19
- readonly action: string;
20
- readonly args?: Readonly<Record<string, unknown>>;
21
- };
1
+ export type * from "@cosmicdrift/kumiko-types/target-ref";
@@ -1,132 +1 @@
1
- // TreeNode single Knoten im Visual-Tree (opt-in Workspace mit
2
- // `navigation: "tree"`). Provider liefern entweder statische
3
- // readonly TreeNode[] oder dynamische TreeChildrenSubscribe.
4
- //
5
- // **Mental-Modell** (VS-Code-Explorer):
6
- // [icon] [label] [...hover-actions]
7
- // optional ein target zum Klicken (öffnet Editor-Maske via
8
- // Target-Resolver) und optional children als nested tree.
9
- //
10
- // **State** markiert Visual-Modus für Skeleton-Pattern:
11
- // - "filled" (default) — schwarz, Knoten hat Inhalt
12
- // - "stub" — hellgrau, existing aber leer (Designer-Stub-File)
13
- // - "empty" — Platzhalter für "+ create"-Affordance
14
- // - "loading" — Children werden gerade aufgelöst
15
- // - "error" — Provider hat Fehler emittiert
16
- // Provider die kein Skeleton-Pattern brauchen müssen state nicht setzen.
17
- //
18
- // **Subscribe-Form** für dynamic Children: Provider erhält emit(),
19
- // gibt unsubscribe() zurück. Initial-Emit synchron oder async, weitere
20
- // Emits beliebig oft (z.B. wenn Entity-Row neu erscheint via SSE).
21
- // Spielt natürlich mit existing SSE-Frame: ein Provider kann intern
22
- // auf Entity-Update-Events abonnieren und bei Änderung emit() aufrufen.
23
- //
24
- // Siehe docs/plans/architecture/visual-tree.md A4.
25
-
26
- import type { TargetRef } from "./target-ref";
27
-
28
- export type TreeNodeState = "filled" | "stub" | "empty" | "loading" | "error";
29
-
30
- export type TreeAction = {
31
- // Icon-Key — vom Renderer-Icon-Registry interpretiert. Konvention
32
- // matched NavDefinition.icon: unbekannte Icons surface als missing-icon
33
- // im UI, nicht als Boot-Failure.
34
- readonly icon: string;
35
- // i18n-Translation-Key oder roher String. Vom Renderer aufgelöst, Engine
36
- // behandelt opak (mirrors NavDefinition.label, WorkspaceDefinition.label).
37
- readonly label: string;
38
- // Klick-Ziel der Action. Pflicht — Action ohne target ist semantisch
39
- // sinnlos (Hover-Icon das nichts tut).
40
- readonly target: TargetRef;
41
- };
42
-
43
- export type TreeNode = {
44
- // i18n-Translation-Key oder roher String. Vom Renderer beim Rendern
45
- // aufgelöst (siehe TreeAction.label).
46
- readonly label: string;
47
- // Optional. Icon links neben dem Label. Selbe Konvention wie
48
- // TreeAction.icon — Renderer-Icon-Registry-Lookup.
49
- readonly icon?: string;
50
- // Visueller State für Skeleton-Pattern. Default "filled" (kein Eintrag
51
- // ⇒ schwarz/normal). Wert-Semantik im Header-Comment dieser Datei.
52
- readonly state?: TreeNodeState;
53
- // Optional Klick-Ziel. Fehlt → reiner Container-Knoten (nur ausklappbar,
54
- // nicht klickbar). Vorhanden → Klick öffnet die Editor-Maske via
55
- // Target-Resolver in renderer-web.
56
- readonly target?: TargetRef;
57
- // Hover-Actions rechts (Add/Refresh/Delete/etc.). Werden in der
58
- // Sidebar-Row erst bei Hover sichtbar — VS-Code-Pattern. Engine
59
- // ordnet die Actions in der Reihenfolge an, in der sie hier stehen.
60
- readonly actions?: readonly TreeAction[];
61
- // Statische Children oder dynamic Subscribe-Function. Subscribe wird
62
- // erst beim Ausklappen aufgerufen (lazy); die Function-Form erlaubt
63
- // SSE-gefütterte Live-Updates wenn neue Entity-Rows reinkommen.
64
- readonly children?: readonly TreeNode[] | TreeChildrenSubscribe;
65
- // Provider-deklarierte „+ create"-Action für Knoten mit `state: "empty"`.
66
- // Tree-Component zeigt automatisch ein „+"-Icon und dispatcht
67
- // `createAction.target` bei Klick — Provider weiß was „leer befüllen"
68
- // für ihn bedeutet (z.B. „neuer Page-Slug" vs „neue Entity-Row"),
69
- // Convention könnte das nicht raten. Konsistent zu `state` (auch
70
- // Provider-explizit). Siehe visual-tree.md V.1.1-Decision D3.
71
- readonly createAction?: TreeAction;
72
- };
73
-
74
- // Subscribe<T> — Provider implementiert: emit(initial); ...emit(updated);
75
- // und gibt unsubscribe-Function zurück. Caller (Tree-Component) ruft
76
- // unsubscribe auf wenn Knoten unmounted/eingeklappt wird.
77
- //
78
- // **V.1.4 emitError**: optional callback für async-error-Pfade (fetch-
79
- // fail, SSE-disconnect). Provider die explizit Errors signalisieren
80
- // wollen rufen `emitError(e)` statt empty-emit; VisualTree zeigt
81
- // Error-Banner mit Retry-Button. Sync-Throws im Provider-Body werden
82
- // vom useEffect-try/catch abgefangen — emitError ist nur für async.
83
- export type Subscribe<T> = (
84
- emit: (value: T) => void,
85
- emitError?: (error: Error) => void,
86
- ) => () => void;
87
-
88
- // TreeChildrenSubscribe — Lazy-Variante für dynamic Children. Wird
89
- // erst aufgerufen wenn der Knoten im UI ausgeklappt wird. Kein ctx-
90
- // Argument: Provider sind session-bound; Backend liest tenantId aus
91
- // session bei jedem fetch/dispatch. V.1.1 hatte ein ctx mit tenantId,
92
- // das aber im Browser nie echten Tenant trug (war auf SYSTEM_TENANT_ID
93
- // gepinnt) und vom einzigen V.1.2-Consumer (text-content) ignoriert
94
- // wurde. SR2-Rip 2026-05-18: Dead-API entfernt; wenn später ein
95
- // Provider tenant-aware-rendern muss (z.B. cross-tenant-Dashboards
96
- // für SystemAdmin), wird ctx mit echtem Tenant-Source aus dem Auth-
97
- // Layer re-introduziert. YAGNI bis dahin.
98
- export type TreeChildrenSubscribe = () => Subscribe<readonly TreeNode[]>;
99
-
100
- // TreeActionDef — Schema-Eintrag pro Action in der treeActions-Map
101
- // eines Features. Phase 0: Args sind ein optionales Type-Sample
102
- // (kein Validator zur Laufzeit — Validation passiert compile-time
103
- // via buildTarget-Generic, runtime via Editor-Panel-Schema).
104
- //
105
- // Lebt hier (nicht in build-target.ts) weil es konzeptuell zur
106
- // Visual-Tree-Domäne gehört, nicht zum Builder. build-target.ts
107
- // importiert den Type von hier.
108
- export type TreeActionDef<TArgs = Record<string, unknown>> = {
109
- readonly args?: TArgs;
110
- };
111
-
112
- // TreeActionsHandle<T> — Return-Type von r.treeActions(...). Trägt
113
- // den literal-typed Action-Map durch das Feature-Export-System
114
- // (siehe FeatureDefinition.exports + Memory `[EventDef-Exports-
115
- // Pattern]`). Das ist die compile-time Bridge zu buildTarget:
116
- //
117
- // const handle = r.treeActions({ edit: { args: { slug: "" as string } } });
118
- // // handle.id → TFeature (literal feature name)
119
- // // handle.treeActions → { edit: { args: { slug: string } } } (literal-typed)
120
- // buildTarget({ target: handle, action: "edit", args: { slug: "x" } });
121
- // // ^^^^^^^^^^^^^^ ^^^^^^^^
122
- // // literal-validated typed-validated
123
- //
124
- // Runtime-Lookup geht über FeatureDefinition.treeActions (erased Map),
125
- // Compile-Time-Validation über diesen Handle.
126
- export type TreeActionsHandle<
127
- TFeature extends string,
128
- TActions extends Record<string, TreeActionDef>,
129
- > = {
130
- readonly id: TFeature;
131
- readonly treeActions: TActions;
132
- };
1
+ export type * from "@cosmicdrift/kumiko-types/tree-node";
@@ -1,49 +1,2 @@
1
- import type { AccessRule } from "./handlers";
2
-
3
- // Workspace declaration. A workspace is a persona-/role-scoped UI surface:
4
- // pure UI composition with no backend, DB or auth impact. The engine stores
5
- // these verbatim and the active web shell (shellWorkspaces) renders the
6
- // switcher and filters the nav tree by membership + access.
7
- //
8
- // Membership is computed from two sources, merged at boot:
9
- // 1. r.workspace({ nav: [...] }) — explicit list of nav QNs
10
- // 2. r.nav({ workspaces: [...] }) — nav entry self-assigns to workspaces
11
- // A nav entry that appears in neither source belongs to no workspace and
12
- // only shows up when no workspace is active (legacy / non-workspace apps).
13
- //
14
- // Cross-feature references are allowed: `nav` may point at any registered
15
- // nav QN. The boot validator checks references exist and that workspace
16
- // IDs referenced from r.nav are real.
17
- export type WorkspaceDefinition = {
18
- // Feature author writes the short id ("disposition"); the registry
19
- // overwrites `id` with the qualified name ("bmc:workspace:disposition")
20
- // in its stored copy. Same pattern as NavDefinition / ScreenDefinition.
21
- readonly id: string;
22
- // i18n translation key. Resolved at render time by the renderer's
23
- // useTranslation hook; engine keeps it opaque.
24
- readonly label: string;
25
- // Icon key — whatever the icon registry of the active renderer understands.
26
- // Engine doesn't validate; unknown icons surface as a missing icon on
27
- // screen, not a boot failure (mirrors NavDefinition.icon).
28
- readonly icon?: string;
29
- // Sort weight in the workspace switcher (lower = earlier). Ties broken
30
- // by registration order — features registered later appear lower.
31
- readonly order?: number;
32
- // Role / openToAll gate. Only users matching this rule see the workspace
33
- // in their switcher. Mirrors NavDefinition.access — same semantics across
34
- // the UI surface, so a default-deny app can do `{ roles: [] }`.
35
- readonly access?: AccessRule;
36
- // Explicit nav QNs that belong to this workspace. Merged with any nav
37
- // entries that self-assign via r.nav({ workspaces: [...] }).
38
- readonly nav?: readonly string[];
39
- // Default workspace at login when the user has access to multiple. Boot
40
- // validator rejects more than one default per app.
41
- readonly default?: boolean;
42
- // Render mode of the workspace's sidebar. "nav" (default, missing-ok)
43
- // mounts the existing NavTree component as before. "tree" mounts the
44
- // Visual-Tree component which collects r.tree() providers across all
45
- // active features. Default-on-undefined preserves backwards-compat —
46
- // every existing workspace stays nav-mode without code touch.
47
- // See visual-tree.md A1.
48
- readonly navigation?: "nav" | "tree";
49
- };
1
+ // Legacy path re-exported for callers still importing this module directly.
2
+ export type * from "@cosmicdrift/kumiko-types/workspace";
@@ -13,7 +13,7 @@
13
13
  // don't run at build time, so dummy event-payloads are fine.
14
14
  //
15
15
  // CLOSURE-BODY CONTRACT: the pipeline-closure body (the function passed
16
- // to `pipeline(...)`) must produce its step-list deterministically based
16
+ // to `stepsPipeline(...)`) must produce its step-list deterministically based
17
17
  // on the step-builder `r` alone. Reading `event.payload` outside of
18
18
  // resolvers (i.e. at the top of the closure, not inside a step's `row:`
19
19
  // or `data:` callback) is forbidden — at boot the dummy payload is `{}`
@@ -23,6 +23,10 @@
23
23
  // caught by this validator. A future lint-rule will enforce the contract
24
24
  // statically; today it lives in this comment + the StepBuilder doc.
25
25
 
26
+ import {
27
+ KUMIKO_META_SYMBOL,
28
+ KUMIKO_NAME_SYMBOL,
29
+ } from "@cosmicdrift/kumiko-types/schema-table-types";
26
30
  import { getStep } from "./define-step";
27
31
  import { buildPipelineSteps } from "./pipeline";
28
32
  import type { FeatureDefinition, SessionUser, TenantId, WriteEvent } from "./types";
@@ -55,13 +59,9 @@ function* walkAllSteps(steps: readonly StepInstance[]): Generator<StepInstance,
55
59
  }
56
60
  }
57
61
 
58
- // @cast-boundary drizzle-bridge — reads table name from a Symbol without
59
- // importing drizzle-orm (bun-db pattern, see bun-db/query.ts).
60
- const KUMIKO_NAME_SYMBOL = Symbol.for("kumiko:schema:Name");
61
62
  // table()/buildEntityTable spread column handles as enumerable props, so an
62
63
  // entity field named `tableName`/`source` would shadow the matching meta key —
63
- // the canonical meta under this symbol is the only collision-safe source.
64
- const KUMIKO_META_SYMBOL = Symbol.for("kumiko:schema:Meta");
64
+ // the canonical meta under KUMIKO_META_SYMBOL is the only collision-safe source.
65
65
 
66
66
  function resolveTableNameFromStep(table: unknown): string {
67
67
  if (typeof table === "object" && table !== null) {