@cratis/pi 7.34.1 → 7.35.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 (227) hide show
  1. package/package/corpus/agents/security-reviewer.md +1 -0
  2. package/package/corpus/agents/spec-writer.md +1 -1
  3. package/package/corpus/harnesses/pi/extensions/shared/rules.ts +3 -1
  4. package/package/corpus/hooks/scripts/cratis-nuget-pins.txt +7 -6
  5. package/package/corpus/hooks/scripts/cratis-release-notes-reviewed.cjs +7 -6
  6. package/package/corpus/hooks/scripts/cratis-store-mutations.json +7 -3
  7. package/package/corpus/product-sync.json +896 -0
  8. package/package/corpus/prompts/add-business-rule.prompt.md +1 -1
  9. package/package/corpus/prompts/ship-changes.prompt.md +2 -2
  10. package/package/corpus/rules/ai-distribution.md +31 -3
  11. package/package/corpus/rules/application-profile.md +2 -1
  12. package/package/corpus/rules/components.md +66 -7
  13. package/package/corpus/rules/concepts.md +11 -3
  14. package/package/corpus/rules/csharp.md +3 -1
  15. package/package/corpus/rules/dialogs.md +9 -0
  16. package/package/corpus/rules/efcore.md +1 -1
  17. package/package/corpus/rules/elixir.md +49 -0
  18. package/package/corpus/rules/framework.md +5 -3
  19. package/package/corpus/rules/general.md +1 -0
  20. package/package/corpus/rules/glossary.md +4 -4
  21. package/package/corpus/rules/go-engineering.md +60 -0
  22. package/package/corpus/rules/go.md +115 -0
  23. package/package/corpus/rules/java.md +5 -2
  24. package/package/corpus/rules/kotlin.md +7 -5
  25. package/package/corpus/rules/orleans.md +65 -9
  26. package/package/corpus/rules/profiles.md +43 -6
  27. package/package/corpus/rules/pull-requests.md +3 -3
  28. package/package/corpus/rules/react.md +8 -1
  29. package/package/corpus/rules/reactors.md +27 -3
  30. package/package/corpus/rules/specs.csharp.md +11 -4
  31. package/package/corpus/rules/specs.scenarios.csharp.md +35 -4
  32. package/package/corpus/rules/specs.typescript.md +2 -1
  33. package/package/corpus/rules/storybook.md +1 -1
  34. package/package/corpus/rules/typescript.md +1 -1
  35. package/package/corpus/rules/vertical-slices.md +37 -5
  36. package/package/corpus/skills/cratis-application-react-specifications/SKILL.md +4 -2
  37. package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +18 -8
  38. package/package/corpus/skills/cratis-application-slice-specifications/references/query-and-decision-scenarios.md +65 -0
  39. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +53 -57
  40. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authentication.md +38 -42
  41. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +18 -7
  42. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authproxy.md +30 -0
  43. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/frontend.md +12 -9
  44. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/local-development.md +9 -9
  45. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/observable-emission-guards.md +8 -5
  46. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/tenancy.md +20 -4
  47. package/package/corpus/skills/cratis-arc-command/SKILL.md +32 -10
  48. package/package/corpus/skills/cratis-arc-command/references/command-result.md +12 -5
  49. package/package/corpus/skills/cratis-arc-command/references/decisions-and-routing.md +95 -0
  50. package/package/corpus/skills/cratis-arc-command/references/generated-values.md +3 -2
  51. package/package/corpus/skills/cratis-arc-command/references/handler-shapes.md +8 -8
  52. package/package/corpus/skills/cratis-arc-command/references/proxy-generation.md +22 -3
  53. package/package/corpus/skills/cratis-arc-command/references/read-model-injection.md +13 -1
  54. package/package/corpus/skills/cratis-arc-command-execution/SKILL.md +19 -9
  55. package/package/corpus/skills/cratis-arc-command-kotlin/SKILL.md +44 -18
  56. package/package/corpus/skills/cratis-arc-command-kotlin/references/read-model-naming.md +29 -0
  57. package/package/corpus/skills/cratis-arc-command-operation/SKILL.md +10 -9
  58. package/package/corpus/skills/cratis-arc-command-operation/references/execution-and-recovery.md +2 -2
  59. package/package/corpus/skills/cratis-arc-command-operation/references/testing.md +4 -3
  60. package/package/corpus/skills/cratis-arc-command-typescript/SKILL.md +42 -22
  61. package/package/corpus/skills/cratis-arc-command-typescript/references/chronicle-events.md +36 -5
  62. package/package/corpus/skills/cratis-arc-command-typescript/references/command-operations.md +114 -0
  63. package/package/corpus/skills/cratis-arc-command-typescript/references/hosting-and-storage.md +37 -16
  64. package/package/corpus/skills/cratis-arc-command-typescript/references/identity-and-introspection.md +88 -0
  65. package/package/corpus/skills/cratis-arc-command-typescript/references/observability-and-host-scopes.md +25 -0
  66. package/package/corpus/skills/cratis-arc-command-typescript/references/proxy-generation.md +35 -4
  67. package/package/corpus/skills/cratis-arc-command-typescript/references/slice-layout.md +11 -0
  68. package/package/corpus/skills/cratis-arc-command-typescript/verification.json +8 -1
  69. package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +49 -19
  70. package/package/corpus/skills/cratis-arc-ef-core-migration/SKILL.md +12 -6
  71. package/package/corpus/skills/cratis-arc-go/SKILL.md +148 -0
  72. package/package/corpus/skills/cratis-arc-go/references/queries.md +80 -0
  73. package/package/corpus/skills/cratis-arc-hosting/SKILL.md +96 -0
  74. package/package/corpus/skills/cratis-arc-hosting/references/integrations-and-publish.md +80 -0
  75. package/package/corpus/skills/cratis-arc-identity-and-tenancy-kotlin/SKILL.md +137 -0
  76. package/package/corpus/skills/cratis-arc-observable-query-http/SKILL.md +20 -2
  77. package/package/corpus/skills/cratis-arc-query-kotlin/SKILL.md +26 -6
  78. package/package/corpus/skills/cratis-arc-query-paging/SKILL.md +25 -20
  79. package/package/corpus/skills/cratis-arc-query-typescript/SKILL.md +32 -6
  80. package/package/corpus/skills/cratis-arc-query-typescript/references/storage-observation-and-compliance.md +66 -0
  81. package/package/corpus/skills/cratis-arc-query-typescript/verification.json +5 -1
  82. package/package/corpus/skills/cratis-arc-react-page/SKILL.md +24 -13
  83. package/package/corpus/skills/cratis-arc-react-page/references/data-page.md +20 -10
  84. package/package/corpus/skills/cratis-arc-react-page/references/data-tables.md +17 -3
  85. package/package/corpus/skills/cratis-arc-react-page/references/dialogs.md +14 -3
  86. package/package/corpus/skills/cratis-arc-react-page/references/from-screenplay.md +6 -1
  87. package/package/corpus/skills/cratis-arc-react-page/references/provenance.md +1 -1
  88. package/package/corpus/skills/cratis-arc-react-page/references/queries-and-commands.md +11 -1
  89. package/package/corpus/skills/cratis-arc-react-page/verification.json +6 -1
  90. package/package/corpus/skills/cratis-arc-spring-data-kotlin/SKILL.md +163 -0
  91. package/package/corpus/skills/cratis-arc-testing-kotlin/SKILL.md +131 -0
  92. package/package/corpus/skills/cratis-arc-validation-kotlin/SKILL.md +44 -11
  93. package/package/corpus/skills/cratis-arc-validation-typescript/SKILL.md +5 -3
  94. package/package/corpus/skills/cratis-chronicle-cli-operations/SKILL.md +79 -25
  95. package/package/corpus/skills/cratis-chronicle-cli-operations/references/command-effects.md +57 -0
  96. package/package/corpus/skills/cratis-chronicle-client-dotnet/SKILL.md +87 -99
  97. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/additional-surfaces.md +65 -0
  98. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/client-construction.md +42 -0
  99. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/compatibility-check.md +12 -0
  100. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/discovery.md +43 -19
  101. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/hosting.md +29 -1
  102. package/package/corpus/skills/cratis-chronicle-client-elixir/SKILL.md +158 -162
  103. package/package/corpus/skills/cratis-chronicle-client-elixir/references/append-api.md +36 -15
  104. package/package/corpus/skills/cratis-chronicle-client-elixir/references/compliance.md +32 -0
  105. package/package/corpus/skills/cratis-chronicle-client-elixir/references/connections.md +56 -0
  106. package/package/corpus/skills/cratis-chronicle-client-elixir/references/event-sources.md +64 -0
  107. package/package/corpus/skills/cratis-chronicle-client-elixir/references/pitfalls.md +25 -0
  108. package/package/corpus/skills/cratis-chronicle-client-elixir/references/projections.md +48 -0
  109. package/package/corpus/skills/cratis-chronicle-client-elixir/references/upgrading.md +34 -0
  110. package/package/corpus/skills/cratis-chronicle-client-elixir/references/variants.md +13 -5
  111. package/package/corpus/skills/cratis-chronicle-client-elixir/verification.json +23 -0
  112. package/package/corpus/skills/cratis-chronicle-client-go/SKILL.md +162 -0
  113. package/package/corpus/skills/cratis-chronicle-client-go/references/projections.md +73 -0
  114. package/package/corpus/skills/cratis-chronicle-client-kotlin/SKILL.md +87 -88
  115. package/package/corpus/skills/cratis-chronicle-client-kotlin/references/connection-lifecycle.md +13 -0
  116. package/package/corpus/skills/cratis-chronicle-client-kotlin/references/discovery-and-registration.md +14 -4
  117. package/package/corpus/skills/cratis-chronicle-client-kotlin/references/event-sources.md +65 -0
  118. package/package/corpus/skills/cratis-chronicle-client-kotlin/references/options.md +29 -0
  119. package/package/corpus/skills/cratis-chronicle-client-kotlin/references/spring-boot.md +13 -0
  120. package/package/corpus/skills/cratis-chronicle-client-kotlin/references/variants.md +5 -4
  121. package/package/corpus/skills/cratis-chronicle-client-typescript/SKILL.md +165 -156
  122. package/package/corpus/skills/cratis-chronicle-client-typescript/references/read-models-and-projections.md +54 -11
  123. package/package/corpus/skills/cratis-chronicle-client-typescript/references/testing.md +126 -0
  124. package/package/corpus/skills/cratis-chronicle-client-typescript/references/variants.md +3 -5
  125. package/package/corpus/skills/cratis-chronicle-client-typescript/verification.json +19 -0
  126. package/package/corpus/skills/cratis-chronicle-compliance/SKILL.md +36 -13
  127. package/package/corpus/skills/cratis-chronicle-decision-reads/SKILL.md +110 -0
  128. package/package/corpus/skills/cratis-chronicle-decision-reads/references/admission-and-ownership.md +57 -0
  129. package/package/corpus/skills/cratis-chronicle-decision-reads/verification.json +12 -0
  130. package/package/corpus/skills/cratis-chronicle-event-constraints/SKILL.md +58 -19
  131. package/package/corpus/skills/cratis-chronicle-event-constraints/references/closing-streams.md +73 -0
  132. package/package/corpus/skills/cratis-chronicle-event-modeling/SKILL.md +32 -3
  133. package/package/corpus/skills/cratis-chronicle-event-specifications/SKILL.md +18 -5
  134. package/package/corpus/skills/cratis-chronicle-event-type-migration/SKILL.md +32 -2
  135. package/package/corpus/skills/cratis-chronicle-hosting/SKILL.md +134 -0
  136. package/package/corpus/skills/cratis-chronicle-hosting/references/operations.md +89 -0
  137. package/package/corpus/skills/cratis-chronicle-hosting/verification.json +14 -0
  138. package/package/corpus/skills/cratis-chronicle-mcp-inspection/SKILL.md +93 -66
  139. package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/blocked-tools.md +21 -7
  140. package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/deployment.md +77 -0
  141. package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/observational-tools.md +46 -4
  142. package/package/corpus/skills/cratis-chronicle-multi-tenancy/SKILL.md +15 -1
  143. package/package/corpus/skills/cratis-chronicle-projection/SKILL.md +44 -10
  144. package/package/corpus/skills/cratis-chronicle-projection/references/fluent-builder.md +7 -1
  145. package/package/corpus/skills/cratis-chronicle-projection/references/model-bound-attributes.md +8 -0
  146. package/package/corpus/skills/cratis-chronicle-reactor/SKILL.md +85 -105
  147. package/package/corpus/skills/cratis-chronicle-reactor/references/specifications.md +20 -1
  148. package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +2 -2
  149. package/package/corpus/skills/cratis-chronicle-read-model/references/queries.md +35 -16
  150. package/package/corpus/skills/cratis-chronicle-read-model-specifications/SKILL.md +15 -3
  151. package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +23 -4
  152. package/package/corpus/skills/cratis-chronicle-web-workbench/SKILL.md +40 -15
  153. package/package/corpus/skills/cratis-cli-terminal-workbench/SKILL.md +20 -6
  154. package/package/corpus/skills/cratis-code-review/SKILL.md +25 -3
  155. package/package/corpus/skills/cratis-components-accessibility/SKILL.md +20 -4
  156. package/package/corpus/skills/cratis-components-schema-editor/SKILL.md +40 -28
  157. package/package/corpus/skills/cratis-components-schema-editor/references/tree-layout.md +62 -0
  158. package/package/corpus/skills/cratis-components-schema-editor/verification.json +14 -0
  159. package/package/corpus/skills/cratis-components-stepper-command-dialog/SKILL.md +16 -8
  160. package/package/corpus/skills/cratis-components-styling/SKILL.md +57 -20
  161. package/package/corpus/skills/cratis-components-styling/verification.json +13 -0
  162. package/package/corpus/skills/cratis-components-toolbar/SKILL.md +37 -7
  163. package/package/corpus/skills/cratis-components-toolbar/verification.json +12 -0
  164. package/package/corpus/skills/cratis-engineering-csharp-conventions/SKILL.md +6 -0
  165. package/package/corpus/skills/cratis-engineering-csharp-conventions/references/exceptions-logging-and-di.md +5 -3
  166. package/package/corpus/skills/cratis-fundamentals-concept/SKILL.md +19 -6
  167. package/package/corpus/skills/cratis-fundamentals-concept/references/typescript-concepts.md +97 -0
  168. package/package/corpus/skills/cratis-fundamentals-concept/verification.json +4 -1
  169. package/package/corpus/skills/cratis-fundamentals-concept-go/SKILL.md +112 -0
  170. package/package/corpus/skills/cratis-fundamentals-type-discovery/SKILL.md +54 -17
  171. package/package/corpus/skills/cratis-fundamentals-type-discovery/verification.json +14 -0
  172. package/package/corpus/skills/cratis-lens-browser-extension/SKILL.md +55 -28
  173. package/package/corpus/skills/cratis-performance-review/SKILL.md +5 -2
  174. package/package/corpus/skills/cratis-release-notes/SKILL.md +3 -1
  175. package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +5 -4
  176. package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +5 -6
  177. package/package/corpus/skills/cratis-screenplay-command-surface/references/compliance.md +24 -6
  178. package/package/corpus/skills/cratis-screenplay-command-surface/references/enum-numbers.md +4 -2
  179. package/package/corpus/skills/cratis-screenplay-command-surface/references/generated-values-and-responses.md +4 -1
  180. package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +3 -2
  181. package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md +2 -2
  182. package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +1 -0
  183. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generate-notes.md +34 -4
  184. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +5 -3
  185. package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +1 -1
  186. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +4 -2
  187. package/package/corpus/skills/cratis-screenplay-model-authoring/references/property-links.md +42 -3
  188. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +3 -1
  189. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +3 -1
  190. package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +3 -1
  191. package/package/corpus/skills/cratis-screenplay-specifications/references/examples-and-routes.md +48 -0
  192. package/package/corpus/skills/cratis-screenplay-specifications/verification.json +3 -1
  193. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +4 -2
  194. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +5 -4
  195. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +8 -6
  196. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +2 -2
  197. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +4 -2
  198. package/package/corpus/skills/cratis-screenplay-toolchain/references/doc-contradictions.md +1 -1
  199. package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +16 -11
  200. package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +5 -2
  201. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1329 -32
  202. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
  203. package/package/corpus/skills/cratis-screenplay-toolchain/references/verdicts.md +2 -2
  204. package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +23 -7
  205. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +1 -1
  206. package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +2 -0
  207. package/package/corpus/skills/cratis-screenplay-ui-composition/references/screen-composition-contract.md +27 -9
  208. package/package/corpus/skills/cratis-security-review/SKILL.md +9 -3
  209. package/package/corpus/skills/cratis-security-review/references/arc-boundaries.md +59 -0
  210. package/package/corpus/skills/cratis-specification-by-example/SKILL.md +7 -0
  211. package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +43 -11
  212. package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md +16 -4
  213. package/package/corpus/skills/cratis-specifications-csharp/references/csharp-patterns.md +18 -5
  214. package/package/corpus/skills/cratis-specifications-csharp/references/integration-specs.md +21 -0
  215. package/package/corpus/skills/cratis-specifications-csharp/references/shared-lifecycle.md +34 -0
  216. package/package/corpus/skills/cratis-specifications-csharp/verification.json +13 -0
  217. package/package/corpus/skills/cratis-specifications-typescript/SKILL.md +14 -5
  218. package/package/corpus/skills/cratis-specifications-typescript/verification.json +12 -0
  219. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +8 -2
  220. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +6 -3
  221. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/rendered-application.md +10 -1
  222. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/scene-runtime.md +75 -0
  223. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +5 -0
  224. package/package/corpus/skills/cratis-studio-mcp-safety-guidance/SKILL.md +14 -1
  225. package/package/profile-catalog.json +68 -1
  226. package/package.json +1 -1
  227. package/src/index.ts +3 -1
