@cratis/pi 7.34.1 → 7.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package/corpus/agents/security-reviewer.md +1 -0
- package/package/corpus/agents/spec-writer.md +1 -1
- package/package/corpus/harnesses/pi/extensions/shared/rules.ts +3 -1
- package/package/corpus/hooks/scripts/cratis-nuget-pins.txt +7 -6
- package/package/corpus/hooks/scripts/cratis-release-notes-reviewed.cjs +7 -6
- package/package/corpus/hooks/scripts/cratis-store-mutations.json +7 -3
- package/package/corpus/product-sync.json +896 -0
- package/package/corpus/prompts/add-business-rule.prompt.md +1 -1
- package/package/corpus/prompts/ship-changes.prompt.md +2 -2
- package/package/corpus/rules/ai-distribution.md +31 -3
- package/package/corpus/rules/application-profile.md +2 -1
- package/package/corpus/rules/components.md +66 -7
- package/package/corpus/rules/concepts.md +11 -3
- package/package/corpus/rules/csharp.md +3 -1
- package/package/corpus/rules/dialogs.md +9 -0
- package/package/corpus/rules/efcore.md +1 -1
- package/package/corpus/rules/elixir.md +49 -0
- package/package/corpus/rules/framework.md +5 -3
- package/package/corpus/rules/general.md +1 -0
- package/package/corpus/rules/glossary.md +4 -4
- package/package/corpus/rules/go-engineering.md +60 -0
- package/package/corpus/rules/go.md +115 -0
- package/package/corpus/rules/java.md +5 -2
- package/package/corpus/rules/kotlin.md +7 -5
- package/package/corpus/rules/orleans.md +65 -9
- package/package/corpus/rules/profiles.md +43 -6
- package/package/corpus/rules/pull-requests.md +3 -3
- package/package/corpus/rules/react.md +8 -1
- package/package/corpus/rules/reactors.md +27 -3
- package/package/corpus/rules/specs.csharp.md +11 -4
- package/package/corpus/rules/specs.scenarios.csharp.md +35 -4
- package/package/corpus/rules/specs.typescript.md +2 -1
- package/package/corpus/rules/storybook.md +1 -1
- package/package/corpus/rules/typescript.md +1 -1
- package/package/corpus/rules/vertical-slices.md +37 -5
- package/package/corpus/skills/cratis-application-react-specifications/SKILL.md +4 -2
- package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +18 -8
- package/package/corpus/skills/cratis-application-slice-specifications/references/query-and-decision-scenarios.md +65 -0
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +53 -57
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authentication.md +38 -42
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +18 -7
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authproxy.md +30 -0
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/frontend.md +12 -9
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/local-development.md +9 -9
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/observable-emission-guards.md +8 -5
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/tenancy.md +20 -4
- package/package/corpus/skills/cratis-arc-command/SKILL.md +32 -10
- package/package/corpus/skills/cratis-arc-command/references/command-result.md +12 -5
- package/package/corpus/skills/cratis-arc-command/references/decisions-and-routing.md +95 -0
- package/package/corpus/skills/cratis-arc-command/references/generated-values.md +3 -2
- package/package/corpus/skills/cratis-arc-command/references/handler-shapes.md +8 -8
- package/package/corpus/skills/cratis-arc-command/references/proxy-generation.md +22 -3
- package/package/corpus/skills/cratis-arc-command/references/read-model-injection.md +13 -1
- package/package/corpus/skills/cratis-arc-command-execution/SKILL.md +19 -9
- package/package/corpus/skills/cratis-arc-command-kotlin/SKILL.md +44 -18
- package/package/corpus/skills/cratis-arc-command-kotlin/references/read-model-naming.md +29 -0
- package/package/corpus/skills/cratis-arc-command-operation/SKILL.md +10 -9
- package/package/corpus/skills/cratis-arc-command-operation/references/execution-and-recovery.md +2 -2
- package/package/corpus/skills/cratis-arc-command-operation/references/testing.md +4 -3
- package/package/corpus/skills/cratis-arc-command-typescript/SKILL.md +42 -22
- package/package/corpus/skills/cratis-arc-command-typescript/references/chronicle-events.md +36 -5
- package/package/corpus/skills/cratis-arc-command-typescript/references/command-operations.md +114 -0
- package/package/corpus/skills/cratis-arc-command-typescript/references/hosting-and-storage.md +37 -16
- package/package/corpus/skills/cratis-arc-command-typescript/references/identity-and-introspection.md +88 -0
- package/package/corpus/skills/cratis-arc-command-typescript/references/observability-and-host-scopes.md +25 -0
- package/package/corpus/skills/cratis-arc-command-typescript/references/proxy-generation.md +35 -4
- package/package/corpus/skills/cratis-arc-command-typescript/references/slice-layout.md +11 -0
- package/package/corpus/skills/cratis-arc-command-typescript/verification.json +8 -1
- package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +49 -19
- package/package/corpus/skills/cratis-arc-ef-core-migration/SKILL.md +12 -6
- package/package/corpus/skills/cratis-arc-go/SKILL.md +148 -0
- package/package/corpus/skills/cratis-arc-go/references/queries.md +80 -0
- package/package/corpus/skills/cratis-arc-hosting/SKILL.md +96 -0
- package/package/corpus/skills/cratis-arc-hosting/references/integrations-and-publish.md +80 -0
- package/package/corpus/skills/cratis-arc-identity-and-tenancy-kotlin/SKILL.md +137 -0
- package/package/corpus/skills/cratis-arc-observable-query-http/SKILL.md +20 -2
- package/package/corpus/skills/cratis-arc-query-kotlin/SKILL.md +26 -6
- package/package/corpus/skills/cratis-arc-query-paging/SKILL.md +25 -20
- package/package/corpus/skills/cratis-arc-query-typescript/SKILL.md +32 -6
- package/package/corpus/skills/cratis-arc-query-typescript/references/storage-observation-and-compliance.md +66 -0
- package/package/corpus/skills/cratis-arc-query-typescript/verification.json +5 -1
- package/package/corpus/skills/cratis-arc-react-page/SKILL.md +24 -13
- package/package/corpus/skills/cratis-arc-react-page/references/data-page.md +20 -10
- package/package/corpus/skills/cratis-arc-react-page/references/data-tables.md +17 -3
- package/package/corpus/skills/cratis-arc-react-page/references/dialogs.md +14 -3
- package/package/corpus/skills/cratis-arc-react-page/references/from-screenplay.md +6 -1
- package/package/corpus/skills/cratis-arc-react-page/references/provenance.md +1 -1
- package/package/corpus/skills/cratis-arc-react-page/references/queries-and-commands.md +11 -1
- package/package/corpus/skills/cratis-arc-react-page/verification.json +6 -1
- package/package/corpus/skills/cratis-arc-spring-data-kotlin/SKILL.md +163 -0
- package/package/corpus/skills/cratis-arc-testing-kotlin/SKILL.md +131 -0
- package/package/corpus/skills/cratis-arc-validation-kotlin/SKILL.md +44 -11
- package/package/corpus/skills/cratis-arc-validation-typescript/SKILL.md +5 -3
- package/package/corpus/skills/cratis-chronicle-cli-operations/SKILL.md +79 -25
- package/package/corpus/skills/cratis-chronicle-cli-operations/references/command-effects.md +57 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/SKILL.md +87 -99
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/additional-surfaces.md +65 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/client-construction.md +42 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/compatibility-check.md +12 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/discovery.md +43 -19
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/hosting.md +29 -1
- package/package/corpus/skills/cratis-chronicle-client-elixir/SKILL.md +158 -162
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/append-api.md +36 -15
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/compliance.md +32 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/connections.md +56 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/event-sources.md +64 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/pitfalls.md +25 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/projections.md +48 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/upgrading.md +34 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/variants.md +13 -5
- package/package/corpus/skills/cratis-chronicle-client-elixir/verification.json +23 -0
- package/package/corpus/skills/cratis-chronicle-client-go/SKILL.md +162 -0
- package/package/corpus/skills/cratis-chronicle-client-go/references/projections.md +73 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/SKILL.md +87 -88
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/connection-lifecycle.md +13 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/discovery-and-registration.md +14 -4
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/event-sources.md +65 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/options.md +29 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/spring-boot.md +13 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/variants.md +5 -4
- package/package/corpus/skills/cratis-chronicle-client-typescript/SKILL.md +165 -156
- package/package/corpus/skills/cratis-chronicle-client-typescript/references/read-models-and-projections.md +54 -11
- package/package/corpus/skills/cratis-chronicle-client-typescript/references/testing.md +126 -0
- package/package/corpus/skills/cratis-chronicle-client-typescript/references/variants.md +3 -5
- package/package/corpus/skills/cratis-chronicle-client-typescript/verification.json +19 -0
- package/package/corpus/skills/cratis-chronicle-compliance/SKILL.md +36 -13
- package/package/corpus/skills/cratis-chronicle-decision-reads/SKILL.md +110 -0
- package/package/corpus/skills/cratis-chronicle-decision-reads/references/admission-and-ownership.md +57 -0
- package/package/corpus/skills/cratis-chronicle-decision-reads/verification.json +12 -0
- package/package/corpus/skills/cratis-chronicle-event-constraints/SKILL.md +58 -19
- package/package/corpus/skills/cratis-chronicle-event-constraints/references/closing-streams.md +73 -0
- package/package/corpus/skills/cratis-chronicle-event-modeling/SKILL.md +32 -3
- package/package/corpus/skills/cratis-chronicle-event-specifications/SKILL.md +18 -5
- package/package/corpus/skills/cratis-chronicle-event-type-migration/SKILL.md +32 -2
- package/package/corpus/skills/cratis-chronicle-hosting/SKILL.md +134 -0
- package/package/corpus/skills/cratis-chronicle-hosting/references/operations.md +89 -0
- package/package/corpus/skills/cratis-chronicle-hosting/verification.json +14 -0
- package/package/corpus/skills/cratis-chronicle-mcp-inspection/SKILL.md +93 -66
- package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/blocked-tools.md +21 -7
- package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/deployment.md +77 -0
- package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/observational-tools.md +46 -4
- package/package/corpus/skills/cratis-chronicle-multi-tenancy/SKILL.md +15 -1
- package/package/corpus/skills/cratis-chronicle-projection/SKILL.md +44 -10
- package/package/corpus/skills/cratis-chronicle-projection/references/fluent-builder.md +7 -1
- package/package/corpus/skills/cratis-chronicle-projection/references/model-bound-attributes.md +8 -0
- package/package/corpus/skills/cratis-chronicle-reactor/SKILL.md +85 -105
- package/package/corpus/skills/cratis-chronicle-reactor/references/specifications.md +20 -1
- package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +2 -2
- package/package/corpus/skills/cratis-chronicle-read-model/references/queries.md +35 -16
- package/package/corpus/skills/cratis-chronicle-read-model-specifications/SKILL.md +15 -3
- package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +23 -4
- package/package/corpus/skills/cratis-chronicle-web-workbench/SKILL.md +40 -15
- package/package/corpus/skills/cratis-cli-terminal-workbench/SKILL.md +20 -6
- package/package/corpus/skills/cratis-code-review/SKILL.md +25 -3
- package/package/corpus/skills/cratis-components-accessibility/SKILL.md +20 -4
- package/package/corpus/skills/cratis-components-schema-editor/SKILL.md +40 -28
- package/package/corpus/skills/cratis-components-schema-editor/references/tree-layout.md +62 -0
- package/package/corpus/skills/cratis-components-schema-editor/verification.json +14 -0
- package/package/corpus/skills/cratis-components-stepper-command-dialog/SKILL.md +16 -8
- package/package/corpus/skills/cratis-components-styling/SKILL.md +57 -20
- package/package/corpus/skills/cratis-components-styling/verification.json +13 -0
- package/package/corpus/skills/cratis-components-toolbar/SKILL.md +37 -7
- package/package/corpus/skills/cratis-components-toolbar/verification.json +12 -0
- package/package/corpus/skills/cratis-engineering-csharp-conventions/SKILL.md +6 -0
- package/package/corpus/skills/cratis-engineering-csharp-conventions/references/exceptions-logging-and-di.md +5 -3
- package/package/corpus/skills/cratis-fundamentals-concept/SKILL.md +19 -6
- package/package/corpus/skills/cratis-fundamentals-concept/references/typescript-concepts.md +97 -0
- package/package/corpus/skills/cratis-fundamentals-concept/verification.json +4 -1
- package/package/corpus/skills/cratis-fundamentals-concept-go/SKILL.md +112 -0
- package/package/corpus/skills/cratis-fundamentals-type-discovery/SKILL.md +54 -17
- package/package/corpus/skills/cratis-fundamentals-type-discovery/verification.json +14 -0
- package/package/corpus/skills/cratis-lens-browser-extension/SKILL.md +55 -28
- package/package/corpus/skills/cratis-performance-review/SKILL.md +5 -2
- package/package/corpus/skills/cratis-release-notes/SKILL.md +3 -1
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +5 -4
- package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +7 -11
- package/package/corpus/skills/cratis-screenplay-command-surface/references/compliance.md +26 -6
- package/package/corpus/skills/cratis-screenplay-command-surface/references/enum-numbers.md +4 -2
- package/package/corpus/skills/cratis-screenplay-command-surface/references/generated-values-and-responses.md +4 -1
- package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +7 -1
- package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +3 -2
- package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md +6 -2
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +1 -0
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generate-notes.md +34 -4
- package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +17 -24
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +1 -1
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +19 -2
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +11 -3
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/property-links.md +90 -4
- package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +19 -2
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +3 -1
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +3 -1
- package/package/corpus/skills/cratis-screenplay-specifications/references/examples-and-routes.md +48 -0
- package/package/corpus/skills/cratis-screenplay-specifications/verification.json +3 -1
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +4 -2
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +5 -4
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +8 -6
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +8 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +4 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/doc-contradictions.md +7 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +24 -11
- package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +10 -4
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1543 -131
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/verdicts.md +9 -3
- package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +23 -7
- package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +1 -1
- package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +2 -0
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/screen-composition-contract.md +27 -9
- package/package/corpus/skills/cratis-security-review/SKILL.md +9 -3
- package/package/corpus/skills/cratis-security-review/references/arc-boundaries.md +59 -0
- package/package/corpus/skills/cratis-specification-by-example/SKILL.md +7 -0
- package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +43 -11
- package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md +16 -4
- package/package/corpus/skills/cratis-specifications-csharp/references/csharp-patterns.md +18 -5
- package/package/corpus/skills/cratis-specifications-csharp/references/integration-specs.md +21 -0
- package/package/corpus/skills/cratis-specifications-csharp/references/shared-lifecycle.md +34 -0
- package/package/corpus/skills/cratis-specifications-csharp/verification.json +13 -0
- package/package/corpus/skills/cratis-specifications-typescript/SKILL.md +14 -5
- package/package/corpus/skills/cratis-specifications-typescript/verification.json +12 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +8 -2
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +6 -3
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/rendered-application.md +10 -1
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/scene-runtime.md +75 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +5 -0
- package/package/corpus/skills/cratis-studio-mcp-safety-guidance/SKILL.md +14 -1
- package/package/profile-catalog.json +68 -1
- package/package.json +1 -1
- package/src/index.ts +3 -1
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cratis-arc-spring-data-kotlin
|
|
3
|
+
description: Use Spring Data JPA or MongoDB with Kotlin or Java Arc read models — repository-backed queries and paging, command current-state resolution, observable snapshots, concept converters, certified tenant storage and explicit transaction opt-ins. Use when wiring JVM Arc persistence or database-backed observations. Do not use for Chronicle projections, C# EF Core, query transport alone, or authentication and tenant resolution alone.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!-- Copyright (c) Cratis. All rights reserved. -->
|
|
8
|
+
<!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
|
|
9
|
+
|
|
10
|
+
# Use Spring Data with JVM Arc
|
|
11
|
+
|
|
12
|
+
Keep Spring Data responsible for persistence and Arc responsible for the
|
|
13
|
+
model-bound command/query pipeline. Repository injection alone does not isolate
|
|
14
|
+
tenants or turn a repository into an observable source.
|
|
15
|
+
|
|
16
|
+
## Verified product sources
|
|
17
|
+
|
|
18
|
+
Verified at `Arc.Kotlin v7.7.0`: `Integrations/SpringDataJpa`,
|
|
19
|
+
`Integrations/SpringDataMongo` (observable query services/extensions, contextual
|
|
20
|
+
read-model providers, tenant access and converters) and
|
|
21
|
+
`Documentation/guides/spring-data/*.mdx`.
|
|
22
|
+
Add `io.cratis:arc-spring-data-jpa:7.7.0` or
|
|
23
|
+
`io.cratis:arc-spring-data-mongodb:7.7.0`; both include the Arc Spring Boot
|
|
24
|
+
starter and corresponding Spring Data starter. Spring owns repository discovery,
|
|
25
|
+
datasource/entity manager, Mongo client and their standard configuration.
|
|
26
|
+
|
|
27
|
+
## Query a mapped read model
|
|
28
|
+
|
|
29
|
+
JPA example (requires the application's normal JPA entity/no-arg setup):
|
|
30
|
+
|
|
31
|
+
```kotlin
|
|
32
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
33
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
34
|
+
|
|
35
|
+
import io.cratis.arc.artifacts.FromServices
|
|
36
|
+
import io.cratis.arc.artifacts.ReadModel
|
|
37
|
+
import jakarta.persistence.Entity
|
|
38
|
+
import jakarta.persistence.Id
|
|
39
|
+
import org.springframework.data.jpa.repository.JpaRepository
|
|
40
|
+
|
|
41
|
+
@Entity
|
|
42
|
+
@ReadModel
|
|
43
|
+
data class TaskView(@Id val id: String = "", val title: String = "") {
|
|
44
|
+
companion object {
|
|
45
|
+
@JvmStatic
|
|
46
|
+
fun all(@FromServices tasks: TaskViewRepository): List<TaskView> = tasks.findAll()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface TaskViewRepository : JpaRepository<TaskView, String>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The same injection pattern works with `MongoRepository`, fragments or an
|
|
54
|
+
application query service. Java uses static query methods on its mapped type.
|
|
55
|
+
Protect the query with the application's authorization policy; mapping does
|
|
56
|
+
not make it safe to expose anonymously.
|
|
57
|
+
|
|
58
|
+
A query can declare exact non-null Spring Data Commons `Pageable` and `Sort`.
|
|
59
|
+
KSP binds them from the captured `QueryRequest`, not thread-local request scope.
|
|
60
|
+
Such queries must return exact `org.springframework.data.domain.Page<T>`;
|
|
61
|
+
Arc normalizes it into `QueryPage<T>` before renderers, preserving pre-page
|
|
62
|
+
total count. Page size zero means unpaged; blank sort field means unsorted.
|
|
63
|
+
Do not confuse Spring Data `Page<T>` with a nonexistent Arc `Page<T>`.
|
|
64
|
+
|
|
65
|
+
## Current state in a command
|
|
66
|
+
|
|
67
|
+
Mapped `@ReadModel` types are owned by contextual
|
|
68
|
+
`CanResolveReadModelForCommand` providers. JPA claims `DECLARED` ownership;
|
|
69
|
+
MongoDB claims `FALLBACK`, so an explicit JPA/Chronicle/application owner wins.
|
|
70
|
+
Equal-strength claims fail startup. Registry-owned model parameters resolve
|
|
71
|
+
before ordinary services, using the generated command key and captured tenant.
|
|
72
|
+
Keys must already match the persistence identifier type, not need coercion.
|
|
73
|
+
Missing required rows or keys yield `dependencyUnavailable`; nullable Kotlin
|
|
74
|
+
parameters/Java `Optional` observe absence. Resolver failures remain exceptions.
|
|
75
|
+
|
|
76
|
+
## Stream storage snapshots
|
|
77
|
+
|
|
78
|
+
Mongo example excerpt inside a `TaskView` companion object (the type has an
|
|
79
|
+
`active` property and is Mongo-mapped):
|
|
80
|
+
|
|
81
|
+
```kotlin
|
|
82
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
83
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
84
|
+
|
|
85
|
+
import io.cratis.arc.springdata.mongodb.MongoObservableQuery
|
|
86
|
+
import io.cratis.arc.springdata.mongodb.observe
|
|
87
|
+
import kotlinx.coroutines.flow.Flow
|
|
88
|
+
import org.springframework.data.mongodb.core.query.Criteria
|
|
89
|
+
|
|
90
|
+
@JvmStatic
|
|
91
|
+
fun active(@FromServices queries: MongoObservableQuery): Flow<List<TaskView>> =
|
|
92
|
+
queries.observe<TaskView>(Criteria.where("active").`is`(true))
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`observe`, `observeList`, `observeSingle`, `observeById`, `observeShared` are
|
|
96
|
+
extensions on Arc's `MongoObservableQuery` or `JpaObservableQuery`, not foreign
|
|
97
|
+
repositories or collections. Import the extensions from the store's package.
|
|
98
|
+
Flows are cold and close their subscription on cancellation. `observeShared`
|
|
99
|
+
explicitly shares one subscription and replays the latest complete snapshot.
|
|
100
|
+
Java uses `observePublisher` or `MongoObservations`/`JpaObservations` helpers.
|
|
101
|
+
|
|
102
|
+
MongoDB change streams require a replica set or sharded cluster; invalidations
|
|
103
|
+
cause a fresh filtered snapshot so rows that stop matching disappear. JPA
|
|
104
|
+
observations are **in-process only**: publish committed changes through
|
|
105
|
+
`DatabaseChangePublisher`. There is no silent polling or cross-process JPA
|
|
106
|
+
notification. A tenant label on a JPA notification is not storage isolation.
|
|
107
|
+
|
|
108
|
+
## Tenant-bound storage and concepts
|
|
109
|
+
|
|
110
|
+
Resolve/authenticate the tenant using `cratis-arc-identity-and-tenancy-kotlin`
|
|
111
|
+
first. Then select certified isolated stores:
|
|
112
|
+
|
|
113
|
+
- JPA: an application `JpaPersistenceUnitResolver` returns a `JpaPersistenceUnit`
|
|
114
|
+
certified for the requested tenant/namespace and mapped type.
|
|
115
|
+
- Mongo: a `TenantAwareMongoOperationsResolver` returns `TenantMongoOperations`
|
|
116
|
+
for the exact tenant. Unknown tenants throw; mismatched certificates fail,
|
|
117
|
+
never fall back to a default database.
|
|
118
|
+
- `TenantContextMongoAccess.operations()` resolves the ambient tenant on **each
|
|
119
|
+
call**, not at construction. Establish `withTenant` explicitly; the command
|
|
120
|
+
pipeline does not create this ambient scope for you. Java on a plain thread
|
|
121
|
+
uses `operationsForCurrentTenant()` inside `TenantContextBridge.withTenant`;
|
|
122
|
+
a Java command handler uses the explicit-tenant overload instead of blocking
|
|
123
|
+
inside its coroutine. The auto-configured access has no fallback tenant.
|
|
124
|
+
|
|
125
|
+
Plain injected repositories are not automatically routed by tenant. Native
|
|
126
|
+
collection access uses Arc's `NamingPolicy`, while Spring Data operations respect
|
|
127
|
+
`@Document`; choose deliberately. For Chronicle projection collection alignment,
|
|
128
|
+
read [../cratis-arc-command-kotlin/references/read-model-naming.md](../cratis-arc-command-kotlin/references/read-model-naming.md)
|
|
129
|
+
when upgrading or changing names.
|
|
130
|
+
|
|
131
|
+
Concept persistence needs store-specific converters: JPA attribute converters
|
|
132
|
+
(or embedded ids for composite identity), Mongo concrete scalar read/write pairs.
|
|
133
|
+
Do not persist a generic `ConceptAs` wrapper as an arbitrary object or assume a
|
|
134
|
+
JSON converter also handles BSON/JPA. Read the tagged `concepts-jpa.mdx` and
|
|
135
|
+
`concepts-mongodb.mdx` guides for the actual identifier type and converter registration.
|
|
136
|
+
|
|
137
|
+
## Transactions are explicit, thread-bound opt-ins
|
|
138
|
+
|
|
139
|
+
`cratis.arc.spring-data.jpa.command-transactions-enabled` and
|
|
140
|
+
`cratis.arc.spring-data.mongodb.command-transactions-enabled` default to false.
|
|
141
|
+
Enable only for a verified fixed store and identity-aligned transaction manager.
|
|
142
|
+
Dynamic tenant stores are not auto-enrolled. Even enabled, command persistence
|
|
143
|
+
must not suspend or switch threads: imperative Spring transactions are not
|
|
144
|
+
coroutine-safe. They commit only a successful final `CommandResult` and roll
|
|
145
|
+
back failures when completing on the opening thread.
|
|
146
|
+
|
|
147
|
+
There is **no distributed transaction** across JPA, MongoDB and Chronicle.
|
|
148
|
+
Chronicle completion follows local scopes, but a local store may already commit
|
|
149
|
+
before another store or Chronicle fails. Define reconciliation for partial or
|
|
150
|
+
indeterminate outcomes rather than claiming atomic cross-store success.
|
|
151
|
+
|
|
152
|
+
## Verify
|
|
153
|
+
|
|
154
|
+
- Run `./gradlew build`, pipeline specs via `cratis-arc-testing-kotlin`, and
|
|
155
|
+
real-store tests for converters, paging counts and tenant isolation.
|
|
156
|
+
- Verify missing/unknown tenants cannot access the default store.
|
|
157
|
+
- Exercise Mongo snapshots against a real replica set; an in-memory emulator
|
|
158
|
+
cannot prove change streams. Verify cancellation releases the cursor.
|
|
159
|
+
- For JPA, verify committed notifications, rollback suppression and the intended
|
|
160
|
+
in-process boundary; test thread affinity before enabling transactions.
|
|
161
|
+
|
|
162
|
+
Query transport: `cratis-arc-query-kotlin`. Chronicle projections:
|
|
163
|
+
`cratis-chronicle-client-kotlin`, not a Spring Data observation.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cratis-arc-testing-kotlin
|
|
3
|
+
description: Specify Kotlin or Java Arc commands and queries through real in-process pipelines with arc-testing — CommandScenario, QueryScenario, bounded ObservableQueryScenario collection, read-model pins, tenant resolution, and Chronicle append assertions. Use when writing or diagnosing JVM Arc pipeline specifications without Spring Boot or a kernel. Do not use for standalone Chronicle client tests, C# scenarios, or defining the command or query itself.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!-- Copyright (c) Cratis. All rights reserved. -->
|
|
8
|
+
<!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
|
|
9
|
+
|
|
10
|
+
# Specify Arc behavior on the JVM
|
|
11
|
+
|
|
12
|
+
Use generated artifacts through the real pipelines, not hand-written handlers
|
|
13
|
+
that bypass KSP wiring. `arc-testing` needs neither Spring Boot nor Docker.
|
|
14
|
+
This is test support, not an alternative production host.
|
|
15
|
+
|
|
16
|
+
## Verified product sources
|
|
17
|
+
|
|
18
|
+
Verified at `Arc.Kotlin v7.7.0`: `Testing/src/main/kotlin/io/cratis/arc/testing`
|
|
19
|
+
(`CommandScenario`, `QueryScenario`, `ObservableQueryScenario`, result assertions),
|
|
20
|
+
`Integrations/Chronicle/ChronicleCommandScenario.kt`, and
|
|
21
|
+
`Documentation/guides/testing.mdx`. Add
|
|
22
|
+
`testImplementation("io.cratis:arc-testing:7.7.0")`; align it with the runtime,
|
|
23
|
+
plugin and KSP version. The repository uses JUnit Jupiter `6.1.3`.
|
|
24
|
+
|
|
25
|
+
## Choose the pipeline
|
|
26
|
+
|
|
27
|
+
| Behavior | Scenario |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| Execute or validate a command | `CommandScenario(module, CommandType::class.java)` |
|
|
30
|
+
| One-shot query | `QueryScenario<T>` selected by `FullyQualifiedQueryName` |
|
|
31
|
+
| Streaming query | `ObservableQueryScenario<T>` with bounded `collect(maximumEmissions, timeoutMillis)` |
|
|
32
|
+
|
|
33
|
+
Application specs select a generated `ArcArtifactModule`. Manual
|
|
34
|
+
`CommandHandler`/`QueryPerformer` constructors are for framework tests.
|
|
35
|
+
Arrange services, validators, authorization policies, filters, principal,
|
|
36
|
+
tenant and correlation id on the scenario before executing it.
|
|
37
|
+
|
|
38
|
+
Illustrative excerpt: `module` is the generated module; `CreateTask` and its
|
|
39
|
+
`TaskRepository`/`TaskCreated` types are supplied by the application.
|
|
40
|
+
|
|
41
|
+
```kotlin
|
|
42
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
43
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
44
|
+
|
|
45
|
+
import io.cratis.arc.testing.CommandScenario
|
|
46
|
+
|
|
47
|
+
val result = CommandScenario(module, CreateTask::class.java)
|
|
48
|
+
.addService(TaskRepository::class.java, repository)
|
|
49
|
+
.execute(CreateTask("Try Arc"))
|
|
50
|
+
|
|
51
|
+
result.shouldSucceed().shouldHaveResponse(TaskCreated::class.java)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Command and one-shot query scenarios perform JSON round trips by default,
|
|
55
|
+
including the module's registered derived types. Keep them enabled to exercise
|
|
56
|
+
wire behavior. Disable them only for a deliberate pure/in-process assertion;
|
|
57
|
+
serialization failures propagate to the test, not a successful result.
|
|
58
|
+
Observable scenarios do not perform opening-argument or result-data round trips.
|
|
59
|
+
|
|
60
|
+
## Pin current state, including absence
|
|
61
|
+
|
|
62
|
+
- `withReadModel(type, value)` pins a type regardless of command key.
|
|
63
|
+
- `withReadModelForKey(type, key, value)` proves key selection too; other keys
|
|
64
|
+
resolve to absence. Scalar keys match concept-wrapped keys after unwrapping.
|
|
65
|
+
- A `null` pin is deliberate absence. Required parameters fail with
|
|
66
|
+
`dependencyUnavailable`; Kotlin nullable parameters receive `null`, and
|
|
67
|
+
Java `Optional` parameters receive `Optional.empty()`.
|
|
68
|
+
- Pins claim ownership and win over fallback resolvers. Do not mix a global
|
|
69
|
+
pin and keyed pins for the same type. Use `addReadModelResolver` for computed state.
|
|
70
|
+
|
|
71
|
+
## Assert the rejecting stage
|
|
72
|
+
|
|
73
|
+
Use positive and negative assertions rather than only `shouldFail()`:
|
|
74
|
+
`shouldBeAuthorized`/`shouldBeUnauthorized`, `shouldBeValid`/`shouldBeInvalid`,
|
|
75
|
+
`shouldHaveErrors`/`shouldHaveNoErrors`.
|
|
76
|
+
`shouldBeAuthorized().shouldBeInvalid()` states that authorization passed and
|
|
77
|
+
a validation rule rejected the input.
|
|
78
|
+
|
|
79
|
+
`CommandScenarioResult.shouldBeInvalid()` fails when all feedback is
|
|
80
|
+
`dependencyUnavailable`: that normally means the test forgot a dependency,
|
|
81
|
+
not that a rule ran. Pin or register it before asserting the rule. When missing
|
|
82
|
+
dependencies are the intended behavior, assert
|
|
83
|
+
`shouldHaveValidation(reason = ValidationResultReasons.DEPENDENCY_UNAVAILABLE)`.
|
|
84
|
+
|
|
85
|
+
`withTenantResolution` takes a resolver and explicit request context on all
|
|
86
|
+
three scenarios. The resolved tenant also becomes the namespace unless one is
|
|
87
|
+
supplied. Test unresolved and unauthorized tenant selection as well as success;
|
|
88
|
+
use `cratis-arc-identity-and-tenancy-kotlin` for the request contract.
|
|
89
|
+
|
|
90
|
+
## Bound observable specifications
|
|
91
|
+
|
|
92
|
+
One timeout budget covers opening and collection. Timeout/cancellation
|
|
93
|
+
propagates and cancels cooperative upstream work; it is not a successful result.
|
|
94
|
+
`maximumEmissions` is a cap, not a required count: a finite stream can finish
|
|
95
|
+
empty or early. Chain `shouldHaveEmissionCount(expected)` when count matters.
|
|
96
|
+
`addEmissionGuard` supplies per-emission checks; assert opening rejection with
|
|
97
|
+
`shouldFail()` and terminal guard denial with `shouldTerminateUnauthorized()`.
|
|
98
|
+
|
|
99
|
+
## Chronicle integration without a kernel
|
|
100
|
+
|
|
101
|
+
Add the Chronicle starter (or `io.cratis:cratis`) alongside `arc-testing`.
|
|
102
|
+
Its `CommandScenarioExtender` is found through `ServiceLoader` and supplies
|
|
103
|
+
an in-memory event log automatically. `givenChronicle().events(id, event)`
|
|
104
|
+
establishes prior history; `chronicle().shouldHaveAppendedEvent(id, Event::class.java)`
|
|
105
|
+
checks the new append. Given events are excluded from `appendedEvents`.
|
|
106
|
+
Arrange `constraintViolation(...)` or `concurrencyViolation(...)` to reject an
|
|
107
|
+
append deterministically and assert `shouldHaveConstraintViolation(...)` or
|
|
108
|
+
`shouldHaveConcurrencyViolation(...)`. Rejected appends are not appended events.
|
|
109
|
+
This does not verify a real kernel constraint or storage integration.
|
|
110
|
+
|
|
111
|
+
## Java and verification
|
|
112
|
+
|
|
113
|
+
Use the closeable `BlockingCommandScenario` over a configured scenario for
|
|
114
|
+
ordinary Java tests; configure pins, tenant resolution and Chronicle before
|
|
115
|
+
constructing the bridge. `ChronicleCommandScenarios` exposes Kotlin extensions
|
|
116
|
+
as Java statics. For asynchronous tests use `AsyncCommandScenario`,
|
|
117
|
+
`AsyncQueryScenario`, `AsyncObservableQueryScenario` and a `JavaAsyncScope`.
|
|
118
|
+
`usingExecutor` borrows an executor; `owningExecutorService` owns shutdown.
|
|
119
|
+
Scenarios borrow the scope; close the owner after the test.
|
|
120
|
+
`collectAsync` returns a `CompletionStage` with bounded collection. Timeout
|
|
121
|
+
cancels the stage; callback-based `collect` does not deliver timeout callbacks.
|
|
122
|
+
|
|
123
|
+
- Follow the `for_`/`when_` naming conventions in `kotlin.md`/`java.md`.
|
|
124
|
+
- Run `./gradlew build` with warnings treated as errors and all affected specs.
|
|
125
|
+
- Verify authorization, rejection, absence and failure paths that apply, not
|
|
126
|
+
only a successful response.
|
|
127
|
+
- Run real-store integration checks separately when the behavior depends on
|
|
128
|
+
kernel constraints, persistence, transactions or change streams.
|
|
129
|
+
|
|
130
|
+
For definition rather than tests: `cratis-arc-command-kotlin`,
|
|
131
|
+
`cratis-arc-query-kotlin`, `cratis-arc-validation-kotlin`.
|
|
@@ -14,16 +14,12 @@ that way; keep service calls, async work, and cross-member logic imperative.
|
|
|
14
14
|
|
|
15
15
|
## Verified product sources
|
|
16
16
|
|
|
17
|
-
Verified against `Arc.Kotlin` at tag **`v7.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Documented consumer setup: JDK 17, Kotlin 2.4.20, KSP 2.3.12, Spring Boot
|
|
21
|
-
4.1.x. `io.cratis:arc` supplies `io.cratis.arc.validation.FluentModelValidator`,
|
|
22
|
-
`CommandValidator<T>`, `QueryValidator<T>`, `ConceptValidator<T>`,
|
|
17
|
+
Verified against `Arc.Kotlin` at tag **`v7.7.0`**: JDK 17, Gradle 8.14.4,
|
|
18
|
+
Kotlin 2.4.20, KSP 2.3.12, Spring Boot 4.1.1, JUnit Jupiter 6.1.3. `io.cratis:arc` supplies `io.cratis.arc.validation.FluentModelValidator`,
|
|
19
|
+
`CommandValidator<T>`, nongeneric `QueryValidator`, `ConceptValidator<T>`,
|
|
23
20
|
`ModelValidator<T>`, `ConceptValidationExclusion`, `IgnoreValidation`,
|
|
24
|
-
`CommandFilter`, `QueryFilter`.
|
|
25
|
-
|
|
26
|
-
`guides/pipeline-filters.md`.
|
|
21
|
+
`CommandFilter`, `QueryFilter`. Sources: `queries/QueryValidator.kt`,
|
|
22
|
+
`commands/CommandValidator.kt`, validation types and `guides/pipeline-filters.mdx`.
|
|
27
23
|
|
|
28
24
|
## Shared fluent rules — server and generated TypeScript
|
|
29
25
|
|
|
@@ -125,7 +121,7 @@ validated child roots still run.
|
|
|
125
121
|
|
|
126
122
|
## Server-only validators
|
|
127
123
|
|
|
128
|
-
### `CommandValidator<T>`
|
|
124
|
+
### `CommandValidator<T>`
|
|
129
125
|
|
|
130
126
|
```kotlin
|
|
131
127
|
@Component
|
|
@@ -153,6 +149,39 @@ Java implementations use `BlockingCommandValidator`/`AsyncCommandValidator`
|
|
|
153
149
|
with the matching `*Adapter`, published as an ordinary `CommandValidator`
|
|
154
150
|
Spring bean — there is no second Java-specific discovery mechanism.
|
|
155
151
|
|
|
152
|
+
### `QueryValidator` — request-based, not generic
|
|
153
|
+
|
|
154
|
+
A query validator receives `QueryRequest` and `QueryContext`, not a typed
|
|
155
|
+
command-style model. `queryName = null` matches every query; set a
|
|
156
|
+
`FullyQualifiedQueryName` to restrict it to one query.
|
|
157
|
+
|
|
158
|
+
```kotlin
|
|
159
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
160
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
161
|
+
|
|
162
|
+
import io.cratis.arc.queries.FullyQualifiedQueryName
|
|
163
|
+
import io.cratis.arc.queries.QueryContext
|
|
164
|
+
import io.cratis.arc.queries.QueryRequest
|
|
165
|
+
import io.cratis.arc.queries.QueryValidator
|
|
166
|
+
import io.cratis.arc.results.ValidationResult
|
|
167
|
+
import org.springframework.stereotype.Component
|
|
168
|
+
|
|
169
|
+
@Component
|
|
170
|
+
class TaskQueryValidator : QueryValidator {
|
|
171
|
+
override val queryName: FullyQualifiedQueryName? = null
|
|
172
|
+
|
|
173
|
+
override suspend fun validate(request: QueryRequest, context: QueryContext): List<ValidationResult> =
|
|
174
|
+
if (request.arguments["title"] == "") {
|
|
175
|
+
listOf(ValidationResult.error("A task title is required.", listOf("title")))
|
|
176
|
+
} else {
|
|
177
|
+
emptyList()
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
This example rejects an explicitly empty title; add the absence rule separately
|
|
183
|
+
when omission is invalid for the selected query.
|
|
184
|
+
|
|
156
185
|
### `ConceptValidator<TConcept>`
|
|
157
186
|
|
|
158
187
|
A reusable invariant on a `ConceptAs<T>` concept type, walked automatically
|
|
@@ -251,7 +280,7 @@ fun billingCommandFilter(): CommandFilter = BillingCommandFilter()
|
|
|
251
280
|
|
|
252
281
|
## Order of execution
|
|
253
282
|
|
|
254
|
-
Typed `CommandValidator
|
|
283
|
+
Typed `CommandValidator` and request-based `QueryValidator` rules run once, before the shared
|
|
255
284
|
model/concept traversal. A separately registered `ModelValidator` for the
|
|
256
285
|
command's own class is a distinct rule that also runs once at the root.
|
|
257
286
|
Cancellation from any validator — a concept validator, a Kotlin property
|
|
@@ -264,6 +293,8 @@ exception result; it is not silently skipped.
|
|
|
264
293
|
|
|
265
294
|
- Defining the command or query the rule attaches to:
|
|
266
295
|
`cratis-arc-command-kotlin`, `cratis-arc-query-kotlin`.
|
|
296
|
+
- In-process rule assertions and dependency pins: `cratis-arc-testing-kotlin`.
|
|
297
|
+
- Authentication, identity and tenancy: `cratis-arc-identity-and-tenancy-kotlin`.
|
|
267
298
|
- Append-time Chronicle uniqueness/concurrency: `cratis-chronicle-event-constraints`.
|
|
268
299
|
- The C# Arc validation shape (`ConceptValidator<T>`, `CommandValidator<T>`,
|
|
269
300
|
Provide short-circuiting): `cratis-arc-command-validation`.
|
|
@@ -283,3 +314,5 @@ exception result; it is not silently skipped.
|
|
|
283
314
|
every rule expressed with `FluentModelValidator` — verify with a build that
|
|
284
315
|
regenerates the proxy.
|
|
285
316
|
- `./gradlew build` is clean with zero warnings and zero errors.
|
|
317
|
+
- Exercise rejection through `cratis-arc-testing-kotlin`; `shouldBeInvalid()`
|
|
318
|
+
must prove a rule ran, not only a missing dependency.
|
|
@@ -20,14 +20,14 @@ generator copies into generated proxies. Setup is in
|
|
|
20
20
|
|
|
21
21
|
## Verified product sources
|
|
22
22
|
|
|
23
|
-
Verified against `Cratis/Arc.TypeScript`
|
|
24
|
-
|
|
23
|
+
Verified against `Cratis/Arc.TypeScript` tag **v0.57.2** (GitHub pre-release;
|
|
24
|
+
server packages 0.57.2, not on npm), reading `Source/Core/validation/**` (including
|
|
25
25
|
`index.ts`, `ValidationResult.ts`, `Severity.ts`, `RuleBuilder.ts`),
|
|
26
26
|
`Source/Core/commands/Outcome.ts`, `Documentation/commands/command-validation.md`,
|
|
27
27
|
`validation-severity-filtering.md`, `command-outcomes.md`,
|
|
28
28
|
`Documentation/queries/validation.md`, `Documentation/concepts.md`,
|
|
29
29
|
`Documentation/proxy-generation/validation.md`, `Source/Testing`, and the
|
|
30
|
-
`Samples/Tasks` validators.
|
|
30
|
+
`Samples/Tasks` validators.
|
|
31
31
|
`ValidationResult` is both the exported interface and a value with the helpers
|
|
32
32
|
`ValidationResult.information/warning/error(message, options?)`; the positional
|
|
33
33
|
`validation(...)` function remains available.
|
|
@@ -180,6 +180,8 @@ export class RenameTaskValidator extends CommandValidator<RenameTask> {
|
|
|
180
180
|
your message.
|
|
181
181
|
- It works **only** inside a validator of a model-bound command, during
|
|
182
182
|
validation. Validators do not receive read models through their constructors.
|
|
183
|
+
- Reads are scoped to the current command/tenant and cancellation signal, on
|
|
184
|
+
both validate and execute routes; do not retain a validation read across calls.
|
|
183
185
|
|
|
184
186
|
## Rule vocabulary
|
|
185
187
|
|
|
@@ -16,13 +16,19 @@ This skill is verified against these exact sources:
|
|
|
16
16
|
|
|
17
17
|
| Package | Version | Purpose |
|
|
18
18
|
| --- | --- | --- |
|
|
19
|
-
| `Cratis.Cli` | `3.
|
|
19
|
+
| `Cratis.Cli` | `3.53.1` | command effects, confirmations, contexts, output and command tree |
|
|
20
|
+
| `Cratis.Chronicle` | `19.32.0` | the CLI's Chronicle client package |
|
|
21
|
+
| `Cratis.Chronicle` | `19.50.1` | server authentication configuration and development-client registration |
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
Re-verified at `Cratis/cli v3.53.1`: since 3.2.0, observer removal,
|
|
24
|
+
partition-quarantine clearing, server-bound login and broader diagnose scope
|
|
25
|
+
have changed operational guidance. Read [command effects](references/command-effects.md)
|
|
26
|
+
when classifying a mutation or confirmation; it cites the exact tag.
|
|
23
27
|
|
|
24
28
|
The CLI ships a **versioned machine-readable catalog of its own surface**, and
|
|
25
|
-
that catalog is the authority for exact command names
|
|
29
|
+
that catalog is the authority for exact command names, `effect` and
|
|
30
|
+
`requiresConfirmation` on the installed version. Treat every effect other than
|
|
31
|
+
`read-only` (including unknown values) as a state change:
|
|
26
32
|
|
|
27
33
|
```bash
|
|
28
34
|
cratis llm-context # every command, option and argument as JSON
|
|
@@ -66,8 +72,29 @@ The connection string resolves in this exact order:
|
|
|
66
72
|
4. `chronicle://localhost:35000`
|
|
67
73
|
|
|
68
74
|
Credentials are composed separately, and only when the resolved string carries
|
|
69
|
-
no embedded `user:pass@` and no `apiKey
|
|
70
|
-
|
|
75
|
+
no embedded `user:pass@` and no `apiKey=` (embedded credentials win): use a cached
|
|
76
|
+
login token only for its issuing server and while valid (more than one minute
|
|
77
|
+
before expiry), then context client id/secret, then the built-in development
|
|
78
|
+
client. The CLI does not restrict that fallback to localhost; acceptance depends
|
|
79
|
+
on the server's authentication configuration and registered clients, not its
|
|
80
|
+
address. Development builds can register that client automatically; do not rely
|
|
81
|
+
on a remote server rejecting it. An expired matching login without
|
|
82
|
+
client credentials raises `LoginSessionExpired` (exit 4), not a silent fallback.
|
|
83
|
+
A login belonging to another server is not sent; a once-per-process stderr
|
|
84
|
+
notice explains the mismatch.
|
|
85
|
+
|
|
86
|
+
Use `cratis chronicle login <user>` (`--secret` or prompt), `chronicle logout`
|
|
87
|
+
and `chronicle auth status -o json` (`tokenServer`, `loginMatchesServer`). Login
|
|
88
|
+
refuses multi-host and `chronicle+srv://` targets. CLIs before 3.21.0 discarded
|
|
89
|
+
the login token; log in again after upgrading. Context values can be changed
|
|
90
|
+
with `context set-value server|event-store|namespace|client-id|client-secret`.
|
|
91
|
+
Keep secrets out of logs and committed configuration.
|
|
92
|
+
Evidence: [ChronicleSettings.cs](https://github.com/Cratis/cli/blob/v3.53.1/Source/Cli/Commands/Chronicle/ChronicleSettings.cs)
|
|
93
|
+
and [authentication](https://github.com/Cratis/cli/blob/v3.53.1/Documentation/chronicle/auth.md).
|
|
94
|
+
Server evidence at Chronicle v19.50.1:
|
|
95
|
+
[authentication configuration](https://github.com/Cratis/Chronicle/blob/v19.50.1/Source/Kernel/Core/Configuration/Authentication.cs)
|
|
96
|
+
and [development-client registration](https://github.com/Cratis/Chronicle/blob/v19.50.1/Source/Kernel/Core/Setup/Authentication/AuthenticationService.cs)
|
|
97
|
+
(`EnsureDefaultClientCredentials`, compiled under `DEVELOPMENT`).
|
|
71
98
|
|
|
72
99
|
Prefer a named context over repeating a connection string:
|
|
73
100
|
|
|
@@ -103,13 +130,15 @@ There is one output flag, `-o` / `--output`, with values `table`, `plain`,
|
|
|
103
130
|
|
|
104
131
|
Exit codes are stable and worth branching on: `0` success, `1` not found, `2`
|
|
105
132
|
connection error, `3` server error, `4` authentication error, `5` validation
|
|
106
|
-
error.
|
|
133
|
+
error; `6` is `changes_pending` for `render --check`, not Chronicle commands.
|
|
134
|
+
JSON errors carry an `error` code such as `not_found`, `connection_error`,
|
|
135
|
+
`server_error`, `authentication_error` or `validation_error`.
|
|
107
136
|
|
|
108
137
|
## Where to look
|
|
109
138
|
|
|
110
139
|
| Question | Where to look |
|
|
111
140
|
| --- | --- |
|
|
112
|
-
| Is the server healthy at all? | `cratis chronicle diagnose
|
|
141
|
+
| Is the server healthy at all? | `cratis chronicle diagnose`; `--all-namespaces`, `--all-event-stores`, `--watch --interval <seconds>`; non-zero for unhealthy, quarantined or incomplete checks |
|
|
113
142
|
| Why has this read model stopped updating? | `chronicle failed-partitions list --observer <id>` — the error is on the partition, not in the log |
|
|
114
143
|
| An observer is quarantined — why? | `chronicle failed-partitions show <observer> <partition> --detailed`, with attempt history |
|
|
115
144
|
| Did this event actually get appended? | `chronicle events get --event-type <type> --event-source-id <id>` (`events tail` returns only the highest sequence number — not a count, not the events) |
|
|
@@ -119,19 +148,26 @@ error.
|
|
|
119
148
|
| Is a replay or migration still running? | `chronicle jobs list`, then `chronicle jobs get <id>` |
|
|
120
149
|
| What does the server itself recommend? | `chronicle recommendations list` |
|
|
121
150
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
`
|
|
151
|
+
Classify inspection through `effect=read-only` in `cratis llm-context`, not a
|
|
152
|
+
remembered allowlist. `chronicle report-error` is cataloged read-only, but opens
|
|
153
|
+
a browser issue form; the harness guard deliberately blocks that external UI
|
|
154
|
+
action.
|
|
155
|
+
|
|
156
|
+
`read-models get|snapshots|instances <READ_MODEL>` takes the **Identifier** column
|
|
157
|
+
of `read-models list`, not the container name. `events get` accepts `--sequence`,
|
|
158
|
+
`--from`, `--to`, `--event-source-id` and `--event-type` (comma-separated, optional
|
|
159
|
+
`Type+gen`). It has no limit option: bound `--from`/`--to` and prefer `-o plain`.
|
|
160
|
+
The catalog recommends plain for `event-types list`, `projections list` and
|
|
161
|
+
`read-models instances`, and json-compact for `read-models get`.
|
|
128
162
|
|
|
129
163
|
## Read what comes back
|
|
130
164
|
|
|
131
|
-
- **A failed partition
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
165
|
+
- **A failed partition is not necessarily quarantined.** Eligible failures retry
|
|
166
|
+
automatically under the configured budget; quarantined partitions stop retrying.
|
|
167
|
+
Missing `IsQuarantined` is Unknown, not healthy. A stale value can mean lag or a
|
|
168
|
+
stopped partition: inspect attempts and observer state rather than guessing.
|
|
169
|
+
Observer clear does not clear partition quarantine. Source: Chronicle
|
|
170
|
+
**v19.50.1**, `Documentation/concepts/observers.mdx`.
|
|
135
171
|
- **Fix the cause before replaying.** Replaying into an unfixed handler fails the
|
|
136
172
|
same way and buries the original error under a newer one.
|
|
137
173
|
- **A quarantined observer does not resume by itself.** A quarantine ends when
|
|
@@ -141,6 +177,12 @@ list|show`, `failed-partitions list|show`, `projections list|show`,
|
|
|
141
177
|
not the first. A redeploy that restarts the client can also end the quarantine
|
|
142
178
|
as a side effect, so check the observer's state before and after a redeploy.
|
|
143
179
|
|
|
180
|
+
- **Observer and partition quarantine are separate.** `observers clear-quarantine`
|
|
181
|
+
clears only the observer. `observers clear-partition-quarantine <observer> <partition>`
|
|
182
|
+
needs Chronicle 19.29.0+, resets the retry budget and retries unless `--no-retry`
|
|
183
|
+
is given; handler side effects may repeat. `retry-partition` exits non-zero
|
|
184
|
+
when quarantined or not failed. `jobs resume` resumes Stopped jobs, not Failed.
|
|
185
|
+
|
|
144
186
|
## Before you change anything
|
|
145
187
|
|
|
146
188
|
Default to read-only inspection. A request to diagnose a live store does not
|
|
@@ -150,12 +192,20 @@ These commands mutate the running store:
|
|
|
150
192
|
|
|
151
193
|
- `chronicle observers replay`, `replay-partition`, `retry-partition`,
|
|
152
194
|
`clear-quarantine`
|
|
195
|
+
- `chronicle observers remove` — destructive across every namespace of the event
|
|
196
|
+
store: definition, state, handled counts, failures and projection definition;
|
|
197
|
+
read model data stays. Refused while running or subscribed, no force flag.
|
|
198
|
+
- `chronicle observers clear-partition-quarantine` — may retry the handler
|
|
153
199
|
- `chronicle jobs stop`, `chronicle jobs resume`
|
|
154
200
|
- `chronicle recommendations perform`, `chronicle recommendations ignore`
|
|
155
201
|
- `chronicle subscriptions add`, `chronicle subscriptions remove`
|
|
156
202
|
- `chronicle users add`, `chronicle users remove`
|
|
157
203
|
- `chronicle applications add`, `chronicle applications remove`
|
|
158
204
|
|
|
205
|
+
This is the v3.53.1 surface, not the authority for later versions; check the
|
|
206
|
+
catalog's `effect` before acting. `chronicle login/logout` are `local`, while
|
|
207
|
+
`chronicle workbench` is `destructive` because its keys can mutate the store.
|
|
208
|
+
|
|
159
209
|
Where the Cratis hooks are installed, this boundary is enforced: a `PreToolUse` guard on shell
|
|
160
210
|
commands blocks every `cratis chronicle` command that is not on its read-only allowlist, unknown
|
|
161
211
|
commands and the interactive `workbench` included, with or without `--yes`. When it blocks, do not
|
|
@@ -172,22 +222,24 @@ Before any of them:
|
|
|
172
222
|
3. Prepare the repository-approved inverse or safe compensation when one exists;
|
|
173
223
|
stop when the effect cannot be safely reversed unless the owner separately
|
|
174
224
|
authorizes that irreversible operation.
|
|
175
|
-
4. Show the
|
|
176
|
-
action.
|
|
225
|
+
4. Show the intended change (and a dry run where supported) and obtain explicit
|
|
226
|
+
authorization for that exact target and action.
|
|
177
227
|
5. Re-read the target immediately before mutation and stop on drift.
|
|
178
228
|
|
|
179
229
|
### Two confirmation traps
|
|
180
230
|
|
|
181
231
|
**Destructive commands fail closed outside a terminal.** Every command with a
|
|
182
232
|
confirmation prompt — `observers replay`, `observers replay-partition`,
|
|
183
|
-
`observers retry-partition`, `observers clear-quarantine`,
|
|
233
|
+
`observers retry-partition`, `observers clear-quarantine`,
|
|
234
|
+
`observers clear-partition-quarantine`, `observers remove`, `jobs stop`,
|
|
184
235
|
`jobs resume`, `recommendations perform`, `recommendations ignore`,
|
|
185
236
|
`users remove`, `applications remove`, `subscriptions remove` — asks
|
|
186
237
|
interactively, and when the session is **not** interactive (a script, a
|
|
187
238
|
pipeline, an agent harness) it does *not* proceed: it writes
|
|
188
239
|
"Re-run the command with --yes to confirm the operation" and exits with the
|
|
189
240
|
validation error code. `--yes` is therefore the only way a non-interactive run
|
|
190
|
-
performs one of these
|
|
241
|
+
performs one of these. It is confirmation, **not user authorization**; check
|
|
242
|
+
`requiresConfirmation` independently from `effect` in the installed catalog. Declining
|
|
191
243
|
the interactive prompt exits successfully having done nothing.
|
|
192
244
|
|
|
193
245
|
**Additive commands do not prompt.** `users add`, `applications add` and
|
|
@@ -207,10 +259,12 @@ authorization.
|
|
|
207
259
|
|
|
208
260
|
## Related
|
|
209
261
|
|
|
210
|
-
-
|
|
211
|
-
|
|
212
|
-
|
|
262
|
+
- `cratis-chronicle-mcp-inspection` offers read-mostly inspection/design-time
|
|
263
|
+
tools and job control only; replay, retry and observer recovery are CLI work.
|
|
264
|
+
- The terminal Workbench (`cratis chronicle workbench`) presents the same data
|
|
265
|
+
with mutating keys; a human at a terminal uses it, not an agent harness.
|
|
213
266
|
- The browser Workbench owns redaction, revision, and event-type authoring.
|
|
267
|
+
- Narrator (VS Code extension `cratis.narrator`, verified at `v3.0.2`) browses stores, event types, observers and projections from the editor, using the same contexts in `~/.cratis/config.json`.
|
|
214
268
|
- Source-level diagnosis belongs in the application's own diagnostic workflow;
|
|
215
269
|
start there when the symptom reproduces locally, and start here when it is
|
|
216
270
|
only visible on a running server.
|