@ybotok/loam 0.2.0-alpha.5 → 0.2.0-alpha.6
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/CHANGELOG.md +901 -0
- package/MIGRATING-from-OpenSpec.md +7 -4
- package/QUICKSTART.md +8 -3
- package/README.md +13 -7
- package/ROADMAP.md +264 -11
- package/SCHEMA.md +439 -38
- package/WORKFLOW.md +23 -10
- package/dist/commands/adopt/render.js +47 -8
- package/dist/commands/adopt/render.js.map +1 -1
- package/dist/commands/archive/plan/landscape.js +45 -1
- package/dist/commands/archive/plan/landscape.js.map +1 -1
- package/dist/commands/archive/plan/model/extending.js +85 -0
- package/dist/commands/archive/plan/model/extending.js.map +1 -0
- package/dist/commands/archive/run.js +5 -2
- package/dist/commands/archive/run.js.map +1 -1
- package/dist/commands/context/print.js +11 -1
- package/dist/commands/context/print.js.map +1 -1
- package/dist/commands/doctor.js +46 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explore.js +12 -2
- package/dist/commands/explore.js.map +1 -1
- package/dist/commands/list/views.js +5 -1
- package/dist/commands/list/views.js.map +1 -1
- package/dist/commands/seed/plan.js +97 -3
- package/dist/commands/seed/plan.js.map +1 -1
- package/dist/commands/seed/seed.js +7 -2
- package/dist/commands/seed/seed.js.map +1 -1
- package/dist/commands/show/feature.js +2 -1
- package/dist/commands/show/feature.js.map +1 -1
- package/dist/commands/show/marks.js +3 -5
- package/dist/commands/show/marks.js.map +1 -1
- package/dist/commands/show/service.js +39 -18
- package/dist/commands/show/service.js.map +1 -1
- package/dist/commands/subsystem/sync.js +128 -74
- package/dist/commands/subsystem/sync.js.map +1 -1
- package/dist/commands/subsystem/txn/exclude.js +132 -0
- package/dist/commands/subsystem/txn/exclude.js.map +1 -0
- package/dist/commands/subsystem/txn/report.js +124 -0
- package/dist/commands/subsystem/txn/report.js.map +1 -0
- package/dist/commands/subsystem/txn/txn.js +10 -3
- package/dist/commands/subsystem/txn/txn.js.map +1 -1
- package/dist/commands/subsystem/txn/views.js +113 -16
- package/dist/commands/subsystem/txn/views.js.map +1 -1
- package/dist/commands/validate/arch-coverage.js +16 -9
- package/dist/commands/validate/arch-coverage.js.map +1 -1
- package/dist/commands/validate/checks/fleet-shape.js +30 -77
- package/dist/commands/validate/checks/fleet-shape.js.map +1 -1
- package/dist/commands/validate/checks/vocabulary.js +4 -19
- package/dist/commands/validate/checks/vocabulary.js.map +1 -1
- package/dist/commands/validate/feature.js +1 -1
- package/dist/commands/validate/feature.js.map +1 -1
- package/dist/commands/validate/fleet/census.js +11 -10
- package/dist/commands/validate/fleet/census.js.map +1 -1
- package/dist/commands/validate/fleet/landscape.js +127 -119
- package/dist/commands/validate/fleet/landscape.js.map +1 -1
- package/dist/commands/validate/fleet/load.js +66 -0
- package/dist/commands/validate/fleet/load.js.map +1 -1
- package/dist/commands/validate/fleet/map/attest.js +103 -0
- package/dist/commands/validate/fleet/map/attest.js.map +1 -0
- package/dist/commands/validate/fleet/map/bindings.js +96 -0
- package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
- package/dist/commands/validate/fleet/map/consumers.js +298 -0
- package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
- package/dist/commands/validate/fleet/map/isolation.js +116 -0
- package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
- package/dist/commands/validate/fleet/map/usecases.js +56 -0
- package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/steps.js +49 -17
- package/dist/commands/validate/fleet/usecases/steps.js.map +1 -1
- package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
- package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
- package/dist/commands/validate/fleet/views/ids.js +13 -9
- package/dist/commands/validate/fleet/views/ids.js.map +1 -1
- package/dist/commands/validate/fleet/views/projects.js +258 -70
- package/dist/commands/validate/fleet/views/projects.js.map +1 -1
- package/dist/commands/validate/fleet/views/root-documents.js +97 -0
- package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
- package/dist/commands/validate/fleet/views/stale.js +2 -2
- package/dist/commands/validate/fleet/views/stale.js.map +1 -1
- package/dist/commands/validate/service/model/diverged.js +226 -0
- package/dist/commands/validate/service/model/diverged.js.map +1 -0
- package/dist/commands/validate/service/model/grade.js +163 -0
- package/dist/commands/validate/service/model/grade.js.map +1 -0
- package/dist/commands/validate/service/service.js +110 -34
- package/dist/commands/validate/service/service.js.map +1 -1
- package/dist/commands/validate/service/specs.js +39 -5
- package/dist/commands/validate/service/specs.js.map +1 -1
- package/dist/commands/validate/service/spine.js +41 -3
- package/dist/commands/validate/service/spine.js.map +1 -1
- package/dist/commands/validate/service/usecases/tags.js +113 -0
- package/dist/commands/validate/service/usecases/tags.js.map +1 -0
- package/dist/commands/validate/service/usecases/usecases.js +209 -0
- package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
- package/dist/commands/validate/validate.js +10 -24
- package/dist/commands/validate/validate.js.map +1 -1
- package/dist/core/agent/agents-md/artifacts.js +1 -0
- package/dist/core/agent/agents-md/artifacts.js.map +1 -1
- package/dist/core/agent/agents-md/command-map.js +18 -4
- package/dist/core/agent/agents-md/command-map.js.map +1 -1
- package/dist/core/agent/agents-md/cycle.js +24 -9
- package/dist/core/agent/agents-md/cycle.js.map +1 -1
- package/dist/core/agent/agents-md/map/lenses/context.js +4 -3
- package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -1
- package/dist/core/agent/agents-md/map/subsystem.js +51 -11
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -1
- package/dist/core/agent/agents-md/map/usecases.js +45 -3
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -1
- package/dist/core/agent/agents-md.js +14 -4
- package/dist/core/agent/agents-md.js.map +1 -1
- package/dist/core/agent/support/report.js +39 -5
- package/dist/core/agent/support/report.js.map +1 -1
- package/dist/core/agent/workflows/adopt.js +123 -14
- package/dist/core/agent/workflows/adopt.js.map +1 -1
- package/dist/core/agent/workflows/check.js +35 -20
- package/dist/core/agent/workflows/check.js.map +1 -1
- package/dist/core/agent/workflows/closing.js +3 -1
- package/dist/core/agent/workflows/closing.js.map +1 -1
- package/dist/core/brief/brief.js +63 -11
- package/dist/core/brief/brief.js.map +1 -1
- package/dist/core/brief/checks.js +133 -7
- package/dist/core/brief/checks.js.map +1 -1
- package/dist/core/brief/landscape.js +212 -129
- package/dist/core/brief/landscape.js.map +1 -1
- package/dist/core/brief/map/extend.js +81 -0
- package/dist/core/brief/map/extend.js.map +1 -0
- package/dist/core/brief/map/owed.js +284 -0
- package/dist/core/brief/map/owed.js.map +1 -0
- package/dist/core/brief/targets.js +30 -29
- package/dist/core/brief/targets.js.map +1 -1
- package/dist/core/brief/unchecked.js +12 -2
- package/dist/core/brief/unchecked.js.map +1 -1
- package/dist/core/c4/likec4.js +23 -1
- package/dist/core/c4/likec4.js.map +1 -1
- package/dist/core/c4/parsed/deployment.js +5 -3
- package/dist/core/c4/parsed/deployment.js.map +1 -1
- package/dist/core/c4/parsed/view-ids.js +39 -1
- package/dist/core/c4/parsed/view-ids.js.map +1 -1
- package/dist/core/c4/prefetch/fleet.js +142 -0
- package/dist/core/c4/prefetch/fleet.js.map +1 -0
- package/dist/core/c4/project/architecture.js +52 -4
- package/dist/core/c4/project/architecture.js.map +1 -1
- package/dist/core/c4/project/batch.js +140 -0
- package/dist/core/c4/project/batch.js.map +1 -0
- package/dist/core/c4/project/documents.js +9 -4
- package/dist/core/c4/project/documents.js.map +1 -1
- package/dist/core/c4/project/load.js +77 -38
- package/dist/core/c4/project/load.js.map +1 -1
- package/dist/core/c4/project/staged.js +46 -12
- package/dist/core/c4/project/staged.js.map +1 -1
- package/dist/core/c4/resolve/attested.js +0 -0
- package/dist/core/c4/resolve/attested.js.map +1 -0
- package/dist/core/c4/resolve/service.js +8 -17
- package/dist/core/c4/resolve/service.js.map +1 -1
- package/dist/core/c4/resolve/steps.js +18 -0
- package/dist/core/c4/resolve/steps.js.map +1 -1
- package/dist/core/c4/root-project/exclude.js +352 -0
- package/dist/core/c4/root-project/exclude.js.map +1 -0
- package/dist/core/c4/service-model/documents.js +47 -0
- package/dist/core/c4/service-model/documents.js.map +1 -0
- package/dist/core/c4/service-model/fleet/extending.js +82 -0
- package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
- package/dist/core/c4/service-model/load.js +165 -0
- package/dist/core/c4/service-model/load.js.map +1 -0
- package/dist/core/c4/service-model/renderer.js +128 -0
- package/dist/core/c4/service-model/renderer.js.map +1 -0
- package/dist/core/c4/service-model/shape.js +126 -0
- package/dist/core/c4/service-model/shape.js.map +1 -0
- package/dist/core/c4/service-model/slice.js +188 -0
- package/dist/core/c4/service-model/slice.js.map +1 -0
- package/dist/core/c4/source-scan.js +26 -0
- package/dist/core/c4/source-scan.js.map +1 -1
- package/dist/core/c4/splice/authored-source.js +60 -13
- package/dist/core/c4/splice/authored-source.js.map +1 -1
- package/dist/core/c4/splice/contract.js.map +1 -1
- package/dist/core/c4/splice/identity/declared.js +87 -0
- package/dist/core/c4/splice/identity/declared.js.map +1 -0
- package/dist/core/c4/splice/identity/edges.js +17 -0
- package/dist/core/c4/splice/identity/edges.js.map +1 -1
- package/dist/core/c4/splice/identity/existing.js +80 -0
- package/dist/core/c4/splice/identity/existing.js.map +1 -0
- package/dist/core/c4/splice/identity/interior.js +80 -0
- package/dist/core/c4/splice/identity/interior.js.map +1 -0
- package/dist/core/c4/splice/identity/owner.js +50 -0
- package/dist/core/c4/splice/identity/owner.js.map +1 -0
- package/dist/core/c4/splice/landscape-merge.js +154 -100
- package/dist/core/c4/splice/landscape-merge.js.map +1 -1
- package/dist/core/c4/splice/model/merge.js +140 -0
- package/dist/core/c4/splice/model/merge.js.map +1 -0
- package/dist/core/c4/splice/placement.js +14 -4
- package/dist/core/c4/splice/placement.js.map +1 -1
- package/dist/core/c4/workspace.js +2 -1
- package/dist/core/c4/workspace.js.map +1 -1
- package/dist/core/coherence/coherence.js +7 -0
- package/dist/core/coherence/coherence.js.map +1 -1
- package/dist/core/delta/delta.js +9 -0
- package/dist/core/delta/delta.js.map +1 -1
- package/dist/core/deployment/delta.js +4 -0
- package/dist/core/deployment/delta.js.map +1 -1
- package/dist/core/diff/base-state.js +21 -5
- package/dist/core/diff/base-state.js.map +1 -1
- package/dist/core/diff/victims.js +10 -1
- package/dist/core/diff/victims.js.map +1 -1
- package/dist/core/docs.js +29 -24
- package/dist/core/docs.js.map +1 -1
- package/dist/core/doctor/config.js +7 -3
- package/dist/core/doctor/config.js.map +1 -1
- package/dist/core/doctor/doctor.js +36 -8
- package/dist/core/doctor/doctor.js.map +1 -1
- package/dist/core/doctor/report.js.map +1 -1
- package/dist/core/doctor/reports/scan.js +242 -0
- package/dist/core/doctor/reports/scan.js.map +1 -0
- package/dist/core/explain/refusals.js +1 -1
- package/dist/core/explain/refusals.js.map +1 -1
- package/dist/core/explore/explore.js +44 -9
- package/dist/core/explore/explore.js.map +1 -1
- package/dist/core/fleet-context.js +47 -0
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/partners.js +5 -9
- package/dist/core/gate/partners.js.map +1 -1
- package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
- package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
- package/dist/core/pack/living.js +47 -13
- package/dist/core/pack/living.js.map +1 -1
- package/dist/core/pack/pack.js +9 -6
- package/dist/core/pack/pack.js.map +1 -1
- package/dist/core/projection/arch-slice.js +2 -2
- package/dist/core/projection/arch-slice.js.map +1 -1
- package/dist/core/repo/paths.js +11 -9
- package/dist/core/repo/paths.js.map +1 -1
- package/dist/core/repo/tree/render/projects.js +93 -35
- package/dist/core/repo/tree/render/projects.js.map +1 -1
- package/dist/core/repo/tree/render/stale.js +2 -3
- package/dist/core/repo/tree/render/stale.js.map +1 -1
- package/dist/core/repo/tree/render/views.js +51 -3
- package/dist/core/repo/tree/render/views.js.map +1 -1
- package/dist/core/repo/tree/walk.js +45 -2
- package/dist/core/repo/tree/walk.js.map +1 -1
- package/dist/core/scaffold/landscape.js +219 -9
- package/dist/core/scaffold/landscape.js.map +1 -1
- package/dist/core/staging/writes.js.map +1 -1
- package/dist/core/usecases/delta/claims.js +1 -0
- package/dist/core/usecases/delta/claims.js.map +1 -1
- package/dist/core/usecases/delta/overlay.js +4 -0
- package/dist/core/usecases/delta/overlay.js.map +1 -1
- package/dist/core/usecases/fleet.js +18 -6
- package/dist/core/usecases/fleet.js.map +1 -1
- package/dist/core/usecases/operations.js +7 -0
- package/dist/core/usecases/operations.js.map +1 -1
- package/dist/core/usecases/service/exclude.js +119 -0
- package/dist/core/usecases/service/exclude.js.map +1 -0
- package/dist/core/usecases/service/flows.js +161 -0
- package/dist/core/usecases/service/flows.js.map +1 -0
- package/dist/core/vocabulary/maturity.js +10 -0
- package/dist/core/vocabulary/maturity.js.map +1 -1
- package/examples/README.md +24 -6
- package/examples/docs/architecture/landscape.likec4 +41 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +5 -2
- package/examples/docs/likec4.config.json +0 -1
- package/examples/docs/services/checkout-web/model.likec4 +39 -56
- package/examples/docs/services/order-service/arch.spec.md +13 -6
- package/examples/docs/services/order-service/model.likec4 +53 -67
- package/examples/docs/services/payment-service/arch.spec.md +7 -4
- package/examples/docs/services/payment-service/model.likec4 +32 -35
- package/examples/docs/services/platform/identity-service/arch.spec.md +7 -4
- package/examples/docs/services/platform/identity-service/model.likec4 +29 -33
- package/examples/docs/services/platform/notification-service/health.yaml +8 -3
- package/examples/docs/services/platform/notification-service/model.likec4 +39 -59
- package/package.json +1 -1
- package/examples/docs/services/checkout-web/likec4.config.json +0 -4
- package/examples/docs/services/order-service/likec4.config.json +0 -4
- package/examples/docs/services/payment-service/likec4.config.json +0 -4
- package/examples/docs/services/platform/identity-service/likec4.config.json +0 -4
- package/examples/docs/services/platform/notification-service/likec4.config.json +0 -4
|
@@ -1,30 +1,22 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
1
|
+
// identity-service's own C4 — what is INSIDE the element the fleet map binds to
|
|
2
|
+
// services/platform/identity-service/: the containers behind the token API and
|
|
3
|
+
// the two stores they reach.
|
|
3
4
|
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
// An EXTENDING model. There is no `specification` block here and there must not
|
|
6
|
+
// be one: the kinds come from architecture/landscape.likec4, which is read as
|
|
7
|
+
// part of the SAME LikeC4 project (the root `likec4.config.json` excludes
|
|
8
|
+
// `**/node_modules/**` and `features/**`, and nothing under `services/`). A
|
|
9
|
+
// second declaration of a kind the map already declares is a duplicate error
|
|
10
|
+
// blamed on both files. `extend` takes the fully-qualified id the map minted —
|
|
11
|
+
// `marketplace.identityService` — because the element is nested in the
|
|
12
|
+
// `marketplace` group; `extend identityService` resolves to nothing.
|
|
13
|
+
//
|
|
14
|
+
// Where the service sits in the SUBSYSTEM tree changes none of this: the model
|
|
15
|
+
// is found by walking `services/`, and `services/platform/` is a grouping
|
|
16
|
+
// directory, never part of any id. SCHEMA.md, "Two shapes of a service model",
|
|
17
|
+
// has the standalone shape and the recipe for migrating a model to this one.
|
|
15
18
|
model {
|
|
16
|
-
identityService
|
|
17
|
-
description 'Issues the access tokens the rest of the fleet presents, and answers whether one is still good'
|
|
18
|
-
// The binding — not the title — is what ties this element to
|
|
19
|
-
// services/identity-service/. With a title alone, renaming the box to
|
|
20
|
-
// 'Identity' would silently stop every join that reads this file (health
|
|
21
|
-
// dependencies, `Covers:` entries, the landscape spine) while `loam
|
|
22
|
-
// validate` stayed green, because a title that fails to match is only a
|
|
23
|
-
// guess at a binding and is graded as one.
|
|
24
|
-
metadata {
|
|
25
|
-
service 'identity-service'
|
|
26
|
-
}
|
|
27
|
-
|
|
19
|
+
extend marketplace.identityService {
|
|
28
20
|
api = container 'api' {
|
|
29
21
|
description 'HTTP surface: POST /tokens, POST /tokens/introspect, GET /tokens/{token}/valid'
|
|
30
22
|
technology 'Go'
|
|
@@ -51,7 +43,9 @@ model {
|
|
|
51
43
|
// architecture/landscape.likec4 as a peer is `landscape.datastore-private`:
|
|
52
44
|
// drawn at fleet level a store reads as a system in its own right, available
|
|
53
45
|
// for somebody else's service to depend on, which is the one coupling that is
|
|
54
|
-
// hardest to undo once a second team believes the picture.
|
|
46
|
+
// hardest to undo once a second team believes the picture. The extending
|
|
47
|
+
// shape makes that the default rather than a discipline — internals are
|
|
48
|
+
// written where they belong because there is nowhere else to write them.
|
|
55
49
|
introspectionCache = container 'introspection-cache' {
|
|
56
50
|
description 'Short-TTL introspection verdicts, keyed by token id'
|
|
57
51
|
technology 'Redis'
|
|
@@ -61,11 +55,12 @@ model {
|
|
|
61
55
|
// These three edges are the WHOLE runtime graph of this service:
|
|
62
56
|
// identity-service is the fleet's root of trust and calls nothing outside
|
|
63
57
|
// its own boundary, which is why health.yaml carries no `dependencies:`
|
|
64
|
-
// key
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
58
|
+
// key, and why this model draws no cross-boundary edge at all. They still
|
|
59
|
+
// have to be drawn — with four nested elements and no edge joining any of
|
|
60
|
+
// them this model is `c4.no-relationships`, on the grounds that parts which
|
|
61
|
+
// reach nothing are almost never the truth. (The check is evidence-gated:
|
|
62
|
+
// one lone container proves nothing and stays silent, which is why the
|
|
63
|
+
// warning is about a model this shape and not about any model.)
|
|
69
64
|
tokens -> keyStore 'Signs with the active key; rotation promotes the next; introspection reads keys and revocations back'
|
|
70
65
|
tokens -> introspectionCache 'Caches introspection verdicts, invalidates on revocation'
|
|
71
66
|
}
|
|
@@ -74,9 +69,10 @@ model {
|
|
|
74
69
|
// Views belong to LikeC4's renderer; no loam check reads anything below. One
|
|
75
70
|
// view is enough here because the whole model fits inside one boundary — the
|
|
76
71
|
// landscape splits its views only because a fleet-wide `include *` is the page
|
|
77
|
-
// nobody can read.
|
|
72
|
+
// nobody can read. View ids are flat across the whole project now that the map
|
|
73
|
+
// and every model share one, so this one is spelled to be unique.
|
|
78
74
|
views {
|
|
79
|
-
view identity_service of identityService {
|
|
75
|
+
view identity_service of marketplace.identityService {
|
|
80
76
|
title 'identity-service — containers'
|
|
81
77
|
include *
|
|
82
78
|
}
|
|
@@ -25,9 +25,14 @@ checks:
|
|
|
25
25
|
liveness: GET /internal/health/liveness
|
|
26
26
|
readiness: GET /internal/health/readiness # consumer group joined + both stores reachable
|
|
27
27
|
dependencies:
|
|
28
|
-
# Resolved against services/notification-service/model.likec4
|
|
29
|
-
#
|
|
30
|
-
#
|
|
28
|
+
# Resolved against services/platform/notification-service/model.likec4 — this
|
|
29
|
+
# service's own model, never the fleet map read on its own
|
|
30
|
+
# (`health.dependency-unmodelled` when nothing there answers to the name).
|
|
31
|
+
# That model EXTENDS the map, so what answers is its own slice: the elements
|
|
32
|
+
# it adds, plus the partners it points at and their ancestors. `kafka` below
|
|
33
|
+
# resolves through the second half — the edges name `kafka.orderEvents` and
|
|
34
|
+
# the broker that owns the topic comes with it.
|
|
35
|
+
# The delivery log and the contact store are absent on purpose: both
|
|
31
36
|
# are nested inside the service element and share its lifecycle, so they are
|
|
32
37
|
# blast radius rather than dependency — identity-service's health.yaml states
|
|
33
38
|
# the same rule for its two stores.
|
|
@@ -1,35 +1,21 @@
|
|
|
1
|
-
//
|
|
1
|
+
// notification-service's own C4 — what is INSIDE the element the fleet map binds
|
|
2
|
+
// to services/platform/notification-service/. Written by an agent from the
|
|
3
|
+
// `loam adopt` brief, then curated.
|
|
2
4
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// the
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
element topic {
|
|
16
|
-
style {
|
|
17
|
-
shape queue
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
5
|
+
// An EXTENDING model: no `specification` block, no partner copies. The topics
|
|
6
|
+
// this service consumes — `kafka.orderEvents`, `kafka.paymentEvents`,
|
|
7
|
+
// `kafka.crmEvents` — are the MAP's, declared there once with the `topic` kind
|
|
8
|
+
// that carries `#external` and `#platform`; this file points at them. So is
|
|
9
|
+
// `notificationProvider`, the third-party gateway: a system this service reaches
|
|
10
|
+
// belongs in architecture/landscape.likec4, and declaring a copy of it here
|
|
11
|
+
// would be `c4.element-unowned`. `extend` takes the fully-qualified id because
|
|
12
|
+
// the element is nested in the `marketplace` group.
|
|
13
|
+
//
|
|
14
|
+
// SCHEMA.md, "Two shapes of a service model", has the standalone shape — a model
|
|
15
|
+
// that declares its own `specification` and is therefore parsed alone — and the
|
|
16
|
+
// ordered recipe for migrating one to this shape.
|
|
22
17
|
model {
|
|
23
|
-
notificationService
|
|
24
|
-
description 'Turns fleet events into customer email and SMS'
|
|
25
|
-
// The binding, not the title, is what ties this element to
|
|
26
|
-
// services/notification-service/. With only a title, renaming the box in a
|
|
27
|
-
// diagram silently detaches every join that runs through it — health.yaml's
|
|
28
|
-
// dependencies, `Covers:` entries, the landscape's service checks.
|
|
29
|
-
metadata {
|
|
30
|
-
service 'notification-service'
|
|
31
|
-
}
|
|
32
|
-
|
|
18
|
+
extend marketplace.notificationService {
|
|
33
19
|
consumer = container 'consumer' {
|
|
34
20
|
description 'Kafka consumer group; one handler per message name'
|
|
35
21
|
technology 'Go'
|
|
@@ -67,30 +53,12 @@ model {
|
|
|
67
53
|
sender -> deliveryLog 'Records delivered / failed'
|
|
68
54
|
}
|
|
69
55
|
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
// — a service that reaches nothing is almost never true.
|
|
77
|
-
kafka = softwareSystem 'kafka' {
|
|
78
|
-
description 'Event backbone (platform)'
|
|
79
|
-
orderEvents = topic 'order.events'
|
|
80
|
-
paymentEvents = topic 'payment.events'
|
|
81
|
-
crmEvents = topic 'crm.events'
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// The second thing this service reaches across its own boundary, and the one
|
|
85
|
-
// the runbook spends an incident section on: while the provider is down or
|
|
86
|
-
// throttling, nothing is delivered and there is no fallback path. It belongs
|
|
87
|
-
// here for the same reason payment-service's model draws `stripe` — a model
|
|
88
|
-
// that stopped at the broker would show a worker whose only failure mode is
|
|
89
|
-
// lag, which is the half of the picture the on-call graphs already give you.
|
|
90
|
-
provider = softwareSystem 'notification-provider' {
|
|
91
|
-
description 'Third-party email and SMS gateway — quota-limited, and outside this fleet'
|
|
92
|
-
}
|
|
93
|
-
|
|
56
|
+
// The three channels this service takes messages off, pointing at the map's
|
|
57
|
+
// topics. health.yaml names `kafka` as a critical dependency and that id has to
|
|
58
|
+
// resolve through this model (`health.dependency-unmodelled` otherwise): it
|
|
59
|
+
// does, because a partner brings its ANCESTORS with it — the edges name the
|
|
60
|
+
// topics and the broker answers for them.
|
|
61
|
+
//
|
|
94
62
|
// No `metadata { consumes }` on these edges, and adding it would change
|
|
95
63
|
// nothing: loam reads the event spine off `architecture/landscape.likec4`
|
|
96
64
|
// alone, never off a service model. What resolves a consumed name against
|
|
@@ -104,15 +72,27 @@ model {
|
|
|
104
72
|
// Drawn topic → consumer, the direction the landscape uses and the one the
|
|
105
73
|
// event spine requires there: `consumes` binds the edge's TARGET, so the same
|
|
106
74
|
// edge drawn the other way round binds to nothing at all.
|
|
107
|
-
kafka.orderEvents -> notificationService.consumer 'OrderPlaced triggers the confirmation'
|
|
108
|
-
kafka.paymentEvents -> notificationService.consumer 'PaymentCaptured triggers the receipt'
|
|
109
|
-
kafka.crmEvents -> notificationService.consumer 'CustomerUpdated refreshes contact details'
|
|
75
|
+
kafka.orderEvents -> marketplace.notificationService.consumer 'OrderPlaced triggers the confirmation'
|
|
76
|
+
kafka.paymentEvents -> marketplace.notificationService.consumer 'PaymentCaptured triggers the receipt'
|
|
77
|
+
kafka.crmEvents -> marketplace.notificationService.consumer 'CustomerUpdated refreshes contact details'
|
|
110
78
|
|
|
111
|
-
|
|
79
|
+
// The second thing this service reaches across its own boundary, and the one
|
|
80
|
+
// the runbook spends an incident section on: while the provider is down or
|
|
81
|
+
// throttling, nothing is delivered and there is no fallback path. Its element
|
|
82
|
+
// is the map's, and the map also carries the SERVICE-level twin of this edge
|
|
83
|
+
// (`marketplace.notificationService -> notificationProvider`), because every
|
|
84
|
+
// fleet check reads the map alone. The cross-boundary call is written twice on
|
|
85
|
+
// purpose — container-level here, service-level there — and that remainder is
|
|
86
|
+
// recorded in ROADMAP.md rather than hidden.
|
|
87
|
+
marketplace.notificationService.sender -> notificationProvider 'Sends email and SMS, and backs off on 429'
|
|
112
88
|
}
|
|
113
89
|
|
|
90
|
+
// Views belong to LikeC4's renderer; no loam check reads anything below. This
|
|
91
|
+
// file is part of the root project, so `npx likec4 start` at the docs root draws
|
|
92
|
+
// this view beside the fleet map — there is no per-service likec4.config.json,
|
|
93
|
+
// and loam never writes one beside an extending model.
|
|
114
94
|
views {
|
|
115
|
-
view notification_service of notificationService {
|
|
95
|
+
view notification_service of marketplace.notificationService {
|
|
116
96
|
include *
|
|
117
97
|
}
|
|
118
98
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ybotok/loam",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.6",
|
|
4
4
|
"description": "Architecture-first semantic integrity and change governance for evolving software systems: connect C4, requirements, contracts, and verification evidence.",
|
|
5
5
|
"author": "spentsov",
|
|
6
6
|
"repository": {
|