@@ -24,12 +24,13 @@ the query string — you choose a **return shape** that the framework can narrow
24
24
 
25
25
  | Package | Version | Purpose |
26
26
  | --- | --- | --- |
27
- | `Cratis.Arc.Core` | `22.16.0` | `QueryableQueryRenderer`, `Paging`, `Sorting`, `PagingInfo` |
28
- | `Cratis.Arc.MongoDB` | `22.16.0` | `Observe` helpers that page at the source |
29
- | `Cratis.Arc.EntityFrameworkCore` | `22.16.0` | `DbSet<T>` observe helpers that page at the source |
30
- | `@cratis/arc.react` | `22.16.0` | `useWithPaging`, `useSuspenseWithPaging` |
27
+ | `Cratis.Arc.Core` | `22.75.0` | `QueryableQueryRenderer`, `Paging`, `Sorting`, `PagingInfo` |
28
+ | `Cratis.Arc.MongoDB` | `22.75.0` | `Observe` helpers that page at the source |
29
+ | `Cratis.Arc.EntityFrameworkCore` | `22.75.0` | `DbSet<T>` observe helpers that page at the source |
30
+ | `@cratis/arc.react` | `22.75.0` | `useWithPaging`, `useSuspenseWithPaging` |
31
31
 
32
- > Re-verified at the versions above by **symbol and signature**: every type, attribute and member this skill names exists at that tag, and the public surface it describes is unchanged since the previous verification (Chronicle 16.45.x / Arc 22.10.4 — the Chronicle 16→18 client diff is converters, options and doc comments; no type was removed or renamed). Behavior claims were verified at the earlier tag unless a section says otherwise.
32
+ > Rechecked at Arc v22.75.0: request parsing, paging validation and storage
33
+ > observation contracts. Do not transfer a provider's ordering guarantee to another.
33
34
 
