@sumrco/cli 0.3.0 → 0.3.2
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/ai/modules/kontract/resources/api-generation-standards.rf.md +83 -0
- package/ai/modules/kontract/resources/{configuration.rf.md → authoring/configuration.rf.md} +49 -11
- package/ai/modules/kontract/resources/authoring/design-profile/api-styles.rf.md +241 -0
- package/ai/modules/kontract/resources/authoring/design-profile/async-styles.rf.md +134 -0
- package/ai/modules/kontract/resources/authoring/design-profile/overview.md +64 -0
- package/ai/modules/kontract/resources/authoring/design-profile/schema-layout-styles.rf.md +356 -0
- package/ai/modules/kontract/resources/authoring/overview.md +56 -0
- package/ai/modules/kontract/resources/{schema-reuse.rf.md → authoring/schema-reuse.rf.md} +222 -46
- package/ai/modules/kontract/resources/{scope-and-splitting.rf.md → authoring/scope-and-splitting.rf.md} +113 -57
- package/ai/modules/kontract/resources/authoring/spec-layout.rf.md +492 -0
- package/ai/modules/kontract/resources/authoring/team-members/spec-author.tm.md +77 -0
- package/ai/modules/kontract/resources/{workflows/contract-change.wf.md → authoring/workflows/spec-change.wf.md} +21 -15
- package/ai/modules/kontract/resources/generated-output.rf.md +19 -14
- package/ai/modules/kontract/resources/openapi-sdk-generator-research.rf.md +17 -19
- package/ai/modules/kontract/resources/overview.md +115 -82
- package/ai/modules/kontract/resources/performance.rf.md +7 -7
- package/ai/modules/kontract/sumr.module.yaml +3 -0
- package/ai/modules/mission/sumr.module.yaml +6 -0
- package/ai/modules/playbook/resources/authoring/content-structure.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/cross-referencing.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/descriptions.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/extraction.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/flows.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/folder-structure.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/frontmatter.rf.md +4 -1
- package/ai/modules/playbook/resources/authoring/markdown.rf.md +1 -1
- package/ai/modules/playbook/resources/authoring/overview.md +1 -1
- package/ai/modules/playbook/resources/team-members/{playbook-technical-writer.tm.md → technical-writer.tm.md} +3 -2
- package/ai/modules/playbook/sumr.module.yaml +7 -2
- package/index.js +332 -276
- package/package.json +1 -1
- package/ai/modules/kontract/resources/language-sdk-generator-extension.rf.md +0 -62
- package/ai/modules/kontract/resources/openapi-generator-lessons.rf.md +0 -61
- package/ai/modules/kontract/resources/spec-layout.rf.md +0 -275
- package/ai/modules/kontract/resources/team-members/contract-author.tm.md +0 -60
|
@@ -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.
|
|
@@ -10,11 +10,17 @@ order: 15
|
|
|
10
10
|
|
|
11
11
|
# Kontract Configuration
|
|
12
12
|
|
|
13
|
-
Kontract reads repo-local configuration from `sumr.yaml`. A
|
|
14
|
-
|
|
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.
|
|
15
16
|
|
|
16
17
|
```yaml
|
|
17
18
|
kontract:
|
|
19
|
+
guidance:
|
|
20
|
+
profile:
|
|
21
|
+
apiStyle: pragmatic-rest
|
|
22
|
+
asyncStyle: command-event
|
|
23
|
+
schemaLayoutStyle: by-product-capability
|
|
18
24
|
sources:
|
|
19
25
|
- name: api
|
|
20
26
|
input: schema
|
|
@@ -36,12 +42,44 @@ kontract:
|
|
|
36
42
|
stringEnums: true
|
|
37
43
|
```
|
|
38
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
|
+
|
|
39
77
|
## Sources
|
|
40
78
|
|
|
41
79
|
| Field | Meaning |
|
|
42
80
|
|---|---|
|
|
43
81
|
| `name` | Stable source name used by `--source`. |
|
|
44
|
-
| `input` | Directory scanned recursively for `*.
|
|
82
|
+
| `input` | Directory scanned recursively for `*.api.yml`, `*.api.yaml`, `*.async.yml`, and `*.async.yaml`. |
|
|
45
83
|
| `targets` | One or more generated outputs. |
|
|
46
84
|
|
|
47
85
|
Use `--source <name>` to scope validation or generation to one source.
|
|
@@ -65,10 +103,10 @@ Use `--target <name>` to scope generation to one target.
|
|
|
65
103
|
| Client/SDK | `typescript-fetch` | TypeScript fetch SDK. |
|
|
66
104
|
| Client/SDK | `typescript-axios` | TypeScript axios SDK. |
|
|
67
105
|
| Client/SDK | `typescript-angular` | Angular SDK. |
|
|
68
|
-
| Model | `typescript-models` | Framework-
|
|
106
|
+
| Model | `typescript-models` | Framework-model-only output. |
|
|
69
107
|
|
|
70
108
|
Kontract is structured for more generator targets over time: runtime evidence,
|
|
71
|
-
docs-ready
|
|
109
|
+
docs-ready API schema artifacts, packaged API contracts, SDKs, mocks, contract
|
|
72
110
|
tests, and breaking-change reports.
|
|
73
111
|
|
|
74
112
|
## `typescript-nestjs` options
|
|
@@ -83,18 +121,18 @@ tests, and breaking-change reports.
|
|
|
83
121
|
`dtos` is the canonical spelling. `dto: true` is accepted as a compatibility
|
|
84
122
|
alias and is normalized internally to `dtos: true`.
|
|
85
123
|
|
|
86
|
-
Framework-
|
|
87
|
-
are emitted for
|
|
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.
|
|
88
126
|
|
|
89
127
|
Use `sdk: true` on a NestJS target when a backend service should call another
|
|
90
128
|
generated HTTP API. Use a standalone `typescript-fetch`, `typescript-axios`, or
|
|
91
129
|
`typescript-angular` target when a frontend/admin app should own its SDK output
|
|
92
130
|
separately.
|
|
93
131
|
|
|
94
|
-
##
|
|
132
|
+
## API schema schema mode
|
|
95
133
|
|
|
96
134
|
Standalone SDK and model targets default to `schemaMode: normalize`. In this
|
|
97
|
-
mode, Kontract accepts real-world
|
|
135
|
+
mode, Kontract accepts real-world API schema specs with inline operation request or
|
|
98
136
|
response schemas, hoists those schemas into generated component names in memory,
|
|
99
137
|
and emits named TypeScript models.
|
|
100
138
|
|
|
@@ -115,10 +153,10 @@ generator:
|
|
|
115
153
|
|
|
116
154
|
Kontract still recommends reusable component schemas for owned APIs because they
|
|
117
155
|
produce stable names and cleaner docs. Normalization exists so customers can
|
|
118
|
-
generate SDKs from external or imperfect
|
|
156
|
+
generate SDKs from external or imperfect API schema specs without rewriting the API
|
|
119
157
|
description first.
|
|
120
158
|
|
|
121
|
-
Use generic
|
|
159
|
+
Use generic API schema metadata for docs/runtime surfaces:
|
|
122
160
|
|
|
123
161
|
```yaml
|
|
124
162
|
x-kontract-surface: public
|
|
@@ -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.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-profile
|
|
3
|
+
title: Contract Design Profile
|
|
4
|
+
description: "How Kontract profile values guide HTTP, async schema, and schema directory examples without changing generation."
|
|
5
|
+
tags: [kontract, design-profile, http, asyncapi, schema-layout]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Contract Design Profile
|
|
9
|
+
|
|
10
|
+
`sumr kontract init` writes a guidance-only profile to `sumr.yaml`.
|
|
11
|
+
`sumr kontract config` shows or updates it later without hand-editing YAML:
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
kontract:
|
|
15
|
+
guidance:
|
|
16
|
+
profile:
|
|
17
|
+
apiStyle: pragmatic-rest
|
|
18
|
+
asyncStyle: command-event
|
|
19
|
+
schemaLayoutStyle: by-product-capability
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The profile guides docs and AI examples. It does not change generator output,
|
|
23
|
+
API schema validation, async schema validation, or application architecture.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
sumr kontract config
|
|
27
|
+
sumr kontract config --api-style rpc-action --async-style cloud-events
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Profile axes
|
|
31
|
+
|
|
32
|
+
| Config key | Reader-facing meaning | Axis reference |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `apiStyle` | API path and component example style. | `api-styles.rf.md` |
|
|
35
|
+
| `asyncStyle` | async schema channel/address and message example style. | `async-styles.rf.md` |
|
|
36
|
+
| `schemaLayoutStyle` | Schema layout style for schema file and folder examples. | `schema-layout-styles.rf.md` |
|
|
37
|
+
|
|
38
|
+
Read the axis-specific references before writing examples. Do not infer file
|
|
39
|
+
moves from the profile alone: the profile is guidance-only.
|
|
40
|
+
|
|
41
|
+
## CLI and YAML names
|
|
42
|
+
|
|
43
|
+
Use `schemaLayoutStyle` in `sumr.yaml` and `--schema-layout-style` in the CLI.
|
|
44
|
+
Do not use organization wording for this axis.
|
|
45
|
+
|
|
46
|
+
## Safe interpretation
|
|
47
|
+
|
|
48
|
+
- HTTP examples must follow `apiStyle`.
|
|
49
|
+
- async schema examples must follow `asyncStyle`, but only when the repo has
|
|
50
|
+
async schema sources/targets or the user asks for messaging contracts.
|
|
51
|
+
- Schema file/folder examples must follow `schemaLayoutStyle`, described as the
|
|
52
|
+
schema layout style.
|
|
53
|
+
- If the repo is API-only, keep examples API-only; do not add
|
|
54
|
+
`*.async.yml`, channels, messages, or `messages/` folders only because the
|
|
55
|
+
profile has an `asyncStyle` default.
|
|
56
|
+
- If the repo is async-only, keep examples async-only; do not add
|
|
57
|
+
`*.api.yml`, paths, parameters, or HTTP responses only because the profile
|
|
58
|
+
has an `apiStyle` default.
|
|
59
|
+
- If the repo has both protocols, keep API schema and async schema roots and
|
|
60
|
+
protocol-specific folders separate. Share only components with
|
|
61
|
+
identical meaning, especially enums and scalar value objects.
|
|
62
|
+
- If an agent recommends moving root specs, it must call out that generated
|
|
63
|
+
output namespaces/import paths can change because Kontract mirrors root spec
|
|
64
|
+
paths under the configured source input directory.
|