@sumrco/cli 0.2.1 → 0.3.1

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 (37) hide show
  1. package/ai/modules/kontract/resources/api-generation-standards.rf.md +83 -0
  2. package/ai/modules/kontract/resources/authoring/configuration.rf.md +220 -0
  3. package/ai/modules/kontract/resources/authoring/design-profile/api-styles.rf.md +241 -0
  4. package/ai/modules/kontract/resources/authoring/design-profile/async-styles.rf.md +134 -0
  5. package/ai/modules/kontract/resources/authoring/design-profile/overview.md +64 -0
  6. package/ai/modules/kontract/resources/authoring/design-profile/schema-layout-styles.rf.md +356 -0
  7. package/ai/modules/kontract/resources/authoring/overview.md +56 -0
  8. package/ai/modules/kontract/resources/authoring/schema-reuse.rf.md +492 -0
  9. package/ai/modules/kontract/resources/authoring/scope-and-splitting.rf.md +244 -0
  10. package/ai/modules/kontract/resources/authoring/spec-layout.rf.md +492 -0
  11. package/ai/modules/kontract/resources/authoring/team-members/spec-author.tm.md +77 -0
  12. package/ai/modules/kontract/resources/{workflows/contract-change.wf.md → authoring/workflows/spec-change.wf.md} +24 -16
  13. package/ai/modules/kontract/resources/generated-output.rf.md +185 -17
  14. package/ai/modules/kontract/resources/openapi-sdk-generator-research.rf.md +57 -0
  15. package/ai/modules/kontract/resources/overview.md +130 -44
  16. package/ai/modules/kontract/resources/performance.rf.md +7 -7
  17. package/ai/modules/kontract/sumr.module.yaml +5 -2
  18. package/ai/modules/mission/sumr.module.yaml +6 -0
  19. package/ai/modules/playbook/resources/authoring/content-structure.rf.md +1 -1
  20. package/ai/modules/playbook/resources/authoring/cross-referencing.rf.md +1 -1
  21. package/ai/modules/playbook/resources/authoring/descriptions.rf.md +1 -1
  22. package/ai/modules/playbook/resources/authoring/extraction.rf.md +1 -1
  23. package/ai/modules/playbook/resources/authoring/flows.rf.md +1 -1
  24. package/ai/modules/playbook/resources/authoring/folder-structure.rf.md +1 -1
  25. package/ai/modules/playbook/resources/authoring/frontmatter.rf.md +4 -1
  26. package/ai/modules/playbook/resources/authoring/markdown.rf.md +1 -1
  27. package/ai/modules/playbook/resources/authoring/overview.md +1 -1
  28. package/ai/modules/playbook/resources/team-members/{playbook-technical-writer.tm.md → technical-writer.tm.md} +3 -2
  29. package/ai/modules/playbook/sumr.module.yaml +7 -2
  30. package/index.js +486 -284
  31. package/package.json +1 -1
  32. package/ai/modules/kontract/resources/configuration.rf.md +0 -123
  33. package/ai/modules/kontract/resources/openapi-generator-lessons.rf.md +0 -61
  34. package/ai/modules/kontract/resources/schema-reuse.rf.md +0 -233
  35. package/ai/modules/kontract/resources/scope-and-splitting.rf.md +0 -147
  36. package/ai/modules/kontract/resources/spec-layout.rf.md +0 -69
  37. package/ai/modules/kontract/resources/team-members/contract-author.tm.md +0 -52