34
35
  Reverify before claiming support for another version. A small, bounded result
35
36
  set does not need any of this — `IEnumerable<T>` is fine.
@@ -38,10 +39,10 @@ set does not need any of this — `IEnumerable<T>` is fine.
38
39
 
39
40
  | Query-string key | Effect |
40
41
  | --- | --- |
41
- | `pageSize` | **Required to page at all** on the query string; any parseable integer is accepted (`0` yields an empty page, negatives are clamped by `Skip`) — the JSON body reader, by contrast, treats `pageSize <= 0` as not paged |
42
+ | `pageSize` | **Required to page at all** on the query string; parseable values enroll paging validation (`page >= 0`, `pageSize > 0`) — the JSON body reader, by contrast, treats `pageSize <= 0` as not paged |
42
43
  | `page` | Zero-based. Defaults to `0` when `pageSize` is present |
43
44
  | `sortby` | Field name; PascalCased before use, so `?sortby=name` sorts on `Name` |
44
- | `sortDirection` | `desc` (case-insensitive) sorts descending; **anything else, including a missing value, is ascending** |
45
+ | `sortDirection` | `asc`/`ascending` or `desc`/`descending`, case-insensitive; unknown values are `malformedRequest` (HTTP 400) |
45
46
 
46
47
  Two consequences that surprise people:
47
48
 
@@ -49,12 +50,12 @@ Two consequences that surprise people:
49
50
  - **Sorting needs both keys.** `sortby` without `sortDirection` is ignored
50
51
  entirely.
51
52
 
