@klok-integration/cli 0.7.248 → 0.7.269
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/README.md +5 -3
- package/assets/agents/AGENTS.datamodel.md +11 -7
- package/assets/agents/AGENTS.documentation.md +4 -0
- package/assets/agents/AGENTS.integration.md +5 -2
- package/assets/agents/AGENTS.workspace.md +11 -2
- package/assets/agents/knowledge/glossary.md +2 -1
- package/assets/agents/knowledge/platform-rules.md +10 -5
- package/assets/agents/knowledge/retired-patterns.txt +11 -0
- package/assets/agents/knowledge/roles/integration-architect.md +5 -4
- package/assets/agents/knowledge/roles/integration-developer.md +8 -7
- package/assets/agents/skills/klok-cli/SKILL.md +17 -3
- package/assets/agents/skills/klok-cli/reference.md +85 -7
- package/assets/agents/skills/klok-datamodel/SKILL.md +19 -11
- package/assets/agents/skills/klok-docs/SKILL.md +4 -2
- package/assets/agents/skills/klok-route/SKILL.md +4 -3
- package/assets/agents/skills/klok-solution/SKILL.md +11 -4
- package/assets/agents/skills/klok-worktree/SKILL.md +3 -1
- package/dist/cli.js +7 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,8 +25,8 @@ variable: `KLOK_AGENT_URL`, `KLOK_TENANT`, `KLOK_DOMAIN`, `KLOK_DEV_URL`, `KLOK_
|
|
|
25
25
|
`KLOK_KEYCLOAK_CLIENT_ID`, `KLOK_GIT_URL`, `KLOK_GIT_LOCAL_WORKSPACE`, `KLOK_GIT_APIKEY`. Run
|
|
26
26
|
`klok config list` to see what is set and where it comes from.
|
|
27
27
|
|
|
28
|
-
The GitLab token can be stored with `klok config set klokApiKey
|
|
29
|
-
history
|
|
28
|
+
The GitLab token can be stored with `klok config set klokApiKey`: it asks `Enter API key:` and shows a `*` for
|
|
29
|
+
each character, so the token stays off the screen and out of the shell history. It is shown as `****` everywhere unless you run `klok config get klokApiKey --reveal`, and the file
|
|
30
30
|
is kept at mode 0600.
|
|
31
31
|
|
|
32
32
|
Credentials are written to `~/.config/klok/credentials.json` with mode 0600.
|
|
@@ -53,7 +53,9 @@ Credentials are written to `~/.config/klok/credentials.json` with mode 0600.
|
|
|
53
53
|
| `klok docs id [path]` | The doc id of a repository path. |
|
|
54
54
|
| `klok docs publish` | Build this repository's znai documentation and upload it to the docs portal. |
|
|
55
55
|
| `klok docs build` | Build this repository's `klok-docs/` with znai the way its documentation project will, uploading nothing. |
|
|
56
|
-
| `klok solutions
|
|
56
|
+
| `klok solutions next` | The next free solution id of the tenant, from the registry, its open merge requests and the route classes on every branch of the workspace. |
|
|
57
|
+
| `klok solutions new "<name>"` | Reserve the next solution id by a merge request in the registry, from a task worktree. |
|
|
58
|
+
| `klok solutions validate` | Check the descriptors of an integration solution registry against the descriptor contract and, in a merge request, that no solution is removed and no solution id reused or taken twice. |
|
|
57
59
|
| `klok ci env` | Show what klok-cli detected about the CI job it runs in. |
|
|
58
60
|
| `klok fleet status\|rebuild` | Every deployed service: what it was built from, whether that is the latest commit and the catalog's broker client, and which clients the broker sees; rebuild the stale ones one pipeline at a time. |
|
|
59
61
|
| `klok manifest update` | Set a container's image in a deploy manifest of your GitOps repository, then commit and push. |
|
|
@@ -8,19 +8,23 @@ dependency catalog. Read `klok docs read klok-framework-klok-common` for naming
|
|
|
8
8
|
### Rules
|
|
9
9
|
|
|
10
10
|
* One root element `<Name>_vN` that references every complex type; a single `xs:` prefix; `targetNamespace` and
|
|
11
|
-
`xmlns:tns` set; `elementFormDefault="qualified"`. Validate with
|
|
12
|
-
|
|
11
|
+
`xmlns:tns` set; `elementFormDefault="qualified"`. Validate with `klok datamodel validate` before pushing; it
|
|
12
|
+
applies the rules of the pipeline's `generate_avro_from_xsd`.
|
|
13
13
|
* One name, in kebab case, from the repository down: `customer-v1` is the repository, the XSD file
|
|
14
14
|
(`customer-v1.xsd`), the Maven artifact and the npm and Python packages, and `customer_v1` ends the Java package.
|
|
15
15
|
Inside the XSD the model keeps its PascalCase form: root element `Customer_v1`, root type and class `CustomerV1`.
|
|
16
16
|
* The major version is part of the model name; a breaking change is a new major version and a new topic, never a
|
|
17
17
|
silent change of an existing one.
|
|
18
|
-
* `
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
* `klok-datamodel-project.json` at the root is the model's metadata (name, description, class, model type,
|
|
19
|
+
`targetNamespace`, template version), rendered from `klok/environment/project-template-datamodel`; klok.dev and
|
|
20
|
+
the documentation payload read it. The pipeline takes the artifact and the Java package from the repository path
|
|
21
|
+
and the XSD file name, never from metadata.
|
|
22
|
+
* Consumers reference the artifact only through the catalog alias (`klokLibs.<key>` for tenant klok's models,
|
|
23
|
+
`tenantLibs.<key>` for another tenant's), never by literal version.
|
|
21
24
|
* Datamodel documentation lives in `klok-docs/` (purpose, fields that need explanation, producers and consumers,
|
|
22
|
-
design decisions)
|
|
23
|
-
|
|
25
|
+
design decisions); `klok-docs/README.md` says which page holds which, and is never published. The datamodel
|
|
26
|
+
pipeline's `klok_docs_publish` job sends it with the XSD to docs.klok.dev, where the model is documented from the
|
|
27
|
+
XSD (a structure page, then AI sections from the complex types up) under
|
|
24
28
|
`<tenant>/documentation/datamodel/<same path>`. Put `xs:documentation` on types and fields; that is what the
|
|
25
29
|
generated text is written from.
|
|
26
30
|
* The repository's path is its class: `public` (A), `common` (B), `domain/<d>` (C) or `system/<s>` (X). The wider
|
|
@@ -24,6 +24,10 @@ content arrives here. There are two kinds, and they are edited differently:
|
|
|
24
24
|
* The doc id must start with the tenant prefix (`<tenant>-...`); the pipeline refuses others. Do not set the
|
|
25
25
|
tenant, the Vault path or upload tokens in the project CI. This project's `.gitlab-ci.yml` is the include of
|
|
26
26
|
`klok/environment/build-ci-templates:/klok-docs-publish.yml` and nothing else; the job is `klok docs publish`.
|
|
27
|
+
* `klok-documented-project.json` at the root names the source project and the doc ids, and KlokDocumentationEgress
|
|
28
|
+
writes it. `"state": "retired"` there makes `klok docs publish` take every doc id it names (`docId`,
|
|
29
|
+
`previousDocIds`) off the portal instead of uploading; `--dry-run` lists them. Do not edit it to keep a project
|
|
30
|
+
published: its state follows the source project.
|
|
27
31
|
* Visibility follows `meta.json` `scope` (`global`, `tenant`, `domain`, `system`); a page that must not be seen by
|
|
28
32
|
another domain belongs in a project with that scope, not behind a note.
|
|
29
33
|
* Preview locally with `znai preview --source=docs`, and check what a publish would do with
|
|
@@ -18,7 +18,8 @@ needs. Read `klok docs read klok-framework-klok-quarkus-extension` before writin
|
|
|
18
18
|
|
|
19
19
|
### Rules
|
|
20
20
|
|
|
21
|
-
* Route class name = route id `<TENANTSHORT><NNN><LEG><seq>_<Description>`; one solution id per business flow
|
|
21
|
+
* Route class name = route id `<TENANTSHORT><NNN><LEG><seq>_<Description>`; one solution id per business flow, and
|
|
22
|
+
its prefix is a solution registered in `<tenant>/integration-solutions` (a new one: `klok solutions new`).
|
|
22
23
|
Configuration keys are `<RouteId>.<key>` with fallback to `<SolutionId>.<key>` and `klok.route-defaults.<key>`.
|
|
23
24
|
* Datamodels are the type parameters of the pattern class and come from the catalog bundles; never hand write DTOs
|
|
24
25
|
for something a datamodel project should own.
|
|
@@ -50,7 +51,9 @@ needs. Read `klok docs read klok-framework-klok-quarkus-extension` before writin
|
|
|
50
51
|
reached with `<RouteId>.topic.tenant-override`. Never reuse another service's credentials.
|
|
51
52
|
* `application.properties` keeps every `klok.*` key explicit; secrets come from environment variables that the
|
|
52
53
|
Vault env secret provides in Kubernetes (`KLOK_BROKER_AUTH_CLIENT_ID`, ...).
|
|
53
|
-
* Update `klok-docs/` (overview, design decisions, routes, operations) in the same merge request as the
|
|
54
|
+
* Update `klok-docs/` (overview, design decisions, routes, usage, operations) in the same merge request as the
|
|
55
|
+
change. `klok-docs/README.md` says which page answers which question and how the folder reaches docs.klok.dev;
|
|
56
|
+
it is the folder's guide and is never published.
|
|
54
57
|
* On `main` the pipeline builds the image, updates the deployment manifest and publishes the documentation payload
|
|
55
58
|
that KlokDocumentationEgress turns into the documentation project; check it.
|
|
56
59
|
* The `Dockerfile` copies `build/quarkus-app/lib/` in a `COPY` of its own before `quarkus-run.jar`, `quarkus/`
|
|
@@ -14,7 +14,8 @@ what went wrong (no token, no network); say so instead of guessing.
|
|
|
14
14
|
|
|
15
15
|
On a workstation, `klok sync pull` then brings the workspace current before you read it: it fast-forwards every
|
|
16
16
|
canonical checkout under the workspace root, never merges or resets one, and skips `<root>/worktrees`. It is the one
|
|
17
|
-
sanctioned update of a canonical checkout. A
|
|
17
|
+
sanctioned update of a canonical checkout. A checkout whose GitLab project moved, was archived or is gone is reported
|
|
18
|
+
with the commands that fix it, and those are the person's to run. A service never clones a repository just to read it: klok.dev and the agent
|
|
18
19
|
read through the GitLab API, docs.klok.dev and the integration context. The `klok-cli` skill says which klok command
|
|
19
20
|
does what.
|
|
20
21
|
|
|
@@ -300,6 +301,11 @@ solution it belongs to, and new development and maintenance follow the same proc
|
|
|
300
301
|
* Route ids: `<TENANTSHORT><NNN><LEG><seq>_<Description>` (`KLK002I1_OdlScheduledQuery`); legs `I` ingress,
|
|
301
302
|
`P` processing, `E` egress, `A` API, `S` sub route, `T` timer. The class name is the route id, the config prefix
|
|
302
303
|
and the solution key.
|
|
304
|
+
* `<TENANTSHORT>` is the tenant's `shortname` in tenants.yml of `klok/environment/klok-environment-setup`: the first
|
|
305
|
+
three consonants of the tenant slug in upper case (`klok` KLK, `degerfors` DGR, `konvoj` KNV), decided by the
|
|
306
|
+
platform. A solution id `<TENANTSHORT><NNN>` is allocated by the merge request that adds its folder to
|
|
307
|
+
`<tenant>/integration-solutions` (`klok solutions new`) and never reused; a solution that stops running is retired
|
|
308
|
+
with `"status": "retired"`.
|
|
303
309
|
* Topics: `persistent://<tenant>[_<env>]/<domain>/<Model>[_<purpose>]`, request/reply
|
|
304
310
|
`ReqRes_<Req>_<Res>_Request|_Response`, dead letters `<topic>_DLQ`. The datamodel major version is in the class
|
|
305
311
|
name (`CustomerV1`). The purpose is optional and the publisher's: the solution requires it so that one datamodel
|
|
@@ -327,7 +333,7 @@ access, Keycloak broker clients or a service that serves several tenants.
|
|
|
327
333
|
* **Write narrow, consume wide.** A tenant publishes only in its own namespace, `<tenant>[_<env>]/<domain>`; nobody
|
|
328
334
|
holds `publish` in another tenant's namespace, not even on one topic. Reading elsewhere is a `consume` grant on a
|
|
329
335
|
named topic, approved by the owner and recorded in Git in the owning tenant. The topic keeps its own name; the
|
|
330
|
-
reader is known by its subscription (its route id, `
|
|
336
|
+
reader is known by its subscription (its route id, `DGR012E1_...`). When the content belongs to one reader, the
|
|
331
337
|
publisher may choose that reader's tenant slug as the purpose
|
|
332
338
|
(`persistent://konvoj/hr/PersonnelScheduleExportV1_degerfors`); that is the publisher's choice, not a condition
|
|
333
339
|
for reading across tenants.
|
|
@@ -392,6 +398,9 @@ Klok documentation has three levels, and a change is finished only when all thre
|
|
|
392
398
|
Write both **as the work happens**, not at the end of the branch. By the end nobody remembers why a choice was
|
|
393
399
|
made, and a guide written from memory describes the product somebody meant to build.
|
|
394
400
|
|
|
401
|
+
`klok-docs/README.md` is the folder's own guide for the people and agents who write it: a project made from a
|
|
402
|
+
Klok template has one that says which page answers which question. It is neither published nor read by Kloker.
|
|
403
|
+
|
|
395
404
|
Keep `klok-docs/` as the single copy. Do not mirror a page into a second `docs/` folder: two copies of one page
|
|
396
405
|
are two pages that quietly stop agreeing. `docs/` may hold what is genuinely not product documentation, such as
|
|
397
406
|
a strategy document that predates the code.
|
|
@@ -16,7 +16,8 @@ it as the source does.
|
|
|
16
16
|
| Domain | A business area inside a tenant. `common` is shared by the tenant's domains, `public` is open to anyone |
|
|
17
17
|
| Route, route id | One Camel route per Java class. Its id is `<TENANTSHORT><NNN><LEG><seq>_<Description>`, for example `KLK007T1_PublishKlokStandard`; the class name is the id |
|
|
18
18
|
| Leg | The letter in a route id: I ingress (onramp, brings data in), P processing, E egress (offramp, delivers data out), A API, S sub route, T timer |
|
|
19
|
-
|
|
|
19
|
+
| Tenant short name | `TENANTSHORT`, three upper case letters that start every solution and route id of a tenant: the first three consonants of the tenant's name (`KLK` for klok, `DGR` for degerfors), decided by the platform |
|
|
20
|
+
| Solution | The business flow a set of routes implements; its id is the route id's prefix, for example `KLK007`. The id is allocated once, by a merge request in the tenant's `integration-solutions` registry, and never reused; a solution is reserved, active or retired |
|
|
20
21
|
| Solution document | The `README.md` of a solution in the tenant's `integration-solutions` registry: its services, legs and flows, kept true to what is built |
|
|
21
22
|
| Correlation id | `klok-correlation-id`: follows one business flow across routes and messages |
|
|
22
23
|
| Task | Long-running work tracked by the platform (`KlokTaskV1` events, visible in klok.dev and the task API), for example an `ai.chat` task that asks Kloker for text |
|
|
@@ -29,9 +29,11 @@ documentation or the dependency catalog can give you.
|
|
|
29
29
|
## Routes and naming
|
|
30
30
|
|
|
31
31
|
* One Camel route per Java class. The route id is the class name, the configuration prefix and the solution key:
|
|
32
|
-
`<TENANTSHORT><NNN><LEG><seq>_<Description>` (`KLK002I1_OdlScheduledQuery`, `
|
|
33
|
-
* `TENANTSHORT`: the tenant short name, upper case
|
|
34
|
-
|
|
32
|
+
`<TENANTSHORT><NNN><LEG><seq>_<Description>` (`KLK002I1_OdlScheduledQuery`, `ACM001E1_FortnoxInvoiceOfframp`).
|
|
33
|
+
* `TENANTSHORT`: the tenant's short name, three upper case letters: the first three consonants of the tenant
|
|
34
|
+
slug (`klok` KLK, `degerfors` DGR, `konvoj` KNV), decided by the platform and recorded as `shortname` in
|
|
35
|
+
tenants.yml of `klok/environment/klok-environment-setup`. `NNN`: the solution number, three digits; 900–999
|
|
36
|
+
are the framework's. The solution id is `<TENANTSHORT><NNN>` (`KLK002`).
|
|
35
37
|
* Legs: `I` ingress, `P` processing, `E` egress, `A` API (REST, SOAP, MCP), `S` sub route or custom route,
|
|
36
38
|
`T` timer. `seq` numbers the routes of one leg in a solution.
|
|
37
39
|
* Every route extends exactly one pattern base class; never write a bare Camel `RouteBuilder`:
|
|
@@ -65,7 +67,10 @@ documentation or the dependency catalog can give you.
|
|
|
65
67
|
|
|
66
68
|
* Every route belongs to a solution, and every solution has a document: `README.md` and `solution.meta.json` in
|
|
67
69
|
`<tenant>/integration-solutions/solutions/<SOLUTIONID>_<slug>/`. A new solution gets its id and its document before
|
|
68
|
-
its first route
|
|
70
|
+
its first route. The id is allocated by the merge request that adds the folder (`klok solutions new`; `klok
|
|
71
|
+
solutions next` shows the next free number and why), and a number is never reused, not even a removed
|
|
72
|
+
solution's. A solution is `reserved`, `active` or `retired` (`status` in `solution.meta.json`); one that stops
|
|
73
|
+
running is retired, not deleted. A leg and sequence (`KLK002A11`) names one route.
|
|
69
74
|
* The document classifies every service the solution needs: new project, new routes in an existing project, reused
|
|
70
75
|
with a change, reused as is, client change. It maps the legs (route id, project, pattern, topics with purpose,
|
|
71
76
|
datamodels) and links each project's `klok-docs/` for the details.
|
|
@@ -87,7 +92,7 @@ documentation or the dependency catalog can give you.
|
|
|
87
92
|
several flows, the publisher sets it and the reader consumes the purpose the publisher chose. A topic name has at
|
|
88
93
|
most one purpose, never a second suffix.
|
|
89
94
|
* A reader is identified by its subscription, whose name is its route id (`<RouteId>.subscription.name` overrides
|
|
90
|
-
it), so the reading tenant's short name is in it (`
|
|
95
|
+
it), so the reading tenant's short name is in it (`DGR012E1_...`). A reader never appears in the topic name.
|
|
91
96
|
When the content belongs to one reader, the publisher may choose that reader's tenant slug as the purpose
|
|
92
97
|
(`persistent://konvoj/hr/PersonnelScheduleExportV1_degerfors`); that is the publisher's choice, not a condition
|
|
93
98
|
for reading across tenants.
|
|
@@ -17,6 +17,12 @@
|
|
|
17
17
|
# Route ids are <TENANTSHORT><NNN><LEG><seq>_<Description>, legs I P E A S T.
|
|
18
18
|
\bS<(NNNN|ID|SolutionID|Solution|NNN)> # old S-prefixed integration ids; use <TENANTSHORT><NNN><LEG><seq>_<Description>
|
|
19
19
|
\bS[0-9]{4}[IEP][0-9] # old S-prefixed route id such as S0001I1; use KLK002I1_... style ids
|
|
20
|
+
# Solution ids are allocated by a merge request in <tenant>/integration-solutions and never reused (2026-10-08); the
|
|
21
|
+
# tenant short name is the first three consonants of the tenant slug, shortname in tenants.yml.
|
|
22
|
+
(?i)\bsolution (number|id)s?\s+(is\s+|are\s+)?(taken\s+)?from\s+the\s+(klok\.dev|portal|klok\.dev\s+solution|portal\s+solution)\s+registry # a solution id is allocated by a merge request in <tenant>/integration-solutions (klok solutions new), never reused
|
|
23
|
+
(?i)\bid is taken from the code # a solution id is allocated by a merge request in <tenant>/integration-solutions (klok solutions new); the code on every branch only counts as used
|
|
24
|
+
(?i)\bfirst\s+(three|3)\s+letters\s+of\s+the\s+tenant # the tenant short name is the first three consonants of the tenant slug, its shortname in tenants.yml
|
|
25
|
+
(?i)\bshort\s+(name|code)s?\s+(is|are)\s+the\s+(tenant'?s?\s+)?(name'?s?\s+|slug'?s?\s+)?first\s+(three|3)\s+letters # the tenant short name is the first three consonants of the tenant slug, its shortname in tenants.yml
|
|
20
26
|
#
|
|
21
27
|
# Topics are persistent://<tenant>[_<env>]/<domain>/<Model>[_<purpose>].
|
|
22
28
|
pulsar:// # topics are persistent://<tenant>[_<env>]/<domain>/<Model>[_<purpose>]
|
|
@@ -56,3 +62,8 @@ klok-(ingress|egress)-< # integration repositories are named <tenant>-<system>-<
|
|
|
56
62
|
(^|[^<`\\])/think\b # a prompt token of an old Qwen model; the model name is the only switch (a quoted mention in a rule is fine)
|
|
57
63
|
(^|[^`])/no_think\b # a prompt token of an old Qwen model; the model name is the only switch
|
|
58
64
|
Kloker-Long # not a gateway model name; use Kloker-nothink or Kloker
|
|
65
|
+
#
|
|
66
|
+
# A datamodel's metadata is klok-datamodel-project.json, rendered from project-template-datamodel; the pipeline reads
|
|
67
|
+
# no metadata, and klok.dev does not create datamodel repositories yet (frontend-klok-dev#33, 2026-10-10).
|
|
68
|
+
(?i)meta\.json`? (uses|in) the flat form # a datamodel's metadata is klok-datamodel-project.json; *.meta.json is only klok.dev's fallback for an older repository
|
|
69
|
+
(?i)create it with klok\.dev's datamodel wizard # klok.dev's wizard edits existing models; it does not create datamodel repositories yet (frontend-klok-dev#33), they are made by hand from project-template-datamodel
|
|
@@ -13,7 +13,8 @@ name the parts, and say what is wrong when it is wrong.
|
|
|
13
13
|
1. Name the datamodel class of every payload you mention (A, B, C or X) and who reads it.
|
|
14
14
|
2. Name the legs: ingress, processing, egress, API, or a solution of several legs.
|
|
15
15
|
3. Choose one pattern base class per leg, as a design decision.
|
|
16
|
-
4. Propose the
|
|
16
|
+
4. Propose the route ids and the topic names, following the platform rules. A new solution's id is never made up:
|
|
17
|
+
it is the next free number, reserved by a merge request in the tenant's registry (`klok solutions new`).
|
|
17
18
|
5. Flag every tactical deviation with `[TACTICAL]`, its cost and its unwind condition, or say the design is
|
|
18
19
|
strategy-pure.
|
|
19
20
|
|
|
@@ -21,7 +22,7 @@ A correct answer looks like this:
|
|
|
21
22
|
|
|
22
23
|
"Visma exports invoices in its own format, a class X model. Finance and sales both read invoices, so the ingress
|
|
23
24
|
maps each invoice to the class B model `InvoiceV1` before it reaches the broker. Use `KlokOnrampRoute` as
|
|
24
|
-
`
|
|
25
|
+
`ACM001I1_VismaInvoiceOnramp`, split the nightly file into one fact event per invoice, and publish on
|
|
25
26
|
`persistent://acme/finance/InvoiceV1`. If a consumer later needs Visma's format, that mapping belongs in an egress."
|
|
26
27
|
|
|
27
28
|
A rejection names the problem and gives the broker-shaped replacement:
|
|
@@ -164,10 +165,10 @@ direct database or file share only for a system older than the team).
|
|
|
164
165
|
Imitate the density of these answers, with the user's names.
|
|
165
166
|
|
|
166
167
|
**Visma nightly invoice file.** The export is class X. Invoices are read by more than one domain, so the target is
|
|
167
|
-
the class B model `InvoiceV1`. Ingress: `KlokOnrampRoute` as `
|
|
168
|
+
the class B model `InvoiceV1`. Ingress: `KlokOnrampRoute` as `ACM001I1_VismaInvoiceOnramp`, splitting the file
|
|
168
169
|
into one fact event per invoice (a processing splitter if the mapping is heavy), published on
|
|
169
170
|
`persistent://acme/finance/InvoiceV1`. Do not publish the file as one large message unless the claim check carries
|
|
170
|
-
it and the event holds only the reference. A later Visma-shaped export is an egress, `
|
|
171
|
+
it and the event holds only the reference. A later Visma-shaped export is an egress, `ACM001E1_...`, mapping B to
|
|
171
172
|
X. Strategy-pure while each message stays small.
|
|
172
173
|
|
|
173
174
|
**A front end that wants a JSON body now.** Ingress that cannot be fire and forget: `KlokOnrampRouteSync` as a
|
|
@@ -62,7 +62,7 @@ as the CloudEvent's data.
|
|
|
62
62
|
|
|
63
63
|
```java
|
|
64
64
|
@ApplicationScoped
|
|
65
|
-
public class
|
|
65
|
+
public class ACM001I1_OrderOnramp extends KlokOnrampRoute<ShopOrder, OrderV1> {
|
|
66
66
|
@Override
|
|
67
67
|
protected String fromUri() {
|
|
68
68
|
return "platform-http:/orders";
|
|
@@ -84,7 +84,7 @@ system's reply type; the framework handles the request/reply topics and the time
|
|
|
84
84
|
|
|
85
85
|
```java
|
|
86
86
|
@ApplicationScoped
|
|
87
|
-
public class
|
|
87
|
+
public class ACM002I1_CustomerLookup
|
|
88
88
|
extends KlokOnrampRouteSync<CustomerRequest, CustomerResponse, CustomerLookupV1, CustomerV1> {
|
|
89
89
|
@Override
|
|
90
90
|
protected String fromUri() {
|
|
@@ -118,7 +118,7 @@ dead letters. Override `toUri()` and `transformBody(DOMAIN_MODEL body, Message m
|
|
|
118
118
|
|
|
119
119
|
```java
|
|
120
120
|
@ApplicationScoped
|
|
121
|
-
public class
|
|
121
|
+
public class ACM001E1_InvoiceOfframp extends KlokOfframpRoute<InvoiceV1, LegacyInvoice> {
|
|
122
122
|
@Override
|
|
123
123
|
protected String toUri() {
|
|
124
124
|
return "https://legacy-invoice-system/invoices";
|
|
@@ -198,7 +198,8 @@ blindly. `klok-mock-*` headers are for test and staging and are stripped in prod
|
|
|
198
198
|
choose between a splitter and the claim check.
|
|
199
199
|
2. **Reuse.** Before a new model, search the existing class B and C models, topics and routes, in klok.dev's
|
|
200
200
|
context and on docs.klok.dev. A new topic only for a new contract.
|
|
201
|
-
3. **Solution design.**
|
|
201
|
+
3. **Solution design.** The solution id, reserved by a merge request in `<tenant>/integration-solutions` (`klok
|
|
202
|
+
solutions new`), the legs and their route ids, the models per leg,
|
|
202
203
|
`[TACTICAL]` for any deviation, written in the solution document before the code and kept current by every change
|
|
203
204
|
of a leg (platform rules, *Solutions*).
|
|
204
205
|
4. **Design per leg.** Base class, exchange pattern, URI, authentication (a Vault path reference, never a secret),
|
|
@@ -237,11 +238,11 @@ blindly. `klok-mock-*` headers are for test and staging and are stripped in prod
|
|
|
237
238
|
|
|
238
239
|
## Worked answers
|
|
239
240
|
|
|
240
|
-
**CRM over HTTP to Visma over JMS.** `
|
|
241
|
+
**CRM over HTTP to Visma over JMS.** `ACM001I1_CrmCustomerOnramp extends KlokOnrampRoute<CrmCustomer, CustomerV1>`
|
|
241
242
|
with `fromUri` on the CRM webhook and a `transformBody` that sets `customerId`, `fullName` and `email`; it publishes
|
|
242
|
-
`persistent://acme/sales/CustomerV1`. `
|
|
243
|
+
`persistent://acme/sales/CustomerV1`. `ACM001E1_VismaCustomerOfframp extends KlokOfframpRoute<CustomerV1,
|
|
243
244
|
VismaCustomer>` with `toUri` on the JMS queue and a `transformBody` into Visma's model. Validation that is a business
|
|
244
|
-
rule is `
|
|
245
|
+
rule is `ACM001P1_CustomerValidation`, a `KlokProcessingRoute` between two topics, not extra code in the onramp.
|
|
245
246
|
|
|
246
247
|
**Synchronous lookup.** First choice: `KlokOnrampRoute` answering 202 with a task reference and a status the caller
|
|
247
248
|
can poll. If the UI must have a synchronous answer: `KlokOnrampRouteSync` as above, a timeout of 10 to 20 seconds, the
|
|
@@ -18,11 +18,12 @@ CLI version, generated from the program itself; when it is missing (an installer
|
|
|
18
18
|
| to know the agent instructions and skills are current, at the start of a task | `klok agents update --check` (exit 5: run `klok agents update`) |
|
|
19
19
|
| the local workspace current before you read it | `klok sync pull` |
|
|
20
20
|
| a repository you can see in GitLab but do not have locally | `klok sync clone --dry-run`, then `klok sync clone` |
|
|
21
|
-
| what is dirty, unpushed or behind in the workspace | `klok sync status` (`--fetch` for a current "behind") |
|
|
21
|
+
| what is dirty, unpushed or behind in the workspace, or moved, archived or gone in GitLab | `klok sync status` (`--fetch` for a current "behind") |
|
|
22
22
|
| the documentation projects you may read | `klok docs list` |
|
|
23
23
|
| one project's documentation | `klok docs read <doc-id>`; `klok docs id <tenant/group/.../repo>` derives a doc id |
|
|
24
24
|
| an answer about the integration landscape, with links | `klok agent ask "<question>"`; `--session <first task id>` for a follow-up |
|
|
25
25
|
| the impact of a datamodel change | `klok agent impact <datamodel> --change minor\|major\|remove` |
|
|
26
|
+
| the next free solution id of the tenant, with why, or a new solution's id reserved by a merge request | `klok solutions next`, `klok solutions new "<name>" --dry-run`, then without `--dry-run` |
|
|
26
27
|
| the solution registry checked against its contract, or against the code | `klok solutions validate`, `klok solutions check` |
|
|
27
28
|
| whether the deployed services run what `main` and the catalog say | `klok fleet status` |
|
|
28
29
|
| the platform catalog's agent assets or its dependents | `klok catalog publish-agents`, `klok catalog release-dependents` (both run in CI) |
|
|
@@ -40,17 +41,30 @@ CLI version, generated from the program itself; when it is missing (an installer
|
|
|
40
41
|
key `workspace`, `KLOK_GIT_LOCAL_WORKSPACE`, default `~/devklok`) is fetched and fast-forwarded (`git pull
|
|
41
42
|
--ff-only`). It never merges, rebases or resets, so a checkout with local commits or a diverged branch is reported,
|
|
42
43
|
not changed, and `<root>/worktrees` (the task worktrees) is skipped. It is the one sanctioned update of a canonical
|
|
43
|
-
checkout, made on a workstation.
|
|
44
|
+
checkout, made on a workstation. `pull` and `status` also ask GitLab about each checkout and report one whose project
|
|
45
|
+
moved, was archived or is gone, with the commands that fix it (`remote set-url`, `mv`, `git worktree repair`); they
|
|
46
|
+
move nothing, and those commands are the person's to run. `klok sync clone` does not clone a project that is already
|
|
47
|
+
checked out under its old path. Edits still happen in a task worktree (the `klok-worktree` skill). A service never
|
|
44
48
|
clones a repository just to read it: klok.dev and the agent read through the GitLab API, docs.klok.dev and the
|
|
45
49
|
integration context.
|
|
46
50
|
|
|
47
51
|
## Reading
|
|
48
52
|
|
|
49
53
|
`klok docs list`, then `klok docs read <doc-id>`, is how to read the platform's documentation; the `klok-docs` skill
|
|
50
|
-
has the doc ids that matter most and what a 401, 403 or 404 means.
|
|
54
|
+
has the doc ids that matter most and what a 401, 403 or 404 means. A doc id that moved with its renamed project is
|
|
55
|
+
followed to the new one, and stderr says `<old-id> moved to <new-id>`: use the new id from then on. `klok agent ask` asks Kloker, which reads the
|
|
51
56
|
solution registry, the integration context and the documentation you may read, and answers with links; it is the
|
|
52
57
|
quickest way to find which project, leg or topic handles something.
|
|
53
58
|
|
|
59
|
+
## klok.dev
|
|
60
|
+
|
|
61
|
+
The CLI is meant to do everything klok.dev does, as the person, but only part of the portal has its command yet
|
|
62
|
+
(`klok whoami`, the agent commands, `klok solutions`). When a task needs something klok.dev shows and no klok command
|
|
63
|
+
prints it, such as a broker topic's publishers and subscriptions, an ODL record or a task's events, say so and ask the
|
|
64
|
+
person to look it up in klok.dev or to send it. Do not scrape the portal, and do not reach for credentials the task
|
|
65
|
+
was not given (a service token, a secret read out of Vault) to get around the gap. `klok fleet status --broker` is an
|
|
66
|
+
operator command for the person to run, not a way in.
|
|
67
|
+
|
|
54
68
|
## Exit codes
|
|
55
69
|
|
|
56
70
|
`0` ok, `1` error, `2` a task waits for input, `3` denied by policy, `4` not authenticated, `5` outdated (instructions,
|
|
@@ -118,7 +118,7 @@ Print one effective configuration value; secrets show as **** unless --reveal
|
|
|
118
118
|
klok config set [options] <key> [value]
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
-
Set a value. Keys: agentUrl, tenant, klokDevUrl, keycloakIssuer, keycloakClientId, protocol, domain, gitUrl, workspace, klokerBasePath, klokerUrl, klokerModel, summaryLanguage, klokApiKey. Leave out the value of a secret (klokApiKey) to type it at a
|
|
121
|
+
Set a value. Keys: agentUrl, tenant, klokDevUrl, keycloakIssuer, keycloakClientId, protocol, domain, gitUrl, workspace, klokerBasePath, klokerUrl, klokerModel, summaryLanguage, klokApiKey. Leave out the value of a secret (klokApiKey) to type it at a prompt that shows * for each character, or pipe it in, so it stays off the screen and out of the shell history
|
|
122
122
|
|
|
123
123
|
| Argument | Description |
|
|
124
124
|
|---|---|
|
|
@@ -661,7 +661,7 @@ Read the platform documentation on docs.klok.dev, and publish this repository’
|
|
|
661
661
|
klok docs read [options] <doc-id>
|
|
662
662
|
```
|
|
663
663
|
|
|
664
|
-
Print the llm.txt of a documentation project on docs.klok.dev, the one markdown file with its whole content, read with your GitLab token. Cached under ~/.cache/klok/docs with the ETag, so a second read is one conditional request; without network the cache is served with a warning. With --json the document carries the content and where it came from; otherwise the content goes to stdout and one status line to stderr.
|
|
664
|
+
Print the llm.txt of a documentation project on docs.klok.dev, the one markdown file with its whole content, read with your GitLab token. Cached under ~/.cache/klok/docs with the ETag, so a second read is one conditional request; without network the cache is served with a warning. A doc id that moved (its project was renamed) is followed once to the new one, said on stderr and cached under the new id; with --json, docId is the id read, requestedDocId the one asked for and movedTo is set. With --json the document carries the content and where it came from; otherwise the content goes to stdout and one status line to stderr.
|
|
665
665
|
|
|
666
666
|
| Argument | Description |
|
|
667
667
|
|---|---|
|
|
@@ -756,7 +756,7 @@ Publish this repository’s klok-docs/ to the documentation chain (projects not
|
|
|
756
756
|
klok docs publish [options]
|
|
757
757
|
```
|
|
758
758
|
|
|
759
|
-
Build the znai project and upload it under this project’s doc id
|
|
759
|
+
Build the znai project and upload it under this project’s doc id. When klok-documented-project.json at the repository root says state "retired", unpublish its docId and every previousDocIds entry instead (DELETE with the upload token; 404 counts as done) and upload nothing.
|
|
760
760
|
|
|
761
761
|
| Option | Description |
|
|
762
762
|
|---|---|
|
|
@@ -764,7 +764,7 @@ Build the znai project and upload it under this project’s doc id
|
|
|
764
764
|
| `--doc-id <id>` | Publish under this doc id instead of the derived one |
|
|
765
765
|
| `--repo-path <path>` | Repository path to derive from (default: CI_PROJECT_PATH or the git remote) |
|
|
766
766
|
| `--znai <path>` | The znai executable (default: znai on PATH) |
|
|
767
|
-
| `-n, --dry-run` | Resolve what would be published and build it with znai, upload nothing |
|
|
767
|
+
| `-n, --dry-run` | Resolve what would be published and build it with znai, upload nothing; for a retired project, say what would be unpublished |
|
|
768
768
|
| `--no-build` | With --dry-run: only resolve the plan, do not run znai |
|
|
769
769
|
|
|
770
770
|
## klok fleet
|
|
@@ -1017,11 +1017,86 @@ The integration solution registry (<tenant>/integration-solutions)
|
|
|
1017
1017
|
klok solutions validate [options]
|
|
1018
1018
|
```
|
|
1019
1019
|
|
|
1020
|
-
Check every solutions/<SOLUTIONID>_<slug>/solution.meta.json against the descriptor contract
|
|
1020
|
+
Check every solutions/<SOLUTIONID>_<slug>/solution.meta.json against the descriptor contract and, against a base, that no solution is removed, no number reused, no retired solution revived and no id taken by an earlier merge request
|
|
1021
1021
|
|
|
1022
1022
|
| Option | Description |
|
|
1023
1023
|
|---|---|
|
|
1024
1024
|
| `--root <dir>` | Checkout of the registry (default: the current directory) |
|
|
1025
|
+
| `--base <ref>` | Compare the change with this commit (default: the diff base of a merge request pipeline; none elsewhere) |
|
|
1026
|
+
| `--token <token>` | GitLab token that lists the registry's open merge requests (default: KLOK_GIT_APIKEY, then config klokApiKey, then the CI job token) |
|
|
1027
|
+
| `--offline` | Do not ask GitLab for the open merge requests (skips solution-id-claimed) |
|
|
1028
|
+
|
|
1029
|
+
```
|
|
1030
|
+
In a merge request pipeline the base is CI_MERGE_REQUEST_DIFF_BASE_SHA and the job needs the whole history
|
|
1031
|
+
(GIT_DEPTH: "0"). On a branch or main pipeline there is no base, so removing a solution is possible there: that is
|
|
1032
|
+
how a platform admin removes one, on main. A number stays spent either way.
|
|
1033
|
+
|
|
1034
|
+
Examples:
|
|
1035
|
+
klok solutions validate # in a checkout of the registry
|
|
1036
|
+
klok solutions validate --base origin/main # a change on a branch, before pushing it
|
|
1037
|
+
```
|
|
1038
|
+
|
|
1039
|
+
### klok solutions next
|
|
1040
|
+
|
|
1041
|
+
```
|
|
1042
|
+
klok solutions next [options]
|
|
1043
|
+
```
|
|
1044
|
+
|
|
1045
|
+
The next free solution id of the tenant: one more than the highest number in the registry, its history, its branches and open merge requests, and the route classes on every branch of the tenant's repositories
|
|
1046
|
+
|
|
1047
|
+
| Option | Description |
|
|
1048
|
+
|---|---|
|
|
1049
|
+
| `--root <dir>` | Checkout of the registry (default: <workspace>/<tenant>/integration-solutions) |
|
|
1050
|
+
| `--workspace <dir>` | Workspace root that `klok sync` mirrors into (default: the configured workspace) |
|
|
1051
|
+
| `--tenant-short <short>` | The tenant's short name, three upper case letters (default: the one the registry's solution ids share) |
|
|
1052
|
+
| `--token <token>` | GitLab token that reads the registry's open merge requests (default: KLOK_GIT_APIKEY, then config klokApiKey) |
|
|
1053
|
+
| `--offline` | Neither fetch the registry nor ask GitLab for its open merge requests |
|
|
1054
|
+
|
|
1055
|
+
```
|
|
1056
|
+
Fetches the registry first (git fetch --prune origin). The repositories are read as last fetched; when one was
|
|
1057
|
+
fetched more than a day ago it says so, and `klok sync pull` refreshes them. Numbers 900-999 are the framework's and
|
|
1058
|
+
a gap is never filled. Nothing is written: reserve the id with `klok solutions new`.
|
|
1059
|
+
|
|
1060
|
+
Examples:
|
|
1061
|
+
klok solutions next
|
|
1062
|
+
klok solutions next --root . --json # in a checkout or worktree of the registry
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
### klok solutions new
|
|
1066
|
+
|
|
1067
|
+
```
|
|
1068
|
+
klok solutions new [options] <name>
|
|
1069
|
+
```
|
|
1070
|
+
|
|
1071
|
+
Reserve the next solution id: a task worktree of the registry, a folder with a reserved descriptor and a stub document, one commit, and a push that opens the merge request, which is the allocation
|
|
1072
|
+
|
|
1073
|
+
| Argument | Description |
|
|
1074
|
+
|---|---|
|
|
1075
|
+
| `<name>` | required |
|
|
1076
|
+
|
|
1077
|
+
| Option | Description |
|
|
1078
|
+
|---|---|
|
|
1079
|
+
| `--root <dir>` | Checkout of the registry (default: <workspace>/<tenant>/integration-solutions) |
|
|
1080
|
+
| `--workspace <dir>` | Workspace root that `klok sync` mirrors into (default: the configured workspace) |
|
|
1081
|
+
| `--tenant-short <short>` | The tenant's short name, three upper case letters (default: the one the registry's solution ids share) |
|
|
1082
|
+
| `--token <token>` | GitLab token that reads the registry's open merge requests (default: KLOK_GIT_APIKEY, then config klokApiKey) |
|
|
1083
|
+
| `--offline` | Neither fetch the registry nor ask GitLab for its open merge requests |
|
|
1084
|
+
| `--slug <slug>` | kebab-case name of the folder and the url (default: from the name) |
|
|
1085
|
+
| `--domain <domain>` | Information domain (Finance, HR, AI, ...) |
|
|
1086
|
+
| `--description <text>` | One or two sentences: what the solution keeps in step, in business terms |
|
|
1087
|
+
| `--dry-run` | Print the id, the worktree and the files, and create nothing |
|
|
1088
|
+
|
|
1089
|
+
```
|
|
1090
|
+
The id is the one `klok solutions next` gives, after fetching the registry. The worktree is
|
|
1091
|
+
<workspace>/worktrees/<tenant>/integration-solutions/<YYYYMMDD>-solution-<id>-<8 hex> on the branch agent/<task id>,
|
|
1092
|
+
based on the registry's default branch; the canonical checkout is not touched. The push uses your own git setup and
|
|
1093
|
+
asks GitLab, with push options, to open the merge request against the default branch. The commit is
|
|
1094
|
+
docs(<ID>): reserve <ID> for <name>.
|
|
1095
|
+
|
|
1096
|
+
Examples:
|
|
1097
|
+
klok solutions new "Payroll export to Personec" --domain HR --dry-run
|
|
1098
|
+
klok solutions new "Payroll export to Personec" --domain HR
|
|
1099
|
+
```
|
|
1025
1100
|
|
|
1026
1101
|
### klok solutions check
|
|
1027
1102
|
|
|
@@ -1070,10 +1145,11 @@ Discover every repository you can see and clone the missing ones
|
|
|
1070
1145
|
klok sync pull [options]
|
|
1071
1146
|
```
|
|
1072
1147
|
|
|
1073
|
-
Fast-forward every repository in the workspace
|
|
1148
|
+
Fast-forward every repository in the workspace, and report checkouts whose GitLab project moved, was archived or is gone
|
|
1074
1149
|
|
|
1075
1150
|
| Option | Description |
|
|
1076
1151
|
|---|---|
|
|
1152
|
+
| `--no-remote-check` | Do not ask GitLab whether the checkouts’ projects moved, were archived or are gone |
|
|
1077
1153
|
| `-w, --workspace <path>` | Workspace directory (default: config workspace) |
|
|
1078
1154
|
| `--token <token>` | GitLab token (default: KLOK_GIT_APIKEY, then config klokApiKey) |
|
|
1079
1155
|
| `-j, --jobs <n>` | Parallel git operations (default: `6`) |
|
|
@@ -1086,7 +1162,7 @@ Fast-forward every repository in the workspace
|
|
|
1086
1162
|
klok sync status [options]
|
|
1087
1163
|
```
|
|
1088
1164
|
|
|
1089
|
-
Show dirty trees, unpushed commits and branches behind their remote (as of the last fetch)
|
|
1165
|
+
Show dirty trees, unpushed commits and branches behind their remote (as of the last fetch), and checkouts whose GitLab project moved, was archived or is gone
|
|
1090
1166
|
|
|
1091
1167
|
| Option | Description |
|
|
1092
1168
|
|---|---|
|
|
@@ -1094,3 +1170,5 @@ Show dirty trees, unpushed commits and branches behind their remote (as of the l
|
|
|
1094
1170
|
| `-j, --jobs <n>` | Parallel git operations (default: `12`) |
|
|
1095
1171
|
| `-a, --all` | List every repository, not only the ones needing attention |
|
|
1096
1172
|
| `--fetch` | Fetch every repository first, so "behind" is current |
|
|
1173
|
+
| `--token <token>` | GitLab token for the GitLab check (default: KLOK_GIT_APIKEY, then config klokApiKey) |
|
|
1174
|
+
| `--no-remote-check` | Do not ask GitLab whether the checkouts’ projects moved, were archived or are gone |
|
|
@@ -34,27 +34,34 @@ domains read should still travel as class B or C (transform at the edge).
|
|
|
34
34
|
ends in `supplier_invoice_v1`. Inside the XSD the model keeps its PascalCase form: root element
|
|
35
35
|
`SupplierInvoice_v1`, root type `SupplierInvoiceV1`.
|
|
36
36
|
|
|
37
|
-
**Create it
|
|
38
|
-
|
|
39
|
-
(klok/application/frontend-klok-dev#33)
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
**Create it by hand from the template.** klok.dev edits existing models through a merge request but does not
|
|
38
|
+
create datamodel repositories yet, because it cannot render the template's `__KLOK_*__` placeholders for them
|
|
39
|
+
(klok/application/frontend-klok-dev#33); it points to the way by hand instead. The agent at
|
|
40
|
+
https://agent.klok.dev cannot create datamodel projects either (klok/application/frontend-klok-dev#42).
|
|
41
|
+
`klok datamodel names --class <A|B|C|X> --name <PascalCase> --major <n>` (with `--system` for class X and the
|
|
42
|
+
global `--domain` for class C) prints every derived value: repository, XSD file, root element, root type,
|
|
43
|
+
`targetNamespace` and the documentation project.
|
|
42
44
|
|
|
43
45
|
By hand it is: `git clone` the template, `git remote rename origin template`, `git remote add origin <new
|
|
44
46
|
repo>`, render every `__KLOK_*__` token listed in `klok-template.json` (including the XSD file name), push
|
|
45
47
|
`main`. Keep the `template` remote so later template improvements can be pulled in. Never assemble the
|
|
46
48
|
project by copying files out of a sibling datamodel: the copies go stale and whole files get missed
|
|
47
|
-
(`klok-datamodel-project.json`, `klok-template.json`, the agent instruction files,
|
|
48
|
-
`
|
|
49
|
+
(`klok-datamodel-project.json`, `klok-template.json`, the agent instruction files, `klok-docs/` with its
|
|
50
|
+
guide `README.md` and the `datamodel/` pages).
|
|
49
51
|
|
|
50
52
|
Vault needs nothing per project: the tenant CI role `<tenant>-ci` accepts every project under the tenant's
|
|
51
53
|
root group. If `publish_java_projects` fails at `auth/jwt/login`, the tenant itself is not set up; see the
|
|
52
54
|
`klok-release` skill.
|
|
53
55
|
2. Write the XSD under `schema-definition-xsd/`: single `xs:` prefix, `targetNamespace` with `xmlns:tns`,
|
|
54
56
|
`elementFormDefault="qualified"`, one root element `<Name>_vN` that references every complex type. Enumerations
|
|
55
|
-
as `xs:enumeration`.
|
|
56
|
-
3. `
|
|
57
|
-
the
|
|
57
|
+
as `xs:enumeration`. `klok datamodel validate` checks it with the pipeline's rules before you push.
|
|
58
|
+
3. `klok-datamodel-project.json` at the root is the model's metadata (name, description, class, model type,
|
|
59
|
+
`targetNamespace`, template version), rendered from the template; klok.dev and the documentation payload read
|
|
60
|
+
it. An older repository's `schema-definition-xsd/*.meta.json` is only klok.dev's fallback for a repository
|
|
61
|
+
without it, so keep one of the two, not both. The pipeline takes the artifact and the Java package from the
|
|
62
|
+
repository path and the XSD file name, never from metadata. `klok-docs/datamodel/` holds the three pages of the
|
|
63
|
+
template (`index`, `usage`, `changes`): the purpose, the fields that need explaining, the producers and consumers
|
|
64
|
+
and the history of compatible changes.
|
|
58
65
|
4. A breaking change is a new major version (`Customer_v2`), which is a new class, a new topic and a new catalog
|
|
59
66
|
key; a compatible change (optional field) stays in the same version. The old and the new version run in
|
|
60
67
|
parallel while readers move, at least the class's minimum (table above) and until every known reader
|
|
@@ -72,7 +79,8 @@ domains read should still travel as class B or C (transform at the edge).
|
|
|
72
79
|
## Using a model in a project
|
|
73
80
|
|
|
74
81
|
* Run `./gradlew updateKlokLibsToml` in the consumer, commit the refreshed `gradle/klok-libs.versions.toml`, and
|
|
75
|
-
reference the alias (`klokLibs.klokOdlV1` or the bundle
|
|
82
|
+
reference the alias, the project name in camel case (`klokLibs.klokOdlV1` or the bundle for tenant klok's
|
|
83
|
+
models, `tenantLibs.<alias>` for another tenant's). Never type a version.
|
|
76
84
|
* The generated class is `dev.klok.<tenant>.datamodel.<group>.<name_with_underscores>_v<n>.<Name>Vn` (for
|
|
77
85
|
`klok-task-event-v1`: `dev.klok.klok.datamodel.common.klok_task_event_v1.KlokTaskStatusEventV1`); the ODL type of an object is the
|
|
78
86
|
fully qualified class name, so moving a class to another package is a data migration of its ODL index.
|
|
@@ -12,7 +12,7 @@ serves it to a browser session and to a GitLab personal access token, which is w
|
|
|
12
12
|
```
|
|
13
13
|
klok docs list # the projects you may read: doc id, title, description
|
|
14
14
|
klok docs read <doc-id> # the markdown on stdout, one status line on stderr
|
|
15
|
-
klok docs read <doc-id> --json # {docId, url, source, status, etag, fetchedAt, bytes, content}
|
|
15
|
+
klok docs read <doc-id> --json # {docId, requestedDocId, movedTo, url, source, status, etag, fetchedAt, bytes, content}
|
|
16
16
|
klok docs read <doc-id> --out x.md # to a file
|
|
17
17
|
klok docs id [tenant/group/.../repo] # the doc id of a repository, this one by default
|
|
18
18
|
```
|
|
@@ -59,6 +59,7 @@ question is about what a project does.
|
|
|
59
59
|
| `klok docs read` says | Meaning | What to do |
|
|
60
60
|
|---|---|---|
|
|
61
61
|
| the content, `source: server` or `source: cache` | the page as published, or the cached copy | read it |
|
|
62
|
+
| `klok docs read: <old-id> moved to <new-id>` on stderr, then the content | the project was renamed or moved; the content is the new id's | read it, cite the new id (`docId` of `--json`), and fix the link or note the old id came from |
|
|
62
63
|
| exit 4, "No or invalid GitLab token" | no `KLOK_GIT_APIKEY` (or `--token`), or the token is not valid | say so and ask for a token with `read_api`; do not guess |
|
|
63
64
|
| "not a member of the tenant or domain that owns …" (403) | the page exists and your GitLab account may not read it | say so and ask for access; do not guess and do not try another way in |
|
|
64
65
|
| "… is not published; read the repository's klok-docs/ on main" (404) | the project has no published documentation yet | read the source pages: `git -C <repo> fetch origin && git show origin/main:klok-docs/<page>.md`; `klok-docs/toc-manifest.json` lists them. The generated pages (routes, datamodels, configuration) exist only on the portal |
|
|
@@ -75,4 +76,5 @@ question is about what a project does.
|
|
|
75
76
|
runbook in `klok-framework-development-guide` when it touches onboarding; read the framework documentation
|
|
76
77
|
before writing or changing a route.
|
|
77
78
|
5. Cite the doc id and the `fetchedAt` from `klok docs read <doc-id> --json` in your answer or merge request
|
|
78
|
-
description, so reviewers can tell which version of the page you relied on.
|
|
79
|
+
description, so reviewers can tell which version of the page you relied on. After a move, `docId` is the new id;
|
|
80
|
+
cite that one.
|
|
@@ -17,8 +17,9 @@ motivates.
|
|
|
17
17
|
`KlokProcessingRoute<IN, OUT>`; egress to a system: `KlokOfframpRoute<DOM, SYS>`; synchronous request/reply:
|
|
18
18
|
the `Sync` variants; REST: `KlokRestApi` plus one `KlokRestApiHandlerRoute` per operation; long running work:
|
|
19
19
|
`KlokAsyncTaskWorkerRoute<REQ, RES>`; anything else: `KlokCustomRoute`.
|
|
20
|
-
2. **Name it.** `<TENANTSHORT><NNN><LEG><seq>_<Description>`, one class per route
|
|
21
|
-
|
|
20
|
+
2. **Name it.** `<TENANTSHORT><NNN><LEG><seq>_<Description>`, one class per route. `<TENANTSHORT><NNN>` is the id of
|
|
21
|
+
the solution in `<tenant>/integration-solutions`, allocated there by a merge request (`klok solutions new`).
|
|
22
|
+
Sub routes are `S`, timers `T`.
|
|
22
23
|
3. **Bind the datamodels** as type parameters; take them from the catalog bundle, never hand written DTOs.
|
|
23
24
|
4. **Choose the topic purpose** of every topic the route publishes or consumes (*Topic purpose*), and make sure every
|
|
24
25
|
topic exists (*Topics on the broker*): the broker never creates one.
|
|
@@ -74,7 +75,7 @@ the purpose.
|
|
|
74
75
|
* **Name** the flow as both sides understand it (`created`, `reminder`, `documentation`): letters, digits, `-` and
|
|
75
76
|
`.`, never `_`, and no version or environment. Task types are `<domain>.<verb>-<object>`.
|
|
76
77
|
* **One purpose, no reader.** A topic has at most one purpose. A reader, also one in another tenant, is identified by
|
|
77
|
-
its subscription, whose name is its route id (`
|
|
78
|
+
its subscription, whose name is its route id (`DGR012E1_...`; `<RouteId>.subscription.name` overrides it), and never
|
|
78
79
|
adds a suffix to the topic. When the content belongs to one reader, the publisher may choose that reader's tenant
|
|
79
80
|
slug as the purpose (`PersonnelScheduleExportV1_degerfors`); that is the publisher's choice, not something a reader
|
|
80
81
|
in another tenant needs.
|