@@ -0,0 +1,83 @@
1
+ ---
2
+ category: reference
3
+ name: api-generation-standards
4
+ title: API Generation Standards
5
+ description: "Professional guardrails for Kontract API generation, including query parameters, safe identifiers, component schemas, map output, strict TypeScript, and Bun-native execution."
6
+ label: API Generation Standards
7
+ when: Reviewing Kontract schema modules or generator changes for API output quality, SDK behavior, query parameters, inline schemas, or strict TypeScript compatibility
8
+ order: 45
9
+ ---
10
+
11
+ # API Generation Standards
12
+
13
+ Use these standards when authoring API schemas, changing API generation, or
14
+ reviewing generated API contracts and SDKs. The goal is predictable,
15
+ professional output that compiles under strict TypeScript and stays aligned with
16
+ the source contract.
17
+
18
+ ## Required behavior
19
+
20
+ - **Preserve query parameter semantics.** Optional query params stay optional,
21
+ array query params serialize according to the spec, and enum query params use
22
+ generated enum symbols instead of raw literal imports.
23
+ - **Keep wire names and local identifiers separate.** Wire keys such as `from`,
24
+ `class`, and `default` must remain unchanged in requests, while generated local
25
+ variables use safe TypeScript identifiers.
26
+ - **Use named component schemas for operation payloads.** Request and response
27
+ bodies should reference `components.schemas` so generated DTO/model/SDK symbols
28
+ are stable and reviewable.
29
+ - **Generate map-shaped schemas deliberately.** `additionalProperties` schemas
30
+ must preserve named fields plus the typed catch-all/index-signature behavior
31
+ across Zod, DTO, model, and SDK output.
32
+ - **Fail clearly for unsupported schema features.** Unsupported `oneOf`,
33
+ `anyOf`, `not`, and discriminator shapes should stop generation before a
34
+ consumer repo is left with partial or missing symbols.
35
+ - **Keep application ownership boundaries clean.** Kontract emits contracts,
36
+ DTOs, framework-models, API metadata, and SDK clients. Application
37
+ modules, handlers, providers, and wiring stay in the consuming app.
38
+ - **Compile generated output under strict TypeScript.** Generated files must not
39
+ contain dangling imports, unsafe `any`, stale runtime globals, deprecated Nest
40
+ HTTP client imports, or framework symbols that were never emitted.
41
+ - **Stay Bun-native.** Generation must not require Java, Docker images,
42
+ downloaded generator binaries, or template folders at runtime.
43
+
44
+ ## Spec authoring rules
45
+
46
+ - Put reusable request bodies, response bodies, parameters, enums, and object
47
+ fragments under `components` and reference them with `$ref`.
48
+ - Encode validation constraints in API schema (`minLength`, `maxLength`, `minimum`,
49
+ `maximum`, `pattern`, `format`) so DTO and Zod output can enforce the same
50
+ contract.
51
+ - Use `additionalProperties` only when the payload is intentionally map-shaped.
52
+ Prefer typed map values over `additionalProperties: true`.
53
+ - For repeated query values, use `type: array` with scalar `items` and an
54
+ explicit API schema serialization shape when the default is not correct for the
55
+ API.
56
+ - Keep operation IDs stable. They become generated operation metadata, SDK method
57
+ names, and review anchors.
58
+
59
+ ## Generator implementation rules
60
+
61
+ - Normalize SDK request parameter names without changing wire keys.
62
+ - Sort required model properties before optional ones unless the target explicitly
63
+ preserves source order.
64
+ - Generate enum values once and import the generated enum symbol everywhere that
65
+ target expects a reusable enum.
66
+ - Prune stale files when a schema, enum, or operation is removed from the source
67
+ spec.
68
+ - Keep generated runtime helpers small and target-specific; do not add a heavy
69
+ shared runtime unless a target explicitly requires it.
70
+
71
+ ## Reviewer checklist
72
+
73
+ - Generated files include the auto-generated header and are not hand-edited.
74
+ - Query DTOs and SDK request types preserve optionality and array semantics from
75
+ the spec.
76
+ - Operation payload schemas reference named components instead of anonymous
77
+ inline request/response objects.
78
+ - Map-shaped schemas preserve named properties and catch-all value types.
79
+ - Generated files avoid unsafe symbols such as `any`, anonymous `InlineObject`
80
+ models, missing enum aliases, stale `basePath` globals, deprecated client
81
+ imports, and unsafe `apiKeys` access.
82
+ - Unsupported schema features fail before any consumer repo is left with partial
83
+ broken output.
@@ -0,0 +1,220 @@
1
+ ---
2
+ category: reference
3
+ name: configuration
4
+ title: Kontract Configuration
5
+ description: "How `sumr.yaml` configures Kontract sources, targets, generator types, and NestJS output options."
6
+ label: Configuration
7
+ when: Adding a Kontract target, debugging missing generated files, or comparing generated output across repos
8
+ order: 15
9
+ ---
10
+
11
+ # Kontract Configuration
12
+
13
+ Kontract reads repo-local configuration from `sumr.yaml`. A guidance profile
14
+ controls docs and AI examples only. A source points at a schema directory; each
15
+ target chooses an output directory and generator.
16
+
17
+ ```yaml
18
+ kontract:
19
+ guidance:
20
+ profile:
21
+ apiStyle: pragmatic-rest
22
+ asyncStyle: command-event
23
+ schemaLayoutStyle: by-product-capability
24
+ sources:
25
+ - name: api
26
+ input: schema
27
+ targets:
28
+ - name: backend
29
+ output: backend/src/shared/models
30
+ generator:
31
+ type: typescript-nestjs
32
+ zod: true
33
+ dtos: true
34
+ sdk: true
35
+ - name: frontend
36
+ output: frontend/src/shared/api
37
+ generator:
38
+ type: typescript-fetch
39
+ schemaMode: normalize
40
+ modelPropertyNaming: original
41
+ paramNaming: original
42
+ stringEnums: true
43
+ ```
44
+
45
+ ## Guidance profile
46
+
47
+ | Field | Meaning |
48
+ |---|---|
49
+ | `guidance.profile.apiStyle` | API style used in examples: `pragmatic-rest`, `resource-oriented`, `json-api`, `odata`, `rpc-action`, `graphql-http`, `hypermedia-rest`, `webhook-callback`, or `mixed`. |
50
+ | `guidance.profile.asyncStyle` | async style used in examples: `command-event`, `event-driven`, `request-reply`, `cloud-events`, or `mixed`. |
51
+ | `guidance.profile.schemaLayoutStyle` | Schema layout style used in examples: `by-product-capability`, `by-api-surface`, `by-service-owner`, `by-resource-area`, `by-workflow`, `by-message-family`, or `mixed`. |
52
+
53
+ `rpc-action` is an HTTP example style for action-oriented endpoints and real
54
+ RPC surfaces when they exist. Do not infer that the application implements a
55
+ generic RPC framework only because a path contains verbs such as `confirm`,
56
+ `process`, or `check-conflicts`.
57
+
58
+ For schema layout examples, use the canonical layout trees in
59
+ `design-profile/schema-layout-styles.rf.md`. In particular, do not confuse
60
+ resource-area fragments inside a product-capability folder with a repo-wide
61
+ `by-resource-area` layout. Moving schema root files changes generated output
62
+ namespaces/import paths; ask whether the user wants a guidance-only profile
63
+ change or an actual schema migration.
64
+ Choose the protocol scenario before writing examples: API-only,
65
+ async-only, or API + async with shared components such as
66
+ enums and scalar value objects.
67
+
68
+ Use `sumr kontract init` to set the profile during activation. Use
69
+ `sumr kontract config` to show or update the current profile. For the current
70
+ flag list and supported interactive choices, run `sumr kontract init --help` or
71
+ `sumr kontract config --help`. Existing profile values stay unchanged unless a
72
+ flag or interactive choice updates them.
73
+
74
+ Activation also keeps local VS Code Material Icon associations in sync for
75
+ `*.api.yml`, `*.api.yaml`, `*.async.yml`, and `*.async.yaml`.
76
+
77
+ ## Sources
78
+
79
+ | Field | Meaning |
80
+ |---|---|
81
+ | `name` | Stable source name used by `--source`. |
82
+ | `input` | Directory scanned recursively for `*.api.yml`, `*.api.yaml`, `*.async.yml`, and `*.async.yaml`. |
83
+ | `targets` | One or more generated outputs. |
84
+
85
+ Use `--source <name>` to scope validation or generation to one source.
86
+
87
+ ## Targets
88
+
89
+ | Field | Meaning |
90
+ |---|---|
91
+ | `name` | Stable target name used by `--target`. |
92
+ | `output` | Root directory for generated output. Treat this folder as generated/read-only. |
93
+ | `generator.type` | Generator family. |
94
+
95
+ Use `--target <name>` to scope generation to one target.
96
+
97
+ ## Generator types
98
+
99
+ | Category | Type | Outputs |
100
+ |---|---|---|
101
+ | Server/framework | `typescript-nestjs` | Zod DTOs, class-validator DTOs, models, Swagger metadata, generated `ApiDoc` decorators. |
102
+ | Messaging | `asyncapi-nats` | NATS subjects, message schemas, server interfaces, and clients. |
103
+ | Client/SDK | `typescript-fetch` | TypeScript fetch SDK. |
104
+ | Client/SDK | `typescript-axios` | TypeScript axios SDK. |
105
+ | Client/SDK | `typescript-angular` | Angular SDK. |
106
+ | Model | `typescript-models` | Framework-model-only output. |
107
+
108
+ Kontract is structured for more generator targets over time: runtime evidence,
109
+ docs-ready API schema artifacts, packaged API contracts, SDKs, mocks, contract
110
+ tests, and breaking-change reports.
111
+
112
+ ## `typescript-nestjs` options
113
+
114
+ | Option | Output |
115
+ |---|---|
116
+ | `zod: true` | Emits `http/zod/*.contract.ts` with Zod schemas and `createZodDto()` classes. |
117
+ | `dtos: true` | Emits `http/dto/*.dto.ts`; also keeps the compatibility behavior of emitting `http/swagger.ts`. |
118
+ | `swagger: true` | Emits per-service `http/swagger.ts` operation metadata and one shared `shared/http/decorators/api-doc.ts` helper for NestJS controllers. |
119
+ | `sdk: true` | Emits a fetch-based `http/sdk/` client that reuses the target's `http/models/` and `http/enums/` types. |
120
+
121
+ `dtos` is the canonical spelling. `dto: true` is accepted as a compatibility
122
+ alias and is normalized internally to `dtos: true`.
123
+
124
+ Framework-interfaces under `http/models/` and enums under `http/enums/`
125
+ are emitted for API schema object schemas regardless of the Zod/DTO flavor.
126
+
127
+ Use `sdk: true` on a NestJS target when a backend service should call another
128
+ generated HTTP API. Use a standalone `typescript-fetch`, `typescript-axios`, or
129
+ `typescript-angular` target when a frontend/admin app should own its SDK output
130
+ separately.
131
+
132
+ ## API schema schema mode
133
+
134
+ Standalone SDK and model targets default to `schemaMode: normalize`. In this
135
+ mode, Kontract accepts real-world API schema specs with inline operation request or
136
+ response schemas, hoists those schemas into generated component names in memory,
137
+ and emits named TypeScript models.
138
+
139
+ Use `schemaMode: strict` when the source spec is product-owned and should fail
140
+ fast unless operation request/response schemas use reusable `$ref` components.
141
+
142
+ ```yaml
143
+ generator:
144
+ type: typescript-fetch
145
+ schemaMode: normalize # default for SDK/model targets
146
+ ```
147
+
148
+ ```yaml
149
+ generator:
150
+ type: typescript-fetch
151
+ schemaMode: strict
152
+ ```
153
+
154
+ Kontract still recommends reusable component schemas for owned APIs because they
155
+ produce stable names and cleaner docs. Normalization exists so customers can
156
+ generate SDKs from external or imperfect API schema specs without rewriting the API
157
+ description first.
158
+
159
+ Use generic API schema metadata for docs/runtime surfaces:
160
+
161
+ ```yaml
162
+ x-kontract-surface: public
163
+ security: []
164
+ ```
165
+
166
+ `x-kontract-surface` values are consumer-defined strings. SUMR uses `public`,
167
+ `app`, `admin`, and `internal`; another product might use `partner`, `mobile`,
168
+ or `marketplace`.
169
+
170
+ ## Common debugging cases
171
+
172
+ ### `http/dto/`, `http/swagger.ts`, or `shared/http/decorators/api-doc.ts` is missing
173
+
174
+ Check both:
175
+
176
+ 1. The target config has `generator.type: typescript-nestjs` and `dtos: true`.
177
+ `dto: true` is also accepted, but prefer `dtos` in new config. If you use
178
+ Zod without class-validator DTOs, set `swagger: true` explicitly.
179
+ 2. The installed `SUMR Kontract module` version includes Swagger/ApiDoc support.
180
+
181
+ If two configs generate identical output and both miss `dto/` + `swagger.ts`,
182
+ the likely issue is the generator version being executed, not the consumer
183
+ repo's config.
184
+
185
+ ### `http/zod/` is missing
186
+
187
+ Check that the NestJS target has `zod: true` or that Zod generation has not been
188
+ explicitly disabled.
189
+
190
+ ### `http/sdk/` is missing
191
+
192
+ Check that the NestJS target has `sdk: true`. Standalone SDK generator targets
193
+ emit service folders with `models.ts`, `runtime.ts`, and `api.ts`; the NestJS
194
+ composed SDK emits under `http/sdk/` and imports types from existing
195
+ `http/models/` and `http/enums/`.
196
+
197
+ ### Generated files are stale
198
+
199
+ Run a scoped clean generation:
200
+
201
+ ```bash
202
+ sumr kontract generate --source api --target backend --clean
203
+ ```
204
+
205
+ Prefer scoping `--clean` in large repos so only the intended generated output
206
+ and selected Kontract cache are removed before regeneration.
207
+
208
+ ### Warm generation is still slow
209
+
210
+ Kontract stores incremental manifests under `.sumr-cache/kontract`. An unchanged
211
+ warm run should skip unchanged services before parse/emit and should not run a
212
+ formatter subprocess.
213
+
214
+ If warm runs regenerate everything, check for:
215
+
216
+ 1. generated files being manually edited or deleted;
217
+ 2. changing generator config in `sumr.yaml`;
218
+ 3. a changed installed `SUMR Kontract module` version;
219
+ 4. ambiguous or remote `$ref` usage that forces the safe path;
220
+ 5. `--clean`, which intentionally clears selected output and cache state.
@@ -0,0 +1,241 @@
1
+ ---
2
+ category: reference
3
+ name: api-styles
4
+ title: HTTP Style Examples
5
+ description: "API profile styles for Kontract examples, including path and component naming samples."
6
+ label: HTTP Styles
7
+ when: Choosing or explaining `kontract.guidance.profile.apiStyle`, HTTP paths, API schema components, or action-oriented endpoints
8
+ order: 16
9
+ ---
10
+
11
+ # HTTP Style Examples
12
+
13
+ Use `kontract.guidance.profile.apiStyle` to choose the API examples an
14
+ agent should produce. This is guidance only; it does not change generation.
15
+
16
+ The `rpc-action` value means **action-oriented HTTP contract examples**. It does
17
+ not mean the service implements a generic RPC framework. Use it for endpoints
18
+ such as `/v1/bookings/{bookingId}/confirm`,
19
+ `/v1/payments/refunds/{refundId}/process`, or a real JSON-RPC surface when one
20
+ exists.
21
+
22
+ | Style | Choose this when | Sample path | Sample component |
23
+ |---|---|---|---|
24
+ | `pragmatic-rest` | You want predictable REST without strict methodology overhead. | `/v1/orders/{orderId}/items` | `Order`, `CreateOrderBody` |
25
+ | `resource-oriented` | You follow resource hierarchy and standard methods closely. | `/v1/publishers/{publisherId}/books/{bookId}` | `Book`, `ListBooksResponse` |
26
+ | `json-api` | Clients expect JSON:API document, relationship, and sparse-field conventions. | `/articles/1/relationships/comments` | `ArticleResource`, `ArticleRelationship` |
27
+ | `odata` | Consumers need OData-style query, filtering, and metadata conventions. | `/Products?$filter=price gt 10` | `ProductEntity`, `ProductCollection` |
28
+ | `rpc-action` | The HTTP contract is action-first, command-like, or includes a real RPC endpoint; this does not require an RPC framework. | `/v1/bookings/{bookingId}/confirm` | `ConfirmBookingRequest`, `BookingConfirmationResult` |
29
+ | `graphql-http` | HTTP mainly carries GraphQL operations. | `/graphql` with operation `GetOrder` | `GraphqlError`, `GetOrderVariables` |
30
+ | `hypermedia-rest` | Clients navigate links and state transitions from representations. | `/v1/orders/{orderId}` with `links.cancel` | `OrderLinks`, `OrderRepresentation` |
31
+ | `webhook-callback` | The contract documents callbacks or externally delivered HTTP events. | `/webhooks/order-created` | `OrderCreatedWebhook`, `WebhookAck` |
32
+ | `mixed` | Multiple HTTP styles are intentional and documented by surface. | `/v1/orders` and `/graphql` | Style-specific names per surface |
33
+
34
+ ## Concrete snippets
35
+
36
+ ### `pragmatic-rest`
37
+
38
+ Use resource paths and conventional operations without forcing one strict REST
39
+ school.
40
+
41
+ ```yaml
42
+ api: 3.1.0
43
+ paths:
44
+ /v1/orders/{orderId}:
45
+ get:
46
+ operationId: getOrder
47
+ responses:
48
+ "200":
49
+ content:
50
+ application/json:
51
+ schema:
52
+ $ref: "#/components/schemas/Order"
53
+ components:
54
+ schemas:
55
+ Order:
56
+ type: object
57
+ required: [id, status]
58
+ ```
59
+
60
+ ### `resource-oriented`
61
+
62
+ Use nested resources, stable identifiers, and standard list/get/create/update/delete
63
+ operations.
64
+
65
+ ```yaml
66
+ api: 3.1.0
67
+ paths:
68
+ /v1/publishers/{publisherId}/books/{bookId}:
69
+ get:
70
+ operationId: getPublisherBook
71
+ parameters:
72
+ - name: publisherId
73
+ in: path
74
+ required: true
75
+ schema: { type: string }
76
+ - name: bookId
77
+ in: path
78
+ required: true
79
+ schema: { type: string }
80
+ ```
81
+
82
+ ### `json-api`
83
+
84
+ Use JSON:API document envelopes, resource objects, attributes, and relationships.
85
+
86
+ ```yaml
87
+ api: 3.1.0
88
+ paths:
89
+ /articles/{articleId}/relationships/comments:
90
+ get:
91
+ operationId: listArticleCommentRelationships
92
+ components:
93
+ schemas:
94
+ ArticleResource:
95
+ type: object
96
+ required: [type, id, attributes]
97
+ properties:
98
+ type: { const: articles }
99
+ id: { type: string }
100
+ relationships:
101
+ $ref: "#/components/schemas/ArticleRelationships"
102
+ ```
103
+
104
+ ### `odata`
105
+
106
+ Use OData-style collection names and query parameters for filtering, expansion,
107
+ and selection.
108
+
109
+ ```yaml
110
+ api: 3.1.0
111
+ paths:
112
+ /Products:
113
+ get:
114
+ operationId: listProducts
115
+ parameters:
116
+ - name: $filter
117
+ in: query
118
+ schema: { type: string }
119
+ - name: $select
120
+ in: query
121
+ schema: { type: string }
122
+ - name: $expand
123
+ in: query
124
+ schema: { type: string }
125
+ ```
126
+
127
+ ### `rpc-action`
128
+
129
+ Use action names when the operation is a business command, not natural resource
130
+ CRUD.
131
+
132
+ ```yaml
133
+ api: 3.1.0
134
+ paths:
135
+ /v1/reports:generate:
136
+ post:
137
+ operationId: generateReport
138
+ requestBody:
139
+ content:
140
+ application/json:
141
+ schema:
142
+ $ref: "#/components/schemas/GenerateReportRequest"
143
+ responses:
144
+ "202":
145
+ description: Report generation accepted
146
+ ```
147
+
148
+ ### `graphql-http`
149
+
150
+ Use one HTTP endpoint where request bodies carry GraphQL operations and variables.
151
+
152
+ ```yaml
153
+ api: 3.1.0
154
+ paths:
155
+ /graphql:
156
+ post:
157
+ operationId: executeGraphqlOperation
158
+ requestBody:
159
+ content:
160
+ application/json:
161
+ schema:
162
+ type: object
163
+ required: [query]
164
+ properties:
165
+ query: { type: string }
166
+ variables: { type: object }
167
+ ```
168
+
169
+ ### `hypermedia-rest`
170
+
171
+ Use representations that include links or allowed state transitions clients can
172
+ follow.
173
+
174
+ ```yaml
175
+ api: 3.1.0
176
+ components:
177
+ schemas:
178
+ OrderRepresentation:
179
+ type: object
180
+ required: [id, status, links]
181
+ properties:
182
+ id: { type: string }
183
+ status: { type: string }
184
+ links:
185
+ type: object
186
+ properties:
187
+ cancel:
188
+ $ref: "#/components/schemas/LinkAction"
189
+ ```
190
+
191
+ ### `webhook-callback`
192
+
193
+ Use inbound HTTP event contracts with explicit event names, payloads, and
194
+ acknowledgement responses.
195
+
196
+ ```yaml
197
+ api: 3.1.0
198
+ paths:
199
+ /webhooks/order-created:
200
+ post:
201
+ operationId: receiveOrderCreatedWebhook
202
+ requestBody:
203
+ content:
204
+ application/json:
205
+ schema:
206
+ $ref: "#/components/schemas/OrderCreatedWebhook"
207
+ responses:
208
+ "202":
209
+ description: Webhook accepted
210
+ ```
211
+
212
+ ### `mixed`
213
+
214
+ Use separate surfaces when a product intentionally exposes more than one HTTP
215
+ style.
216
+
217
+ ```yaml
218
+ api: 3.1.0
219
+ paths:
220
+ /v1/orders:
221
+ get:
222
+ tags: [pragmatic-rest]
223
+ operationId: listOrders
224
+ /graphql:
225
+ post:
226
+ tags: [graphql-http]
227
+ operationId: executeGraphqlOperation
228
+ /v1/reports:generate:
229
+ post:
230
+ tags: [rpc-action]
231
+ operationId: generateReport
232
+ ```
233
+
234
+ ## Guardrails
235
+
236
+ - Do not use `rpc-action` as proof that an application has implemented an RPC
237
+ framework.
238
+ - If `apiStyle: mixed`, label which HTTP surface uses which style before adding
239
+ examples.
240
+ - Keep path and component examples aligned to the selected directory structure
241
+ style from `schema-layout-styles.rf.md`.
@@ -0,0 +1,134 @@
1
+ ---
2
+ category: reference
3
+ name: async-styles
4
+ title: async schema Style Examples
5
+ description: "async profile styles for Kontract examples, including channel/address and message naming samples."
6
+ label: async schema Styles
7
+ when: Choosing or explaining `kontract.guidance.profile.asyncStyle`, messaging channels, async schema addresses, or message names
8
+ order: 17
9
+ ---
10
+
11
+ # async schema Style Examples
12
+
13
+ Use `kontract.guidance.profile.asyncStyle` to choose the async
14
+ examples an agent should produce. This is guidance only; it does not change
15
+ generation.
16
+
17
+ | Style | Choose this when | Sample channel/address | Sample message |
18
+ |---|---|---|---|
19
+ | `command-event` | You separate imperative commands from past-tense events. | `cmd.billing.invoices.create`, `evt.billing.invoices.created` | `CreateInvoiceCommand`, `InvoiceCreatedEvent` |
20
+ | `event-driven` | Services primarily publish facts that subscribers react to. | `billing.invoice.created` | `InvoiceCreated` |
21
+ | `request-reply` | Messaging models query/reply or command/reply interactions. | `qry.catalog.products.get` | `GetProductQuery`, `ProductReply` |
22
+ | `cloud-events` | Events must follow CloudEvents envelope semantics. | `com.example.invoice.created` | `InvoiceCreatedCloudEvent` |
23
+ | `mixed` | Multiple messaging styles are intentional and documented by channel family. | `cmd.*`, `evt.*`, and CloudEvents topics | Names match each family |
24
+
25
+ ## Concrete snippets
26
+
27
+ ### `command-event`
28
+
29
+ Separate imperative commands from fact events and name the reply path explicitly.
30
+
31
+ ```yaml
32
+ async: 3.0.0
33
+ channels:
34
+ createInvoice:
35
+ address: cmd.billing.invoices.create
36
+ messages:
37
+ createInvoiceCommand:
38
+ $ref: "#/components/messages/CreateInvoiceCommand"
39
+ invoiceCreated:
40
+ address: evt.billing.invoices.created
41
+ messages:
42
+ invoiceCreatedEvent:
43
+ $ref: "#/components/messages/InvoiceCreatedEvent"
44
+ ```
45
+
46
+ ### `event-driven`
47
+
48
+ Publish facts that subscribers can react to without coupling to the producer
49
+ workflow.
50
+
51
+ ```yaml
52
+ async: 3.0.0
53
+ channels:
54
+ invoiceCreated:
55
+ address: billing.invoice.created
56
+ messages:
57
+ invoiceCreated:
58
+ $ref: "#/components/messages/InvoiceCreated"
59
+ operations:
60
+ publishInvoiceCreated:
61
+ action: send
62
+ channel:
63
+ $ref: "#/channels/invoiceCreated"
64
+ ```
65
+
66
+ ### `request-reply`
67
+
68
+ Model query or command messages together with the reply channel and payload.
69
+
70
+ ```yaml
71
+ async: 3.0.0
72
+ channels:
73
+ getProduct:
74
+ address: qry.catalog.products.get
75
+ messages:
76
+ getProductQuery:
77
+ $ref: "#/components/messages/GetProductQuery"
78
+ getProductReply:
79
+ address: qry.catalog.products.get.reply
80
+ messages:
81
+ productReply:
82
+ $ref: "#/components/messages/ProductReply"
83
+ ```
84
+
85
+ ### `cloud-events`
86
+
87
+ Wrap events in CloudEvents-compatible metadata when consumers expect that
88
+ envelope.
89
+
90
+ ```yaml
91
+ async: 3.0.0
92
+ components:
93
+ messages:
94
+ InvoiceCreatedCloudEvent:
95
+ payload:
96
+ type: object
97
+ required: [specversion, type, source, id, data]
98
+ properties:
99
+ specversion: { const: "1.0" }
100
+ type: { const: com.example.billing.invoice.created }
101
+ source: { type: string }
102
+ data:
103
+ $ref: "#/components/schemas/InvoiceCreated"
104
+ ```
105
+
106
+ ### `mixed`
107
+
108
+ Keep message families explicit when one system has commands, events, and
109
+ request/reply contracts.
110
+
111
+ ```yaml
112
+ async: 3.0.0
113
+ channels:
114
+ createInvoice:
115
+ address: cmd.billing.invoices.create
116
+ invoiceCreated:
117
+ address: evt.billing.invoices.created
118
+ getInvoice:
119
+ address: qry.billing.invoices.get
120
+ components:
121
+ messages:
122
+ CreateInvoiceCommand: {}
123
+ InvoiceCreatedEvent: {}
124
+ GetInvoiceQuery: {}
125
+ ```
126
+
127
+ ## Guardrails
128
+
129
+ - If `asyncStyle: mixed`, label which channel family uses which style before
130
+ adding examples.
131
+ - Keep channel and message examples aligned to the selected directory structure
132
+ style from `schema-layout-styles.rf.md`.
133
+ - Do not move async schema roots only because the messaging style changed; profile
134
+ values are guidance-only.