52
- Paging is **not** validated on the request path at 22.16.0: `PageNumber`/`PageSize`
53
- concept validators exist (`page >= 0`, `pageSize > 0`) but nothing feeds the
54
- query-string paging into them, so an out-of-range value produces an empty or
55
- clamped page rather than a validation failure. Validate paging arguments in the
56
- frontend, or expose them as explicit query arguments if the rule must be
57
- enforced.
53
+ GET paging/sorting keys are matched case-insensitively. `QueryPipeline.ValidatePaging`
54
+ runs the page validators whenever `paging.IsPaged`: negative page and zero or
55
+ negative size fail validation. This was already true at 22.16.0. A missing sort
56
+ direction parses as ascending, but GET sorting still needs both nonempty keys.
57
+ Sources at Arc v22.75.0: `Arc.Core/Queries/QueryStringQueryRequestReader.cs`,
58
+ `SortDirections.cs` and `QueryPipeline.cs` under `Source/DotNET`.
58
59
 
59
60
  ## Which return shapes page
60
61
 
@@ -102,10 +103,10 @@ query-shaped method on a read model is generic — a generic method is registere
102
103
  and routed but can never be invoked, because there is nothing to close its type
103
104
  parameters with.
104
105
 
105
- For MongoDB `Observe` cost, distinguish the initial retained result, incremental
106
- membership updates, and page-refill queries from an application callback that
107
- explicitly re-runs a query. It does not always fetch the whole collection per
108
- change. See the read-model skill's [versioned query-cost guidance](../cratis-chronicle-read-model/references/queries.md#cost-and-composition).
106
+ At v22.75.0, paged MongoDB observations re-read the page and total on each
107
+ change; unpaged observations retain incremental membership. The watch does not
108
+ always fetch the whole collection. MongoDB observation breaks sort ties on `_id`
109
+ and orders unsorted pages on `_id`. See the read-model skill's [versioned query-cost guidance](../cratis-chronicle-read-model/references/queries.md#cost-and-composition).
109
110
 
110
111
  ## Page the source, not the answer
111
112
 
@@ -134,9 +135,13 @@ a second round trip to the store per query.
134
135
  Because `sortby` is PascalCased, the client sends the camelCase property name
135
136
  the generated proxy uses and the server resolves the CLR property.
136
137
 
137
- Give any list with a natural order a default `OrderBy`. Paging without one is
138
- unstable across storage providers, which return unordered results in different
139
- orders.
138
+ Give any list with a natural order a default `OrderBy`; do not generalize the
139
+ MongoDB observation tie-break to every `IQueryable` provider. Generated proxies
140
+ provide field-named sort helpers. For composed MongoDB/EF observations, pass
141
+ `ignoreQueryContext: true` to auxiliary sources so only the primary consumes
142
+ client paging/sorting and writes totals. Single-instance observations emit
143
+ `default` when absent/deleted/outside the filter; guard `hasData`/`isReady` in React.
144
+ Source: [Arc v22.75.0 MongoDB observations](https://github.com/Cratis/Arc/blob/v22.75.0/Documentation/backend/csharp/mongodb/observing-collections.md).
140
145
 
141
146
  ## Consume it from the frontend
142
147
 
@@ -19,8 +19,8 @@ frontend. Project setup, the builder, and hosts are in
19
19
 
20
20
  ## Verified product sources
21
21
 
22
- Verified against `Cratis/Arc.TypeScript` `main` at commit `94d398d` (tag
23
- `v0.33.0` plus three commits), reading
22
+ Verified against `Cratis/Arc.TypeScript` tag **v0.57.2** (GitHub pre-release;
23
+ server packages 0.57.2, not on npm), reading
24
24
  `Source/Core/queries/index.ts`, `Documentation/queries/**`,
25
25
  `Documentation/mongodb/**`, `Documentation/sql/**`,
26
26
  `Documentation/testing/queries.md` and `observable-queries.md`, and
@@ -143,7 +143,13 @@ Every query route accepts GET and the HTTP `QUERY` method, whose JSON body is
143
143
  `generatedApis: { enableQueryHttpMethod: false }` turns it off (405 with
144
144
  `Allow: GET`). `@query({ httpMethod: QueryHttpMethod.Query })` only sets the
145
145
  generated client's preference; it does not change the server. OpenAPI describes
146
- queries as GET only.
146
+ queries as GET only. OpenAPI includes `POST <command route>/validate` with
147
+ operation id `<id>:validate`; paging/sorting parameters only for array/`queryPage`
148
+ queries (metadata-free arrays need `generatedReturn: { cardinality: 'many', nullable: false }`).
149
+ 401 appears only when authentication can produce it. `/openapi.json` is protected
150
+ by the secure discovery defaults; read
151
+ [the identity/introspection reference](../cratis-arc-command-typescript/references/identity-and-introspection.md)
152
+ when configuring discovery access or identity.
147
153
 
148
154
  ## Page and sort
149
155
 
@@ -151,6 +157,11 @@ queries as GET only.
151
157
  `page` is zero-based. `pageSize` of 0 or less, or a negative page, answers
152
158
  400. Sorting in memory requires the field on every item; a non-array result
153
159
  asked to page or sort answers 400.
160
+ - In-memory complex-field sorting (object/array/map or a concept over one) answers
161
+ 400 `malformedRequest`, or a validation frame after streaming starts. Concepts
162
+ sort by their underlying scalar value (including numeric/chronological values);
163
+ temporal values sort naturally and null concepts join other nulls. Generated
164
+ complex-field `sortBy` helpers are deprecated: sort on scalar fields.
154
165
  - To cut the page in the data source, add `queryOptions()` and return
155
166
  `queryPage(items, totalItems)`. `items` must be exactly the requested page.
156
167
  If the request asked for sorting, pass the applied sort as the third argument —
@@ -174,7 +185,10 @@ static observeAllTasks(tasks: Tasks): BehaviorSubject<TaskItem[]> { return tasks
174
185
  Arc must know a query is observable **before** registration. Generated metadata
175
186
  infers it from the declared return type; without metadata, say so explicitly:
176
187
  `@query({ observable: true }, service(Tasks))`. A snapshot query that returns a
177
- live source anyway fails at run time.
188
+ live source anyway throws `SnapshotStreamError`, without subscribing or calling
189
+ `unsubscribe()` on a shared Subject. Arc releases it once through its available
190
+ async/sync disposal, `dispose`, `close`, or `return` hook;
191
+ `snapshotStreamSource(result)` is exported from core.
178
192
 
179
193
  | Source | Snapshot GET |
180
194
  | --- | --- |
@@ -194,7 +208,8 @@ live source anyway fails at run time.
194
208
  its `signal` aborts when the subscriber leaves.
195
209
  - Paging and sorting apply to **every** emission, in memory. An observable query
196
210
  cannot return `queryPage`; narrow what the source emits instead, or use a
197
- database-backed observation such as MongoDB change streams.
211
+ database-backed observation such as MongoDB change streams or opted-in Drizzle
212
+ observation (see the storage reference below).
198
213
  - Transports: `Accept: text/event-stream` on the route (direct SSE, one
199
214
  `data: <QueryResult>` frame per change), a direct WebSocket upgrade
200
215
  (`{"type":"Data","data":<QueryResult>}` frames, `Ping`/`Pong`), or the
@@ -276,13 +291,22 @@ export class Author {
276
291
  `observe()` needs a replica set. Build owner filters from the verified
277
292
  principal, never from a caller-provided filter object.
278
293
  - Drizzle: `drizzleReadModel(Model)` is a read-only handle; writes belong in
279
- commands through `drizzleDatabase()`.
294
+ commands through `drizzleDatabase()`. Live queries require opt-in
295
+ `DrizzleObservation.InProcess` announcements or experimental PostgreSQLNotify;
296
+ `rxjs` is a required peer of `@cratis/arc.drizzle`.
297
+ - Protected raw MongoDB reads need typed `MongoReadModels` with `readModel`
298
+ registered with Chronicle (optional `subjectFor`). Untyped reads and
299
+ `MongoDBWatcher.changes()` still expose stored ciphertext.
300
+
280
301
  - Chronicle: `ChronicleReadModels` offers `getAll`, `getById`, `observeAll`,
281
302
  `observeById` for the current tenant's namespace. Projecting happens after the
282
303
  append, so a query right after a command can be stale; a live query updates
283
304
  when the projection catches up. Projection authoring is
284
305
  `cratis-chronicle-client-typescript`.
285
306
 
307
+ Read [references/storage-observation-and-compliance.md](references/storage-observation-and-compliance.md)
308
+ when implementing Drizzle observation or serving protected raw MongoDB documents.
309
+
286
310
  ## Specify the query
287
311
 
288
312
  `@cratis/arc.testing` runs the real query pipeline in-process. From
@@ -313,6 +337,8 @@ export class a_task_listing {
313
337
  rehydrated model.
314
338
  - `perform(arguments, { paging, sorting }?)` returns the actual `QueryResult`,
315
339
  e.g. `perform({}, { sorting: { field: 'title', direction: SortDirection.Ascending }, paging: { page: 0, pageSize: 1 } })`.
340
+ - `QueryScenario.perform()` throws `StreamingQueryNotSupportedError` for
341
+ observable queries: use `ObservableQueryScenario` instead.
316
342
  - `ObservableQueryScenario.collect(count, timeoutMs = 5000, arguments?, options?)`
317
343
  returns `{ emissions, completed, rejection }`; a rejected subscription lands in
318
344
  `rejection`, not `emissions`. Always assert the emission count.
@@ -0,0 +1,66 @@
1
+ <!-- Copyright (c) Cratis. All rights reserved. -->
2
+ <!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
3
+
4
+ # Storage observation and protected raw reads
5
+
6
+ Verified at `Cratis/Arc.TypeScript` **v0.57.2** (source preview, not on npm):
7
+ `Source/Drizzle/DrizzleOptions.ts`, package exports and observation code,
8
+ `Source/MongoDB/MongoReadModelsOptions.ts`, `Source/Chronicle/releaseRawDocument.ts`,
9
+ `Documentation/sql/observing-tables.md`, `observing-postgresql.md`, and
10
+ `Documentation/chronicle/compliance.md`.
11
+
12
+ ## Drizzle live queries
13
+
14
+ `rxjs ^7.8.2` is a **required peer** of `@cratis/arc.drizzle`, even with
15
+ observation disabled. Starting an observation without opting in throws; it never
16
+ silently returns a stream that will not update.
17
+
18
+ - In-process: `withDrizzle({ ..., observation: DrizzleObservation.InProcess })`.
19
+ Writers call `DrizzleHandle.notifyChanged(tableOrType)` for a registered table
20
+ object/model, in the current tenant. Only announced writes in this process
21
+ invalidate reads. Inside commands, notifications coalesce until that tenant's
22
+ outermost command finishes (success **or failure**). Transactions owned outside
23
+ Arc are not covered; announce only after their commit. Background writes
24
+ announce immediately, so call after commit.
25
+ - Cross-process PostgreSQL (experimental): use observation options
26
+ `{ mode: DrizzleObservation.PostgreSQLNotify, listener }`. Install the SQL from
27
+ `postgresqlChangeTrigger(table, { schema })` in an application-owned drizzle-kit
28
+ custom migration, not at runtime. `nodePostgresListener(new Client(...))` wraps
29
+ a new, unconnected, dedicated `pg.Client`; route both listener and query pool
30
+ to the same primary database. Aliased tables, views, partitions, inherited and
31
+ temporary tables are rejected. Recovery reconnects with bounded backoff,
32
+ revalidates triggers, then forces fresh snapshots; there is no in-process
33
+ fallback and no durable replay of outage history.
34
+
35
+ `DrizzleReadModels.observe(filter?)` / `observeById(key)` return RxJS sources
36
+ with `current()`. The former fails on `maxPageSize` overflow rather than
37
+ truncating; the latter emits null for absence/deletion. Use these for model-bound
38
+ observable queries. `observePage` requires low-level `defineObservableQuery` and
39
+ has **no generated proxy support**. Count and page are eventually consistent,
40
+ not one atomic snapshot. Release subscriptions/scopes to release listeners.
41
+
42
+ ## MongoDB compliance release
43
+
44
+ With Chronicle registered, decoded **exact** protected read-model instances are
45
+ released before query encoding. For raw `MongoReadModels` documents, pass
46
+ `readModel: PersonView`, with that type registered with `withChronicle`, and
47
+ optionally `subjectFor(document)`. Default subject is stored `__subject`, then a
48
+ string/numeric `_id`. Typed reads reject partial MongoDB projections.
49
+
50
+ Release is fail-closed. The query/emission fails for a mismatched subject or
51
+ tenant, nonempty `__subjects` (per-property subjects), undeclared fields,
52
+ non-JSON BSON values, missing schemas, or a failed/incomplete release. Date
53
+ values are accepted; BSON ObjectId/Binary/Decimal128 payload fields are not.
54
+ Return typed documents directly, in arrays, or in **`queryPage`**. Nesting one
55
+ inside another response shape — including `MongoReadModels.page()`'s `MongoPage`
56
+ — fails; read multi-subject models through `ChronicleReadModels` instead.
57
+
58
+ Untyped MongoReadModels, unmarked driver documents, copies that lose their
59
+ marking, and `MongoDBWatcher.changes()` are still served **as stored ciphertext**.
60
+ Do not assume any raw query was decrypted merely because Chronicle is installed.
61
+ Protected reducer-watch removals whose payload the SDK cannot release carry an
62
+ empty model instance rather than that unreleased payload.
63
+
64
+ Release is not authorization. Filter by the verified caller separately. See
65
+ `cratis-chronicle-compliance` for subject/erasure principles, but use these
66
+ TypeScript APIs rather than its .NET code shapes.
@@ -9,6 +9,10 @@
9
9
  { "kind": "skill-contains", "value": "`@query({ observable: true }, service(Tasks))`" },
10
10
  { "kind": "skill-contains", "value": "| RxJS `BehaviorSubject<T>` | 200 immediately" },
11
11
  { "kind": "skill-contains", "value": "authorization runs **once**, when the subscription\n opens" },
12
- { "kind": "skill-contains", "value": "QueryScenario.for<T>(ReadModel, 'methodName', ...artifacts)" }
12
+ { "kind": "skill-contains", "value": "QueryScenario.for<T>(ReadModel, 'methodName', ...artifacts)" },
13
+ { "kind": "skill-contains", "value": "SnapshotStreamError" },
14
+ { "kind": "skill-contains", "value": "400 `malformedRequest`" },
15
+ { "kind": "skill-contains", "value": "DrizzleObservation.InProcess", "file": "references/storage-observation-and-compliance.md" },
16
+ { "kind": "skill-contains", "value": "Untyped MongoReadModels", "file": "references/storage-observation-and-compliance.md" }
13
17
  ]
14
18
  }
@@ -28,10 +28,10 @@ This skill is verified against these exact package contracts:
28
28
 
29
29
  | Package | Version | Verified from |
30
30
  | --- | --- | --- |
31
- | `@cratis/components` | `4.6.0` | its package manifest (`exports`, peers), `Source/DataPage/*`, `Source/DataTables/*`, `Source/Dialogs/*`, `Source/CommandDialog/*`, `Source/MIGRATION.md` |
32
- | `@cratis/arc` | `>=20.3.1 <23` | peer range declared by `@cratis/components@4.6.0` |
33
- | `@cratis/arc.react` | `>=20.3.1 <23` | peer range declared by `@cratis/components@4.6.0` |
34
- | `react` | `^19.0.0` | peer of `@cratis/components@4.6.0` |
31
+ | `@cratis/components` | `4.26.4` | its package manifest (`exports`, peers), `Source/DataPage/*`, `Source/DataTables/*`, `Source/Dialogs/*`, `Source/CommandDialog/*`, `Source/MIGRATION.md` |
32
+ | `@cratis/arc` | `>=20.3.1 <23` | peer range declared by `@cratis/components@4.26.4` |
33
+ | `@cratis/arc.react` | `>=20.3.1 <23` | peer range declared by `@cratis/components@4.26.4` |
34
+ | `react` | `^19.0.0` | peer of `@cratis/components@4.26.4` |
35
35
 
36
36
  `@cratis/arc.react.mvvm` ships with `@cratis/arc.react` and is an explicit
37
37
  application dependency. Reverify before claiming another version.
@@ -69,16 +69,26 @@ must move focus into itself.
69
69
  fix the C# source and rebuild instead of editing one.
70
70
  - The app must mount `CratisComponentsProvider` (from the package root,
71
71
  `@cratis/components`) above every Cratis component — it carries the locale,
72
- the Components-owned labels and the toast region (`toaster`).
72
+ the Components-owned labels. Enable `toaster` (or mount one `<Toaster />`)
73
+ for notifications; without it even `toastCommandResult` displays nothing.
74
+ Mount exactly one toaster, not both.
73
75
  - The app must import the stylesheets explicitly; components do not import
74
76
  their own CSS:
75
77
 
76
- ```ts
77
- import '@cratis/components/tokens'; // the --cratis-* token seam
78
- import '@cratis/components/styles'; // structural rules for every component
79
- import '@cratis/components/theme'; // optional: the maintained baseline look
78
+ In `index.css`, imported by the entry with `import './index.css'`:
79
+
80
+ ```css
81
+ @import '@cratis/components/tokens';
82
+ @import '@cratis/components/styles';
83
+ @import '@cratis/components/theme'; /* optional baseline */
80
84
  ```
81
85
 
86
+ CSS subpath imports from TypeScript need ambient declarations on TypeScript 6;
87
+ use CSS `@import` to avoid TS2882. For a smaller bundle use `styles/base` plus
88
+ the needed area sheets (`DataPage/styles`, etc.); area order does not matter.
89
+ Import `reflect-metadata` at the entry point; it remains required. `tsyringe`
90
+ is optional for Components but installed by Arc React.
91
+
82
92
  Components has no vendor UI dependency — do not install PrimeReact or an icon
83
93
  font for it. Menu icons are React component types (`react-icons` works).
84
94
 
@@ -268,8 +278,9 @@ const [selected, setSelected] = useState<AccountSummary | null>(null);
268
278
  The **same `query` prop** takes a snapshot query or an observable query. There
269
279
  is no separate `observableQuery` prop: `DataPage` inspects the query prototype
270
280
  and picks the snapshot or observable table itself. Pass an observable query and
271
- the page stays live; pass a snapshot query and call `onRefresh` after a command
272
- succeeds.
281
+ the page stays live. `onRefresh` only forwards a caller callback to the details
282
+ component; it never refetches the table. DataPage has no snapshot refresh handle.
283
+ Use an observable query when commands must update the list.
273
284
 
274
285
  Read [queries-and-commands.md](references/queries-and-commands.md) when using generated proxy hooks, implementing paging, or handling command results; it covers the
275
286
  generated proxy hooks, their exact return tuples, paging, and how to read a
@@ -325,8 +336,8 @@ props handling, or teardown.
325
336
  ## Verify
326
337
 
327
338
  - Every Cratis Components import uses a subpath, not the root barrel.
328
- - `CratisComponentsProvider` wraps the tree and the three stylesheets are
329
- imported once at the app entry point.
339
+ - `CratisComponentsProvider` wraps the tree, one toaster is mounted for
340
+ notifications, and the CSS entries are imported once via the app's CSS file.
330
341
  - `DataPage` receives `title`, `query`, `emptyMessage`, and children, and
331
342
  `dataKey` when the read model has an identity.
332
343
  - Columns sit in `<DataPage.Columns>`; menu items sit in
@@ -38,17 +38,22 @@ Three static members exist:
38
38
  | --- | --- | --- |
39
39
  | `title` | `string` | required — menubar title |
40
40
  | `query` | `Constructor<TQuery>` | required — a snapshot **or** observable query proxy |
41
- | `emptyMessage` | `string` | required — shown when the query returns no rows |
41
+ | `emptyMessage` | `string` | required — only a real empty result |
42
+ | `loadingMessage` / `failureMessage` / `unauthorizedMessage` | `ReactNode` | query-state rows; defaults from `messages.dataTable.loading/failed/unauthorized` |
42
43
  | `children` | `ReactNode` | required — `DataPage.Columns` and optionally `DataPage.MenuItems` |
43
44
  | `queryArguments` | `TArguments` | forwarded to the query |
44
45
  | `dataKey` | `string \| undefined` | row identity; pass whenever the read model has one |
45
- | `selection` | `any \| undefined \| null` | controlled selection |
46
+ | `selection` | `any \| undefined \| null` | controlled single selection |
47
+ | `selectionMode` | `'single' \| 'multiple'` | default single |
48
+ | `selectedItems` / `onSelectedItemsChange` | `TDataType[]` / `(items: TDataType[]) => void` | multiple selection; omit `selectedItems` for internal state |
46
49
  | `onSelectionChange` | `(event: DataTableSelectionChangeEvent<any>) => void` | `event.value` is the row or `null` |
47
50
  | `detailsComponent` | `React.FC<IDetailsComponentProps<any>>` | rendered beside the table for the selected row |
48
51
  | `globalFilterFields` | `string[] \| undefined` | enables the global search box over these fields |
49
52
  | `defaultFilters` | `DataTableFilterMeta` | initial per-column filter state |
50
- | `onRefresh` | `() => void` | invoked to re-fetch a snapshot query |
53
+ | `onRefresh` | `() => void` | forwarded unchanged to details; DataPage never invokes it or refetches |
51
54
  | `actionsAriaLabel` | `string` | accessible name of the actions menubar, default `'Actions'` |
55
+ | `globalSearchPlaceholder` / `globalSearchAriaLabel` | `string` | search copy and accessible name |
56
+ | `paginatorClassName` / `paginatorAriaLabels` | class / label overrides | paginator presentation and localization |
52
57
  | `tableClassName` | `string` | class on the inner table |
53
58
  | `tablePt` | `DataTableParts` | per-part attributes on the inner data table (`tablePtOptions`/`tableUnstyled` are accepted no-ops) |
54
59
  | `menubarClassName` | `string` | class on the action menubar |
@@ -61,8 +66,14 @@ Three static members exist:
61
66
  There is no `observableQuery` prop. `DataPage` inspects the query prototype at
62
67
  render time: a snapshot query renders the snapshot table, anything else renders
63
68
  the observable table. Pass an observable query proxy and the page pushes
64
- updates automatically; pass a snapshot query and re-fetch through `onRefresh`
65
- after a command succeeds.
69
+ updates automatically. There is no snapshot refresh handle on DataPage;
70
+ `onRefresh` is only a caller-owned callback forwarded to the details component.
71
+ Do not promise it will rerun the table's query.
72
+
73
+ Until the first result, query tables show a loading row, not an empty row. Error
74
+ and unauthorized results show a failure row; `empty-row` means a real empty
75
+ result. While refreshing, the table marks `aria-busy`. Style status rows with
76
+ `tablePt.loadingRow/loadingCell/failureRow/failureCell`.
66
77
 
67
78
  ## `MenuItemProps`
68
79
 
@@ -112,9 +123,10 @@ declaration the table reads.
112
123
  | `dataType` | `'text' \| 'numeric' \| 'date' \| 'boolean'` |
113
124
  | `showFilterMatchModes` | `boolean` |
114
125
  | `filterElement` | `(options: ColumnFilterElementOptions) => ReactNode` |
126
+ | `filterOptions` | `{ label: string; value: unknown }[]` — list choices instead of a free-form input |
115
127
  | `filterLabels` | `Partial<ColumnFilterMenuLabels>` |
116
128
  | `filterPt` | `ColumnFilterMenuParts` — parts of the filter popup |
117
- | `selectionMode` | `'single'` — the only implemented value; there is no checkbox multi-selection |
129
+ | `selectionMode` | `'single' \| 'multiple'` — selectors, including checkbox multi-selection |
118
130
  | `style` / `className` | `React.CSSProperties` / `string` |
119
131
  | `headerStyle` / `headerClassName` | `React.CSSProperties` / `string` |
120
132
  | `bodyStyle` / `bodyClassName` | `React.CSSProperties` / `string` |
@@ -128,10 +140,8 @@ Use `body` for a computed or formatted cell:
128
140
  ## Type name caution
129
141
 
130
142
  `ColumnProps` from `@cratis/components/DataPage` is the **column declaration**
131
- type re-exported from `DataTables` (the explicit named re-export shadows the
132
- `DataPage.Columns` wrapper's own `ColumnProps`, which is not reachable from the
133
- subpath). Import it from `@cratis/components/DataTables` when you want the
134
- reference to say so.
143
+ type re-exported from `DataTables`. `ColumnsProps` is also exported from the
144
+ DataPage subpath: it is the props type of the `DataPage.Columns` wrapper.
135
145
 
136
146
  ## Layout
137
147
 
@@ -41,13 +41,17 @@ Both components take the same prop names:
41
41
  | Prop | Type | Notes |
42
42
  | --- | --- | --- |
43
43
  | `query` | `Constructor<TQuery>` | required |
44
- | `emptyMessage` | `string` | required |
44
+ | `emptyMessage` | `string` | required; only for a real empty result |
45
+ | `loadingMessage` / `failureMessage` / `unauthorizedMessage` | `ReactNode` | default `messages.dataTable.loading/failed/unauthorized` |
45
46
  | `children` | `ReactNode` | the `Column` declarations |
46
47
  | `queryArguments` | `TArguments` | forwarded to the query |
47
48
  | `dataKey` | `string \| undefined` | row identity |
48
- | `selection` | `TDataType \| undefined \| null` | controlled selection |
49
+ | `selection` | `TDataType \| undefined \| null` | controlled single selection |
50
+ | `selectionMode` | `'single' \| 'multiple'` | default single |
51
+ | `selectedItems` / `onSelectedItemsChange` | `TDataType[]` / `(items: TDataType[]) => void` | checkbox multi-selection |
49
52
  | `onSelectionChange` | `(event: DataTableSelectionChangeEvent<TDataType>) => void` | `event.value` is the row or `null` |
50
53
  | `globalFilterFields` | `string[] \| undefined` | enables the search box |
54
+ | `globalSearchPlaceholder` / `globalSearchAriaLabel` | `string` | search copy and accessible name |
51
55
  | `defaultFilters` | `DataTableFilterMeta` | initial filter state |
52
56
  | `className` | `string` | |
53
57
  | `pt` | `DataTableParts` | per-part attributes (`ptOptions`/`unstyled` are accepted no-ops) |
@@ -69,6 +73,10 @@ Both components take the same prop names:
69
73
  </DataTableForQuery>
70
74
  ```
71
75
 
76
+ Query tables show loading until the first result, failure on error/unauthorized,
77
+ and `empty-row` only for a real empty result. During refresh the table marks
78
+ `aria-busy`; status parts are `loadingRow`, `loadingCell`, `failureRow`, `failureCell`.
79
+
72
80
  ## Paging, sorting and filtering scope
73
81
 
74
82
  Column sorting and filtering — and the search box — apply to the **currently
@@ -96,11 +104,17 @@ interface DataTableSelectionChangeEvent<TData> {
96
104
  Add a selection column with `<Column selectionMode='single' headerStyle={{ width: '3rem' }} />`
97
105
  when you want an explicit selector rather than row click selection.
98
106
 
107
+ For checkboxes, use `selectionMode='multiple'` on the table and column, with
108
+ `selectedItems` / `onSelectedItemsChange` (receives the array, not an event).
109
+ Select-all covers only rows left visible by filtering, not unloaded pages;
110
+ localize its name with `messages.dataTable.selectAllRows`.
111
+
99
112
  ## Column filtering
100
113
 
101
114
  Set `filter` on a column to get a per-column filter menu. `dataType` picks the
102
115
  match modes (`'text'`, `'numeric'`, `'date'`, `'boolean'`; default `'text'`),
103
- `showFilterMatchModes={false}` hides the mode picker, and `filterElement`
116
+ `showFilterMatchModes={false}` hides the mode picker. `filterOptions` takes
117
+ `{ label, value }[]` for list choices instead of free-form input; `filterElement`
104
118
  replaces the editor entirely:
105
119
 
106
120
  ```tsx
@@ -85,6 +85,9 @@ The most-used props:
85
85
  | --- | --- |
86
86
  | `command` | the generated command class |
87
87
  | `title` | dialog header |
88
+ | `subtitle` / `closeIcon` | secondary header content / dismissal glyph (`ReactNode`) |
89
+ | `placement` | `'center' \| 'start' \| 'end'`; RTL-aware side sheets |
90
+ | `confirmBeforeExecute` | `(values) => boolean \| Promise<boolean>`; pre-execution approval |
88
91
  | `okLabel` / `cancelLabel` | button labels (`'Ok'` / `'Cancel'` by default) |
89
92
  | `initialValues` | synchronous baseline; also the change-tracking baseline |
90
93
  | `currentValues` | reactive overlay for late-loading values |
@@ -99,6 +102,10 @@ The most-used props:
99
102
  | `dismissable` | X, Escape, and backdrop dismissal |
100
103
  | `pt` | `DialogParts` — per-part attributes (`backdrop`, `positioner`, `root`, `header`, `title`, `close`, `content`, `footer`, `confirm`, `cancel`); `ptOptions`/`unstyled` are accepted no-ops |
101
104
 
105
+ Dialog presentation props, including `subtitle`, `placement` and `closeIcon`,
106
+ are forwarded to the dialog (4.14.1+), not the form. `children` may also be a
107
+ render function receiving the command form context (4.25.1+).
108
+
102
109
  `CommandDialog.Column` exists for multi-column layouts:
103
110
 
104
111
  ```tsx
@@ -114,8 +121,10 @@ The most-used props:
114
121
 
115
122
  ### Execution flow
116
123
 
117
- On confirm, `CommandDialog` applies `onBeforeExecute`, sets busy, executes the
118
- command, and on failure calls `onValidationFailure(result.validationResults)`
124
+ On confirm, after validation, `CommandDialog` applies `onBeforeExecute` and
125
+ awaits `confirmBeforeExecute` when supplied. Only `true` executes; fields are
126
+ disabled while it is pending, and changed command values discard approval.
127
+ The command then executes, and on failure calls `onValidationFailure(result.validationResults)`
119
128
  or `onFailed(result)` and **keeps the dialog open**. On success it calls
120
129
  `onSuccess(result.response)` and then the close gate.
121
130
 
@@ -174,7 +183,9 @@ selection — renaming a command property produces a compile error at every
174
183
  binding.
175
184
 
176
185
  `AutoCommandForm` renders a field per command property from the generated
177
- property descriptors, with `exclude` for the ones you do not want:
186
+ property descriptors, with `exclude` for the ones you do not want and `footer`
187
+ for custom footer content. Generated fields bind to their own property; this
188
+ requires Arc and Arc React >=22.16.0:
178
189
 
179
190
  ```tsx
180
191
  <AutoCommandForm command={RegisterInvoice} exclude={['invoiceId']} />
@@ -25,7 +25,12 @@ Three different claims are mixed in any "screen to page" mapping. Keep them apar
25
25
  | --- | --- | --- |
26
26
  | What each `screen`, `form` and interaction construct means | Verified | Screenplay `v4.66.0`: `Documentation/screenplay/{screens,forms,interactions}.md` |
27
27
  | What Stage does with a screen | Verified: it draws it through Scene, it does not write a React page | Stage `v4.24.0`: `Documentation/reference/stage-rendering.md` ("It does not generate screens for it"), `Documentation/reference/default-scene-composition.md` ("does not ... generate per-screen TypeScript components"), `Source/Contracts/Scene/ScreenDirectiveConverter.cs` (`data`, `action`, `section`, `title`, `table`, `summary` become Scene elements) |
28
- | Which Components and Arc API gives a page the same behavior | Verified API; the pairing is this skill's convention | `@cratis/components` `v4.6.0` (`DataPage`, `DataTables`, `CommandDialog`, `CommandForm`) and the sibling references |
28
+ | Which Components and Arc API gives a page the same behavior | Verified API; the pairing is this skill's convention | `@cratis/components` `v4.26.4` (`DataPage`, `DataTables`, `CommandDialog`, `CommandForm`) and the sibling references |
29
+
30
+ A hand-written Arc React page and a Scene-rendered screen are different surfaces;
31
+ they share Components, not ownership or runtime APIs. Scene is the experimental
32
+ UI model/runtime in Stage output; read `cratis-stage-rendering-and-sandbox`
33
+ `references/scene-runtime.md` when inspecting that generated surface.
29
34
 
30
35
  So no product source maps a `.play` screen to an Arc React page. A hand-written
31
36
  page is a **gap-fill** (`cratis-screenplay-render-and-gap-fill`) with the `.play`
@@ -4,7 +4,7 @@ No TrogonStack text is adapted in this skill. Nebulit material is credited in th
4
4
 
5
5
  | Item | Source | Licence | Treatment | Where in this skill |
6
6
  |---|---|---|---|---|
7
- | Component APIs, props and hooks | Cratis Components 4.6.0 and Arc, see *Verified product sources* | MIT | original | SKILL.md, references/ |
7
+ | Component APIs, props and hooks | Cratis Components 4.26.4 and Arc, see *Verified product sources* | MIT | original | SKILL.md, references/ |
8
8
  | Screenplay and Stage facts in the screen mapping | Cratis/Screenplay v4.66.0 and Cratis/Stage v4.24.0 documentation and source | MIT | original | references/from-screenplay.md |
9
9
 
10
10
  ## Adapted closely (Martin Dilger and Nebulit GmbH)
@@ -220,10 +220,20 @@ view model as `ICommandScope`. It exposes `hasChanges`, `isPerforming`,
220
220
  `execute()` (which runs only the commands that have changes), and
221
221
  `revertChanges()`.
222
222
 
223
+ At Arc v22.75.0 `CommandForm` hides raw server exception text by default
224
+ ("An unexpected error occurred. Please try again."). Customize `exceptionMessage`
225
+ or `exceptionDisplayComponent` (`ExceptionDisplayProps`); `showErrors={false}`
226
+ hides built-in display. Dynamic accessors need `fieldName`; custom field validation
227
+ failures block submit. `useIdentity(type)` deserializes typed details.
228
+ Sources: `Source/JavaScript/Arc.React/Arc.tsx` and
229
+ `commands/CommandForm/CommandForm.tsx` at v22.75.0.
230
+
223
231
  ## `<Arc>` configuration
224
232
 
225
233
  The top-level provider configures the microservice name, API base path, and
226
- query transport. Its props include `microservice`, `origin`, `basePath`,
234
+ query transport. Verified at Arc v22.75.0: `basePath` is deprecated and does not
235
+ configure routing; use `apiBasePath` for APIs, router basename for client routing
236
+ and `UsePathBase` on the host. Its props include `microservice`, `origin`,
227
237
  `apiBasePath`, `httpHeadersCallback` (merged into every request — bearer and
228
238
  tenant headers), `detailsType`, `queryTransportMethod`, `queryConnectionCount`,
229
239
  `queryDirectMode`, `observableQueryTransferMode`, and `queryCacheRetentionMs`.
@@ -9,6 +9,11 @@
9
9
  {
10
10
  "kind": "skill-contains",
11
11
  "value": "DataPage"
12
- }
12
+ },
13
+ { "kind": "skill-contains", "value": "DataPage has no snapshot refresh handle" },
14
+ { "kind": "skill-contains", "value": "Mount exactly one toaster" },
15
+ { "kind": "skill-contains", "value": "4.26.4" },
16
+ { "kind": "skill-contains", "value": "checkbox multi-selection", "file": "references/data-tables.md" },
17
+ { "kind": "skill-contains", "value": "DataPage never invokes it or refetches", "file": "references/data-page.md" }
13
18
  ]
14
19
  }