@rse/specbook 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dst/specbook-export-diagram.js +10 -8
- package/dst/specbook-format.md +4 -2
- package/dst/specbook-format.yaml +365 -57
- package/package.json +6 -6
|
@@ -81,16 +81,18 @@ const mermaidColors = (colors, style) => {
|
|
|
81
81
|
theme color spreads after the shape of the D2 themes "Neutral
|
|
82
82
|
Default" (light) and "Dark Mauve" (dark): the neutrals "N1" (text)
|
|
83
83
|
to "N7" (background), the base colors "B1" (strokes) to "B6"
|
|
84
|
-
(fills), and the alternative accents "AA*"/"AB*"
|
|
84
|
+
(fills), and the alternative accents "AA*"/"AB*", where the fills
|
|
85
|
+
"B4" to "B6" of the nesting levels 1 to 3 are spread far apart and,
|
|
86
|
+
unlike in D2, recede towards the outer levels (the containers) */
|
|
85
87
|
const d2Colors = (colors, style) => {
|
|
86
88
|
const [b, a, s] = [colors.base, colors.accent, colors.signal];
|
|
87
89
|
return style === "dark" ? {
|
|
88
90
|
N1: b[28], N2: b[25], N3: b[22], N4: b[13], N5: b[10], N6: b[8], N7: b[6],
|
|
89
|
-
B1: a[21], B2: a[21], B3: a[13], B4:
|
|
91
|
+
B1: a[21], B2: a[21], B3: a[13], B4: b[9], B5: a[0], B6: a[5],
|
|
90
92
|
AA2: s[19], AA4: s[10], AA5: s[8], AB4: s[10], AB5: s[8]
|
|
91
93
|
} : {
|
|
92
94
|
N1: b[3], N2: b[13], N3: b[19], N4: b[25], N5: b[27], N6: b[29], N7: b[31],
|
|
93
|
-
B1: a[7], B2: a[11], B3: a[27], B4: a[
|
|
95
|
+
B1: a[7], B2: a[11], B3: a[27], B4: a[31], B5: a[28], B6: a[24],
|
|
94
96
|
AA2: s[13], AA4: s[28], AA5: s[30], AB4: s[28], AB5: s[30]
|
|
95
97
|
};
|
|
96
98
|
};
|
|
@@ -122,13 +124,13 @@ const d2Error = (err) => {
|
|
|
122
124
|
return message;
|
|
123
125
|
}
|
|
124
126
|
};
|
|
125
|
-
/* render a D2 diagram, with the
|
|
126
|
-
|
|
127
|
-
diagram itself still
|
|
127
|
+
/* render a D2 diagram, with the TALA layout engine and the theme colors
|
|
128
|
+
prepended as one line of configuration (on the theme of the style),
|
|
129
|
+
so the configuration of the diagram itself still wins */
|
|
128
130
|
const renderD2 = (source, colors, style) => {
|
|
129
131
|
const overrides = Object.entries(colors).map(([key, color]) => `${key}: "${color}"`).join("; ");
|
|
130
132
|
const request = d2Chain.then(async () => {
|
|
131
|
-
d2 ??= import("@
|
|
133
|
+
d2 ??= import("@d2lang/d2").then((module) => new module.D2())
|
|
132
134
|
.catch((err) => {
|
|
133
135
|
d2 = null;
|
|
134
136
|
throw err;
|
|
@@ -138,7 +140,7 @@ const renderD2 = (source, colors, style) => {
|
|
|
138
140
|
worker()?.ref();
|
|
139
141
|
try {
|
|
140
142
|
const result = await compiler.compile({
|
|
141
|
-
fs: { index: `vars: { d2-config: { theme-overrides: { ${overrides} } } }\n${source}` },
|
|
143
|
+
fs: { index: `vars: { d2-config: { layout-engine: tala; theme-overrides: { ${overrides} } } }\n${source}` },
|
|
142
144
|
options: { themeID: style === "dark" ? 200 : 0, scale: 1, pad: 0, noXMLTag: true }
|
|
143
145
|
});
|
|
144
146
|
return await compiler.render(result.diagram, result.renderOptions);
|
package/dst/specbook-format.md
CHANGED
|
@@ -1148,8 +1148,10 @@ its own and embedded like an image -- ``,
|
|
|
1148
1148
|
``, or `` -- inside a
|
|
1149
1149
|
description or property value, where its source is inlined at parse time.
|
|
1150
1150
|
The HTML/PDF export renders every such diagram (Mermaid through
|
|
1151
|
-
`beautiful-mermaid`, D2 through `@
|
|
1152
|
-
|
|
1151
|
+
`beautiful-mermaid`, D2 through `@d2lang/d2`, laid out by its TALA
|
|
1152
|
+
engine unless the diagram configures another `layout-engine`) in the
|
|
1153
|
+
theme colors of the document, once per color theme, like a theme-aware
|
|
1154
|
+
image. It folds,
|
|
1153
1155
|
maximizes, and is omitted (`-O diagram:code`, for diagrams as code, or
|
|
1154
1156
|
by nesting level) like a derived Gradia diagram. A diagram failing to render
|
|
1155
1157
|
is omitted with a notice. The normalized Markdown and the AST exports
|
package/dst/specbook-format.yaml
CHANGED
|
@@ -642,7 +642,10 @@
|
|
|
642
642
|
desc: >
|
|
643
643
|
The concrete behaviors and capabilities the solution must provide, describing *what* the
|
|
644
644
|
system does in terms of functions, features, and operations, while the quality bounds and
|
|
645
|
-
constraints on them belong to the Non-Functional Requirements.
|
|
645
|
+
constraints on them belong to the Non-Functional Requirements. The requirements are
|
|
646
|
+
optionally grouped into the coherent capabilities they add up to (the epics of agile
|
|
647
|
+
planning, the features of product management), which the overview diagram draws as boxes
|
|
648
|
+
around their requirements.
|
|
646
649
|
optional: true
|
|
647
650
|
refs: >
|
|
648
651
|
- Mavin et al.: Easy Approach to Requirements Syntax (EARS) (2009),
|
|
@@ -654,12 +657,31 @@
|
|
|
654
657
|
diagram:
|
|
655
658
|
type: grid
|
|
656
659
|
nodes: "[[FR.REQUIREMENT:*]]"
|
|
660
|
+
nest:
|
|
661
|
+
properties:
|
|
662
|
+
- GROUP
|
|
657
663
|
properties:
|
|
658
664
|
- PRIORITY
|
|
659
665
|
config:
|
|
660
666
|
size-node-width-max: 440
|
|
661
|
-
grid-columns-max:
|
|
667
|
+
grid-columns-max: 2
|
|
662
668
|
children:
|
|
669
|
+
- kind: GROUP
|
|
670
|
+
desc: >
|
|
671
|
+
A named group of strongly related requirements, carrying a short (1-3 word),
|
|
672
|
+
per-artifact unique name distinct from the names of its requirements (e.g.
|
|
673
|
+
`Moderation` for the moderating, forwarding, and answering of attendee inputs,
|
|
674
|
+
`Event Access` for the access URLs), and described by a 1-sentence description
|
|
675
|
+
("what") of the capability the requirements add up to plus a 1-sentence rationale
|
|
676
|
+
("why") of the cohesion. A group is an epic in the agile sense and a feature in the
|
|
677
|
+
product sense, but carries no obligation of its own: it has no priority, states no
|
|
678
|
+
behavior, and is verified through its requirements alone, so it affects the
|
|
679
|
+
overview diagram only, where its requirements are drawn next to each other inside
|
|
680
|
+
a box. The groups are listed before the requirements, and every requirement
|
|
681
|
+
belongs to at most one group.
|
|
682
|
+
optional: true
|
|
683
|
+
referenced:
|
|
684
|
+
- "[[FR.REQUIREMENT:*]]"
|
|
663
685
|
- kind: REQUIREMENT
|
|
664
686
|
desc: >
|
|
665
687
|
A single functional requirement, named with a short (3-8 word) summary and described
|
|
@@ -674,14 +696,15 @@
|
|
|
674
696
|
unwanted-behavior (`If <condition>, then the system MUST ...`).
|
|
675
697
|
optional: true
|
|
676
698
|
format:
|
|
677
|
-
|
|
699
|
+
type: compact
|
|
678
700
|
referenced:
|
|
679
701
|
- "[[USE-CASE:*]]"
|
|
680
702
|
diagram:
|
|
681
703
|
type: hub
|
|
682
704
|
center: self
|
|
683
|
-
nodes: "[[FR.
|
|
684
|
-
[[USE-CASE:*]], [[DM.ENTITY:*]], [[FV.COMPONENT:*]],
|
|
705
|
+
nodes: "[[FR.GROUP:*]], [[FR.REQUIREMENT:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]],
|
|
706
|
+
[[RULE:*]], [[USE-CASE:*]], [[DM.ENTITY:*]], [[FV.COMPONENT:*]],
|
|
707
|
+
[[TEST-CASE:*]]"
|
|
685
708
|
labeled: true
|
|
686
709
|
qualified: true
|
|
687
710
|
config:
|
|
@@ -697,6 +720,23 @@
|
|
|
697
720
|
time"), preserving the conscious decision rather than silently dropping it,
|
|
698
721
|
with the statement still phrased as it would be if in scope.
|
|
699
722
|
value: enum(MUST,SHOULD,COULD,WONT)
|
|
723
|
+
- name: GROUP
|
|
724
|
+
desc: >
|
|
725
|
+
Reference to the FUNCTIONAL-REQUIREMENTS group the requirement belongs to,
|
|
726
|
+
placing it next to the other requirements of the group in the overview
|
|
727
|
+
diagram; omitted for a requirement standing on its own.
|
|
728
|
+
value: "[[FR.GROUP:*]]"
|
|
729
|
+
optional: true
|
|
730
|
+
- name: DEPENDS-ON
|
|
731
|
+
desc: >
|
|
732
|
+
Comma-separated references to the FUNCTIONAL-REQUIREMENTS objects the
|
|
733
|
+
requirement presupposes, i.e. whose behavior has to exist before its own
|
|
734
|
+
makes sense (e.g. replying to chat messages presupposes chat messages),
|
|
735
|
+
so that dropping or deferring a requirement reveals what falls with it;
|
|
736
|
+
omitted for a requirement presupposing no other one.
|
|
737
|
+
value: list([[FR.REQUIREMENT:*]])
|
|
738
|
+
optional: true
|
|
739
|
+
acyclic: true
|
|
700
740
|
- name: PREMISES
|
|
701
741
|
desc: >
|
|
702
742
|
Comma-separated references to the SOLUTION-PREMISES objects the
|
|
@@ -748,6 +788,8 @@
|
|
|
748
788
|
exception the lint warning cannot tell apart) and its hub diagram shows what
|
|
749
789
|
answers it.
|
|
750
790
|
optional: true
|
|
791
|
+
format:
|
|
792
|
+
type: compact
|
|
751
793
|
referenced:
|
|
752
794
|
- "[[TACTIC:*]]"
|
|
753
795
|
- "[[DECISION:*]]"
|
|
@@ -1145,7 +1187,7 @@
|
|
|
1145
1187
|
center: self
|
|
1146
1188
|
nodes: "[[USE-CASE:*]], [[ROLE:*]], [[PERSONA:*]], [[STEP:*]], [[ACTIVITY:*]],
|
|
1147
1189
|
[[FR.REQUIREMENT:*]], [[RULE:*]], [[DM.ENTITY:*]], [[TRANSITION:*]],
|
|
1148
|
-
[[PERMISSION:*]], [[PRINCIPLE:*]], [[STORYBOARD:*]], [[CV.ENTITY:*]],
|
|
1190
|
+
[[PERMISSION:*]], [[IC.PRINCIPLE:*]], [[STORYBOARD:*]], [[CV.ENTITY:*]],
|
|
1149
1191
|
[[TEST-CASE:*]]"
|
|
1150
1192
|
labeled: true
|
|
1151
1193
|
qualified: true
|
|
@@ -2230,7 +2272,7 @@
|
|
|
2230
2272
|
optional: true
|
|
2231
2273
|
diagram:
|
|
2232
2274
|
type: grid
|
|
2233
|
-
nodes: "[[PRINCIPLE:*]]"
|
|
2275
|
+
nodes: "[[IC.PRINCIPLE:*]]"
|
|
2234
2276
|
properties:
|
|
2235
2277
|
- CATEGORY
|
|
2236
2278
|
config:
|
|
@@ -2246,8 +2288,10 @@
|
|
|
2246
2288
|
solution, plus a 1-sentence rationale ("why"). A principle is solution-wide and
|
|
2247
2289
|
independent of any particular screen or flow (a structure recurring within one flow
|
|
2248
2290
|
is a Dialog Pattern instead), decides between design alternatives (the alternative
|
|
2249
|
-
it rejects is its `TRADE-OFF`),
|
|
2250
|
-
quality bound is a Non-Functional Requirement instead)
|
|
2291
|
+
it rejects is its `TRADE-OFF`), is not verifiable by a metric (a measurable
|
|
2292
|
+
quality bound is a Non-Functional Requirement instead), and governs the user's
|
|
2293
|
+
experience (a principle governing the architecture is an Architecture Tenets
|
|
2294
|
+
principle instead).
|
|
2251
2295
|
optional: true
|
|
2252
2296
|
referenced:
|
|
2253
2297
|
- "[[DIALOG-PATTERN:*]]"
|
|
@@ -2256,7 +2300,7 @@
|
|
|
2256
2300
|
diagram:
|
|
2257
2301
|
type: hub
|
|
2258
2302
|
center: self
|
|
2259
|
-
nodes: "[[PRINCIPLE:*]], [[PERSONA:*]], [[STEP:*]], [[USE-CASE:*]], [[CONVENTION:*]],
|
|
2303
|
+
nodes: "[[IC.PRINCIPLE:*]], [[PERSONA:*]], [[STEP:*]], [[USE-CASE:*]], [[CONVENTION:*]],
|
|
2260
2304
|
[[DIALOG-PATTERN:*]], [[ELEMENT:*]], [[DECISION:*]]"
|
|
2261
2305
|
labeled: true
|
|
2262
2306
|
qualified: true
|
|
@@ -2354,7 +2398,7 @@
|
|
|
2354
2398
|
diagram:
|
|
2355
2399
|
type: hub
|
|
2356
2400
|
center: self
|
|
2357
|
-
nodes: "[[CONVENTION:*]], [[PERSONA:*]], [[PRINCIPLE:*]], [[TERM:*]], [[DECISION:*]]"
|
|
2401
|
+
nodes: "[[CONVENTION:*]], [[PERSONA:*]], [[IC.PRINCIPLE:*]], [[TERM:*]], [[DECISION:*]]"
|
|
2358
2402
|
labeled: true
|
|
2359
2403
|
qualified: true
|
|
2360
2404
|
config:
|
|
@@ -2383,7 +2427,7 @@
|
|
|
2383
2427
|
Comma-separated references to the INTERACTION-CONCEPT objects the convention
|
|
2384
2428
|
supports in wording, so that a convention is grounded in the interaction
|
|
2385
2429
|
philosophy rather than in taste alone.
|
|
2386
|
-
value: list([[PRINCIPLE:*]])
|
|
2430
|
+
value: list([[IC.PRINCIPLE:*]])
|
|
2387
2431
|
optional: true
|
|
2388
2432
|
- name: TERMS
|
|
2389
2433
|
desc: >
|
|
@@ -2438,7 +2482,7 @@
|
|
|
2438
2482
|
diagram:
|
|
2439
2483
|
type: hub
|
|
2440
2484
|
center: self
|
|
2441
|
-
nodes: "[[DIALOG-PATTERN:*]], [[PRINCIPLE:*]], [[STORYBOARD:*]], [[DECISION:*]]"
|
|
2485
|
+
nodes: "[[DIALOG-PATTERN:*]], [[IC.PRINCIPLE:*]], [[STORYBOARD:*]], [[DECISION:*]]"
|
|
2442
2486
|
deep: true
|
|
2443
2487
|
labeled: true
|
|
2444
2488
|
qualified: true
|
|
@@ -2475,7 +2519,7 @@
|
|
|
2475
2519
|
Comma-separated references to the INTERACTION-CONCEPT objects the pattern
|
|
2476
2520
|
embodies, so that every principle is shown to be honored by at least one
|
|
2477
2521
|
pattern rather than merely declared.
|
|
2478
|
-
value: list([[PRINCIPLE:*]])
|
|
2522
|
+
value: list([[IC.PRINCIPLE:*]])
|
|
2479
2523
|
optional: true
|
|
2480
2524
|
- name: USES
|
|
2481
2525
|
desc: >
|
|
@@ -2644,7 +2688,7 @@
|
|
|
2644
2688
|
diagram:
|
|
2645
2689
|
type: hub
|
|
2646
2690
|
center: self
|
|
2647
|
-
nodes: "[[ELEMENT:*]], [[PERSONA:*]], [[PRINCIPLE:*]], [[MOCKUP:*]]"
|
|
2691
|
+
nodes: "[[ELEMENT:*]], [[PERSONA:*]], [[IC.PRINCIPLE:*]], [[MOCKUP:*]]"
|
|
2648
2692
|
labeled: true
|
|
2649
2693
|
qualified: true
|
|
2650
2694
|
config:
|
|
@@ -2674,7 +2718,7 @@
|
|
|
2674
2718
|
Comma-separated references to the INTERACTION-CONCEPT objects the element
|
|
2675
2719
|
supports in appearance, so that an element is grounded in the interaction
|
|
2676
2720
|
philosophy rather than in taste alone.
|
|
2677
|
-
value: list([[PRINCIPLE:*]])
|
|
2721
|
+
value: list([[IC.PRINCIPLE:*]])
|
|
2678
2722
|
optional: true
|
|
2679
2723
|
- name: SOURCE
|
|
2680
2724
|
desc: >
|
|
@@ -2734,10 +2778,218 @@
|
|
|
2734
2778
|
the design tool or a screenshot of an already existing user interface, so
|
|
2735
2779
|
that the look is seen rather than only read.
|
|
2736
2780
|
|
|
2781
|
+
- kind: ARCH
|
|
2782
|
+
name: Architecture Tenets
|
|
2783
|
+
id: AT
|
|
2784
|
+
file: 22-ARCH-AT-Architecture-Tenets.md
|
|
2785
|
+
desc: >
|
|
2786
|
+
The architecture philosophy of the solution, stated as the few overarching maxims and the
|
|
2787
|
+
standing principles derived from them, which every pattern, view, tactic, decision, and
|
|
2788
|
+
aspect of the architecture has to obey, while the reusable structures belong to the
|
|
2789
|
+
Architecture Patterns and the concrete ones to the views following them. The maxims are listed in decreasing precedence, so that whenever two maxims conflict
|
|
2790
|
+
in a particular design decision, the earlier one wins, and a principle conflict is settled
|
|
2791
|
+
by the precedence of the maxims the principles derive from.
|
|
2792
|
+
|
|
2793
|
+
The tenets are prescriptive and reusable, not verifiable and not decided once: a quality
|
|
2794
|
+
bound verifiable by a metric is a Non-Functional Requirement, the mechanism achieving a
|
|
2795
|
+
quality is a Quality Perspectives tactic, the rule about the source structure and process
|
|
2796
|
+
is a Development Aspects aspect, the one-off trade-off between genuine alternatives is a
|
|
2797
|
+
Design Decisions decision (which applies the tenets through `GUIDED-BY`), and the
|
|
2798
|
+
principle governing the user's experience is an Interaction Concept principle.
|
|
2799
|
+
optional: true
|
|
2800
|
+
refs: >
|
|
2801
|
+
- The Open Group: TOGAF Standard, 10th ed.: Architecture Principles (2022),
|
|
2802
|
+
https://pubs.opengroup.org/togaf-standard/adm-techniques/chap02.html
|
|
2803
|
+
- Greefhorst/Proper: Architecture Principles: The Cornerstones of Enterprise Architecture (2011),
|
|
2804
|
+
https://link.springer.com/book/10.1007/978-3-642-20279-7
|
|
2805
|
+
- Starke/Hruschka: arc42 Template: Solution Strategy (2005),
|
|
2806
|
+
https://arc42.org/overview
|
|
2807
|
+
diagram:
|
|
2808
|
+
type: grid
|
|
2809
|
+
nodes: "[[MAXIM:*]], [[AT.PRINCIPLE:*]]"
|
|
2810
|
+
config:
|
|
2811
|
+
size-node-width-max: 440
|
|
2812
|
+
grid-columns-max: 4
|
|
2813
|
+
children:
|
|
2814
|
+
- kind: MAXIM
|
|
2815
|
+
desc: >
|
|
2816
|
+
A single architecture maxim, named with a short (2-5 word) preference or imperative
|
|
2817
|
+
(e.g. `Simplicity over Flexibility`, `Buy before Build`, `Own the Data`) and
|
|
2818
|
+
described in a concise (1-3 sentence) paragraph by how it guides the architecture
|
|
2819
|
+
of the solution as a whole, plus a 1-sentence rationale ("why"). A solution has only
|
|
2820
|
+
a few (3-7) maxims: a maxim is solution-wide and independent of any particular view
|
|
2821
|
+
or element (a rule bound to a structure is a principle instead), decides between
|
|
2822
|
+
design alternatives (the subordinated side usually named by its `X over Y` form),
|
|
2823
|
+
and is not verifiable by a metric (a measurable quality bound is a Non-Functional
|
|
2824
|
+
Requirement instead).
|
|
2825
|
+
optional: true
|
|
2826
|
+
format:
|
|
2827
|
+
type: compact
|
|
2828
|
+
diagram:
|
|
2829
|
+
type: hub
|
|
2830
|
+
center: self
|
|
2831
|
+
nodes: "[[MAXIM:*]], [[AT.PRINCIPLE:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]],
|
|
2832
|
+
[[TACTIC:*]], [[DECISION:*]], [[ASPECT:*]]"
|
|
2833
|
+
labeled: true
|
|
2834
|
+
qualified: true
|
|
2835
|
+
config:
|
|
2836
|
+
size-node-width-max: 440
|
|
2837
|
+
props:
|
|
2838
|
+
- name: DRIVEN-BY
|
|
2839
|
+
desc: >
|
|
2840
|
+
Comma-separated references to the NON-FUNCTIONAL-REQUIREMENTS or
|
|
2841
|
+
SOLUTION-PREMISES objects the maxim answers (e.g. the maintainability
|
|
2842
|
+
requirement, the small-team premise), so that a maxim is grounded in the
|
|
2843
|
+
forces on the solution rather than in taste alone; omitted for a maxim
|
|
2844
|
+
rooted in the Solution Vision alone.
|
|
2845
|
+
value: list([[NR.*]], [[PREMISE:*]])
|
|
2846
|
+
optional: true
|
|
2847
|
+
- kind: PRINCIPLE
|
|
2848
|
+
desc: >
|
|
2849
|
+
A single architecture principle, named with a short (2-5 word) summary (e.g.
|
|
2850
|
+
`Stateless Services`, `One Owner per Entity`, `Async between Contexts`) and
|
|
2851
|
+
described in a concise (1-3 sentence) paragraph as the standing rule the
|
|
2852
|
+
architecture follows whenever its concern arises, stated with `MUST`/`MUST NOT`
|
|
2853
|
+
or `SHOULD`/`SHOULD NOT`, plus a 1-sentence rationale ("why"). A principle is
|
|
2854
|
+
bound to a particular structure of the architecture (a rule independent of any
|
|
2855
|
+
structure is a maxim instead), reusable across many decisions (a trade-off made
|
|
2856
|
+
once between genuine alternatives is a Design Decisions decision instead), names
|
|
2857
|
+
no mechanism and no product (the mechanism is a Quality
|
|
2858
|
+
Perspectives tactic, the product a Technology Stack component), and governs the
|
|
2859
|
+
architecture, not the source process (a Development Aspects aspect), the code (a
|
|
2860
|
+
Code Patterns pattern), or the user's experience (an Interaction Concept
|
|
2861
|
+
principle).
|
|
2862
|
+
optional: true
|
|
2863
|
+
format:
|
|
2864
|
+
type: compact
|
|
2865
|
+
diagram:
|
|
2866
|
+
type: hub
|
|
2867
|
+
center: self
|
|
2868
|
+
nodes: "[[MAXIM:*]], [[AT.PRINCIPLE:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]],
|
|
2869
|
+
[[TACTIC:*]], [[DECISION:*]], [[ASPECT:*]]"
|
|
2870
|
+
labeled: true
|
|
2871
|
+
qualified: true
|
|
2872
|
+
config:
|
|
2873
|
+
size-node-width-max: 440
|
|
2874
|
+
props:
|
|
2875
|
+
- name: MAXIMS
|
|
2876
|
+
desc: >
|
|
2877
|
+
Comma-separated references to the MAXIM objects the principle
|
|
2878
|
+
concretizes (e.g. a `Stateless Services` principle concretizing a
|
|
2879
|
+
`Scale Out over Scale Up` maxim), so that the principles form a hierarchy
|
|
2880
|
+
below the maxims rather than a flat catalogue; omitted for a principle
|
|
2881
|
+
standing on its own forces alone.
|
|
2882
|
+
value: list([[MAXIM:*]])
|
|
2883
|
+
optional: true
|
|
2884
|
+
- name: DRIVEN-BY
|
|
2885
|
+
desc: >
|
|
2886
|
+
Comma-separated references to the NON-FUNCTIONAL-REQUIREMENTS or
|
|
2887
|
+
SOLUTION-PREMISES objects the principle answers beyond the maxims it
|
|
2888
|
+
concretizes (e.g. the availability requirement, the hosting constraint);
|
|
2889
|
+
omitted for a principle grounded in its maxims alone.
|
|
2890
|
+
value: list([[NR.*]], [[PREMISE:*]])
|
|
2891
|
+
optional: true
|
|
2892
|
+
- name: IMPLICATIONS
|
|
2893
|
+
desc: >
|
|
2894
|
+
What following the principle obliges the architecture to, stated as a 1-2
|
|
2895
|
+
sentence description of the consequences for the elements it governs
|
|
2896
|
+
(e.g. `session state lives in the shared store, so every component
|
|
2897
|
+
instance is replaceable at any time`), as opposed to the rationale which
|
|
2898
|
+
states why the principle is worth these consequences; omitted when nothing
|
|
2899
|
+
non-obvious follows from the principle.
|
|
2900
|
+
optional: true
|
|
2901
|
+
|
|
2902
|
+
- kind: ARCH
|
|
2903
|
+
name: Architecture Patterns
|
|
2904
|
+
id: AP
|
|
2905
|
+
file: 23-ARCH-AP-Architecture-Patterns.md
|
|
2906
|
+
desc: >
|
|
2907
|
+
The reusable structural solutions the architecture of the solution follows, each a named
|
|
2908
|
+
pattern of the literature or of the organization (e.g. hexagonal architecture,
|
|
2909
|
+
transactional outbox, backend for frontend) applied to the solution as a whole, which the
|
|
2910
|
+
views following them realize, the tactics build upon, the decisions choose, and the code
|
|
2911
|
+
patterns code. The artifact completes the guidance of the architecture: the Architecture
|
|
2912
|
+
Tenets state what the architecture values and obeys, the patterns state the structures it
|
|
2913
|
+
takes to do so.
|
|
2914
|
+
|
|
2915
|
+
A pattern names a structure, nothing else: the mechanism achieving one quality attribute
|
|
2916
|
+
is a Quality Perspectives tactic (which may be built from patterns), the one-off trade-off
|
|
2917
|
+
choosing a pattern over its alternatives is a Design Decisions decision, the coded form of
|
|
2918
|
+
a pattern is a Code Patterns pattern shown as a listing, and a structure of the user
|
|
2919
|
+
interface is a Dialog Patterns pattern.
|
|
2920
|
+
optional: true
|
|
2921
|
+
refs: >
|
|
2922
|
+
- Buschmann et al.: Pattern-Oriented Software Architecture, Vol. 1: A System of Patterns (1996),
|
|
2923
|
+
https://www.wiley.com/en-us/Pattern+Oriented+Software+Architecture%2C+Volume+1%2C+A+System+of+Patterns-p-9780471958697
|
|
2924
|
+
- Fowler: Patterns of Enterprise Application Architecture (2002),
|
|
2925
|
+
https://martinfowler.com/books/eaa.html
|
|
2926
|
+
- Hohpe/Woolf: Enterprise Integration Patterns (2003),
|
|
2927
|
+
https://www.enterpriseintegrationpatterns.com/
|
|
2928
|
+
- Richardson: Microservices Patterns (2018),
|
|
2929
|
+
https://microservices.io/patterns/
|
|
2930
|
+
diagram:
|
|
2931
|
+
type: grid
|
|
2932
|
+
nodes: "[[PATTERN:*]]"
|
|
2933
|
+
config:
|
|
2934
|
+
size-node-width-max: 440
|
|
2935
|
+
grid-columns-max: 4
|
|
2936
|
+
children:
|
|
2937
|
+
- kind: PATTERN
|
|
2938
|
+
desc: >
|
|
2939
|
+
A single architecture pattern, named with its established short (2-5 word) name
|
|
2940
|
+
(e.g. `Hexagonal Architecture`, `Transactional Outbox`, `Backend for Frontend`)
|
|
2941
|
+
and described in a concise (1-3 sentence) paragraph by the structure the pattern
|
|
2942
|
+
prescribes and the problem it solves in the solution, plus a 1-sentence rationale
|
|
2943
|
+
("why") for adopting it. A pattern is a structure reusable beyond one quality
|
|
2944
|
+
attribute (a mechanism for one quality is a Quality Perspectives tactic instead)
|
|
2945
|
+
and beyond one decision (a trade-off made once is a Design Decisions decision
|
|
2946
|
+
instead), applies the Architecture Tenets rather than restating them, and is
|
|
2947
|
+
realized by the elements of the views following it, which reference it, so its
|
|
2948
|
+
hub diagram shows where it took effect.
|
|
2949
|
+
optional: true
|
|
2950
|
+
format:
|
|
2951
|
+
type: compact
|
|
2952
|
+
diagram:
|
|
2953
|
+
type: hub
|
|
2954
|
+
center: self
|
|
2955
|
+
nodes: "[[PATTERN:*]], [[AT.PRINCIPLE:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]],
|
|
2956
|
+
[[FV.COMPONENT:*]], [[TACTIC:*]], [[DECISION:*]], [[CODE-PATTERN:*]]"
|
|
2957
|
+
labeled: true
|
|
2958
|
+
qualified: true
|
|
2959
|
+
config:
|
|
2960
|
+
size-node-width-max: 440
|
|
2961
|
+
props:
|
|
2962
|
+
- name: PRINCIPLES
|
|
2963
|
+
desc: >
|
|
2964
|
+
Comma-separated references to the ARCHITECTURE-TENETS principles the
|
|
2965
|
+
pattern applies (e.g. a `Transactional Outbox` applying an `Async between
|
|
2966
|
+
Contexts` principle), so that a pattern is adopted for a stated stance of
|
|
2967
|
+
the architecture rather than for its popularity; omitted for a pattern
|
|
2968
|
+
applying no modeled principle.
|
|
2969
|
+
value: list([[AT.PRINCIPLE:*]])
|
|
2970
|
+
optional: true
|
|
2971
|
+
- name: DRIVEN-BY
|
|
2972
|
+
desc: >
|
|
2973
|
+
Comma-separated references to the NON-FUNCTIONAL-REQUIREMENTS or
|
|
2974
|
+
SOLUTION-PREMISES objects the pattern answers beyond the principles it
|
|
2975
|
+
applies (e.g. the scalability requirement, the hosting constraint); omitted
|
|
2976
|
+
for a pattern grounded in its principles alone.
|
|
2977
|
+
value: list([[NR.*]], [[PREMISE:*]])
|
|
2978
|
+
optional: true
|
|
2979
|
+
- name: USES
|
|
2980
|
+
desc: >
|
|
2981
|
+
Comma-separated references to the smaller ARCHITECTURE-PATTERNS objects
|
|
2982
|
+
the pattern is composed of (e.g. a `Saga` using a `Transactional Outbox`
|
|
2983
|
+
for its steps), so that the patterns form a language of related structures
|
|
2984
|
+
rather than a flat catalogue.
|
|
2985
|
+
value: list([[PATTERN:*]])
|
|
2986
|
+
optional: true
|
|
2987
|
+
acyclic: true
|
|
2988
|
+
|
|
2737
2989
|
- kind: ARCH
|
|
2738
2990
|
name: Context View
|
|
2739
2991
|
id: CV
|
|
2740
|
-
file:
|
|
2992
|
+
file: 24-ARCH-CV-Context-View.md
|
|
2741
2993
|
desc: >
|
|
2742
2994
|
The relationships, dependencies, and interactions between the solution and its environment,
|
|
2743
2995
|
defining the system's boundary by enumerating the external entities sitting at it. The
|
|
@@ -2869,7 +3121,7 @@
|
|
|
2869
3121
|
- kind: ARCH
|
|
2870
3122
|
name: Functionality View
|
|
2871
3123
|
id: FV
|
|
2872
|
-
file:
|
|
3124
|
+
file: 25-ARCH-FV-Functionality-View.md
|
|
2873
3125
|
desc: >
|
|
2874
3126
|
The functional components of the solution, their responsibilities, interfaces, and primary
|
|
2875
3127
|
interactions, describing *how* the solution's runtime elements are structured and which
|
|
@@ -2908,9 +3160,9 @@
|
|
|
2908
3160
|
diagram:
|
|
2909
3161
|
type: hub
|
|
2910
3162
|
center: self
|
|
2911
|
-
nodes: "[[FV.COMPONENT:*]], [[FR.REQUIREMENT:*]], [[
|
|
2912
|
-
[[
|
|
2913
|
-
[[CODE-PATTERN:*]]"
|
|
3163
|
+
nodes: "[[FV.COMPONENT:*]], [[FR.REQUIREMENT:*]], [[PATTERN:*]], [[INTERFACE:*]],
|
|
3164
|
+
[[DM.ENTITY:*]], [[UNIT:*]], [[NODE:*]], [[CONCERN:*]], [[TACTIC:*]],
|
|
3165
|
+
[[DECISION:*]], [[CODE-PATTERN:*]]"
|
|
2914
3166
|
labeled: true
|
|
2915
3167
|
qualified: true
|
|
2916
3168
|
properties:
|
|
@@ -2948,6 +3200,14 @@
|
|
|
2948
3200
|
that every Functional Requirement is owned by at least one component.
|
|
2949
3201
|
value: list([[FR.*]])
|
|
2950
3202
|
optional: true
|
|
3203
|
+
- name: PATTERNS
|
|
3204
|
+
desc: >
|
|
3205
|
+
Comma-separated references to the ARCHITECTURE-PATTERNS objects the
|
|
3206
|
+
structure of the component follows (e.g. the service shaped by a
|
|
3207
|
+
`Hexagonal Architecture`, the publisher keeping a `Transactional Outbox`);
|
|
3208
|
+
omitted for a component following no modeled pattern.
|
|
3209
|
+
value: list([[PATTERN:*]])
|
|
3210
|
+
optional: true
|
|
2951
3211
|
- name: OWNS
|
|
2952
3212
|
desc: >
|
|
2953
3213
|
Comma-separated references to the DATA-MODEL entities the component owns,
|
|
@@ -2986,7 +3246,7 @@
|
|
|
2986
3246
|
- kind: ARCH
|
|
2987
3247
|
name: Technology Stack
|
|
2988
3248
|
id: TS
|
|
2989
|
-
file:
|
|
3249
|
+
file: 26-ARCH-TS-Technology-Stack.md
|
|
2990
3250
|
desc: >
|
|
2991
3251
|
The concrete technology products the solution is built upon, organized by tier and lifecycle
|
|
2992
3252
|
phase, recording for each component its chosen product, its purpose, and the alternatives
|
|
@@ -3347,7 +3607,7 @@
|
|
|
3347
3607
|
- kind: ARCH
|
|
3348
3608
|
name: Development Aspects
|
|
3349
3609
|
id: DA
|
|
3350
|
-
file:
|
|
3610
|
+
file: 27-ARCH-DA-Development-Aspects.md
|
|
3351
3611
|
desc: >
|
|
3352
3612
|
The architecture supporting the software development process, defining the module
|
|
3353
3613
|
organization, build approach, and codeline conventions. The artifact is absent when the
|
|
@@ -3379,18 +3639,20 @@
|
|
|
3379
3639
|
states the product choice), does not restate the runtime structure (a Functionality
|
|
3380
3640
|
View `Module` or `Subsystem` groups the logic), does not cover production
|
|
3381
3641
|
procedures (an Operations View concern does), does not prescribe how a concern is
|
|
3382
|
-
coded (a Code Patterns pattern shows that as a listing),
|
|
3642
|
+
coded (a Code Patterns pattern shows that as a listing), the tenet the rule
|
|
3643
|
+
concretizes is an Architecture Tenets maxim or principle referenced through
|
|
3644
|
+
`GUIDED-BY`, and the trade-off that
|
|
3383
3645
|
produced a rule is a Design Decisions decision referencing the aspect through
|
|
3384
3646
|
`AFFECTS`, while the quality the rule protects (usually a `Maintainability`
|
|
3385
3647
|
requirement) is
|
|
3386
3648
|
addressed by a Quality Perspectives tactic referencing the aspect through
|
|
3387
|
-
`AFFECTS`, too, so the hub diagram of an aspect shows the decision and
|
|
3388
|
-
behind it.
|
|
3649
|
+
`AFFECTS`, too, so the hub diagram of an aspect shows the tenet, the decision, and
|
|
3650
|
+
the tactic behind it.
|
|
3389
3651
|
optional: true
|
|
3390
3652
|
diagram:
|
|
3391
3653
|
type: hub
|
|
3392
3654
|
center: self
|
|
3393
|
-
nodes: "[[ASPECT:*]], [[TACTIC:*]], [[DECISION:*]]"
|
|
3655
|
+
nodes: "[[ASPECT:*]], [[MAXIM:*]], [[AT.PRINCIPLE:*]], [[TACTIC:*]], [[DECISION:*]]"
|
|
3394
3656
|
labeled: true
|
|
3395
3657
|
qualified: true
|
|
3396
3658
|
properties:
|
|
@@ -3408,11 +3670,19 @@
|
|
|
3408
3670
|
standards and conventions), `Testing` (test conventions, layout, and
|
|
3409
3671
|
coverage rules), or `Tooling` (development tools and automation).
|
|
3410
3672
|
value: enum(Structure,Build,Dependency,Codeline,Standardization,Testing,Tooling)
|
|
3673
|
+
- name: GUIDED-BY
|
|
3674
|
+
desc: >
|
|
3675
|
+
Comma-separated references to the ARCHITECTURE-TENETS objects the aspect
|
|
3676
|
+
concretizes for the source structure and process (e.g. the module
|
|
3677
|
+
layering following a `Dependencies Point Inward` principle); omitted for
|
|
3678
|
+
an aspect concretizing no modeled tenet.
|
|
3679
|
+
value: list([[MAXIM:*]], [[AT.PRINCIPLE:*]])
|
|
3680
|
+
optional: true
|
|
3411
3681
|
|
|
3412
3682
|
- kind: ARCH
|
|
3413
3683
|
name: Concurrency View
|
|
3414
3684
|
id: CO
|
|
3415
|
-
file:
|
|
3685
|
+
file: 28-ARCH-CO-Concurrency-View.md
|
|
3416
3686
|
desc: >
|
|
3417
3687
|
The concurrency structure of the solution, mapping functional components to processes and
|
|
3418
3688
|
threads, and defining how they coordinate and communicate. The artifact is absent when the
|
|
@@ -3507,7 +3777,7 @@
|
|
|
3507
3777
|
- kind: ARCH
|
|
3508
3778
|
name: Deployment View
|
|
3509
3779
|
id: DV
|
|
3510
|
-
file:
|
|
3780
|
+
file: 29-ARCH-DV-Deployment-View.md
|
|
3511
3781
|
desc: >
|
|
3512
3782
|
The environment into which the solution is deployed, partitioning it into tiers and mapping
|
|
3513
3783
|
software elements to the runtime platform, hardware, and network topology.
|
|
@@ -3762,7 +4032,7 @@
|
|
|
3762
4032
|
- kind: ARCH
|
|
3763
4033
|
name: Operations View
|
|
3764
4034
|
id: OV
|
|
3765
|
-
file:
|
|
4035
|
+
file: 30-ARCH-OV-Operations-View.md
|
|
3766
4036
|
desc: >
|
|
3767
4037
|
The way the solution is operated, administered, and supported in production, defining the
|
|
3768
4038
|
standing procedures by which the operating organization installs, configures, migrates,
|
|
@@ -3877,7 +4147,7 @@
|
|
|
3877
4147
|
- kind: ARCH
|
|
3878
4148
|
name: Quality Perspectives
|
|
3879
4149
|
id: QP
|
|
3880
|
-
file:
|
|
4150
|
+
file: 31-ARCH-QP-Quality-Perspectives.md
|
|
3881
4151
|
desc: >
|
|
3882
4152
|
How the Non-Functional Requirements (NR) are addressed by the architecture, through the
|
|
3883
4153
|
tactics built into the solution across the views.
|
|
@@ -3911,7 +4181,11 @@
|
|
|
3911
4181
|
mechanism has to meet is the `METRIC` of the addressed Non-Functional Requirement
|
|
3912
4182
|
and is not restated, the production procedure performed against the mechanism
|
|
3913
4183
|
(e.g. scaling out, restoring) is an Operations View concern referenced through
|
|
3914
|
-
`OPERATED-BY`, the
|
|
4184
|
+
`OPERATED-BY`, the tenet the mechanism follows is an Architecture Tenets maxim or
|
|
4185
|
+
principle referenced through `GUIDED-BY`, the structure it is built from is an
|
|
4186
|
+
Architecture Patterns pattern referenced through `PATTERNS`, the trade-off that
|
|
4187
|
+
chose the mechanism
|
|
4188
|
+
over alternatives is a
|
|
3915
4189
|
Design Decisions decision referencing the tactic through `DECIDES`, the product
|
|
3916
4190
|
realizing the mechanism is a Technology Stack component referenced through
|
|
3917
4191
|
`TOOLS`, the developer-facing rule about the source structure is an aspect of the
|
|
@@ -3927,9 +4201,10 @@
|
|
|
3927
4201
|
diagram:
|
|
3928
4202
|
type: hub
|
|
3929
4203
|
center: self
|
|
3930
|
-
nodes: "[[TACTIC:*]], [[NR.REQUIREMENT:*]], [[
|
|
3931
|
-
[[
|
|
3932
|
-
[[
|
|
4204
|
+
nodes: "[[TACTIC:*]], [[NR.REQUIREMENT:*]], [[MAXIM:*]], [[AT.PRINCIPLE:*]],
|
|
4205
|
+
[[PATTERN:*]], [[FV.COMPONENT:*]], [[UNIT:*]], [[ASPECT:*]], [[NODE:*]],
|
|
4206
|
+
[[DM.ENTITY:*]], [[CONCERN:*]], [[DECISION:*]], [[TS.TIER:*.COMPONENT:*]],
|
|
4207
|
+
[[CODE-PATTERN:*]], [[TEST-CASE:*]]"
|
|
3933
4208
|
labeled: true
|
|
3934
4209
|
qualified: true
|
|
3935
4210
|
properties:
|
|
@@ -3959,6 +4234,22 @@
|
|
|
3959
4234
|
Comma-separated references to the NON-FUNCTIONAL-REQUIREMENTS objects the
|
|
3960
4235
|
tactic addresses.
|
|
3961
4236
|
value: list([[NR.*]])
|
|
4237
|
+
- name: GUIDED-BY
|
|
4238
|
+
desc: >
|
|
4239
|
+
Comma-separated references to the ARCHITECTURE-TENETS objects the
|
|
4240
|
+
mechanism of the tactic follows (e.g. the stateless replication following
|
|
4241
|
+
a `Stateless Services` principle); omitted for a tactic following no
|
|
4242
|
+
modeled tenet.
|
|
4243
|
+
value: list([[MAXIM:*]], [[AT.PRINCIPLE:*]])
|
|
4244
|
+
optional: true
|
|
4245
|
+
- name: PATTERNS
|
|
4246
|
+
desc: >
|
|
4247
|
+
Comma-separated references to the ARCHITECTURE-PATTERNS objects the
|
|
4248
|
+
mechanism of the tactic is built from (e.g. the failover built on a
|
|
4249
|
+
`Circuit Breaker`), while `MECHANISM` states the mechanism itself; omitted
|
|
4250
|
+
for a tactic built from no modeled pattern.
|
|
4251
|
+
value: list([[PATTERN:*]])
|
|
4252
|
+
optional: true
|
|
3962
4253
|
- name: MECHANISM
|
|
3963
4254
|
desc: >
|
|
3964
4255
|
The design mechanism through which the tactic is applied to achieve the
|
|
@@ -4001,7 +4292,7 @@
|
|
|
4001
4292
|
- kind: ARCH
|
|
4002
4293
|
name: Design Decisions
|
|
4003
4294
|
id: DD
|
|
4004
|
-
file:
|
|
4295
|
+
file: 32-ARCH-DD-Design-Decisions.md
|
|
4005
4296
|
desc: >
|
|
4006
4297
|
The major decisions related to the solution design, each recording the forces at play, the
|
|
4007
4298
|
chosen response, and the reasoning that justifies it. The artifact is the last
|
|
@@ -4068,7 +4359,10 @@
|
|
|
4068
4359
|
A constraint itself is not a decision: a compliance obligation, a hosting mandate,
|
|
4069
4360
|
or a partner-imposed threshold is a Non-Functional Requirement (of category
|
|
4070
4361
|
`Compliance`, `Constraint`, or the affected quality), and the decision is the
|
|
4071
|
-
response to it, referencing it through `DRIVEN-BY`.
|
|
4362
|
+
response to it, referencing it through `DRIVEN-BY`. A standing rule is not a
|
|
4363
|
+
decision either: a maxim or principle reusable across many decisions is an
|
|
4364
|
+
Architecture Tenets object, and the decision applies it, referencing it through
|
|
4365
|
+
`GUIDED-BY`.
|
|
4072
4366
|
|
|
4073
4367
|
`WHEN`, `WHAT`, and `WHY` are each just a single paragraph of concise and brief
|
|
4074
4368
|
prose text, usually comprised of just 1 to 3 sentences. The value of a decision is
|
|
@@ -4089,11 +4383,12 @@
|
|
|
4089
4383
|
diagram:
|
|
4090
4384
|
type: hub
|
|
4091
4385
|
center: self
|
|
4092
|
-
nodes: "[[DECISION:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]], [[
|
|
4093
|
-
[[
|
|
4094
|
-
[[
|
|
4095
|
-
[[
|
|
4096
|
-
[[
|
|
4386
|
+
nodes: "[[DECISION:*]], [[NR.REQUIREMENT:*]], [[PREMISE:*]], [[MAXIM:*]],
|
|
4387
|
+
[[AT.PRINCIPLE:*]], [[PATTERN:*]], [[DM.ENTITY:*]], [[LIFECYCLE:*]], [[ROLE:*]],
|
|
4388
|
+
[[INTERFACE:*]], [[TYPE:*]], [[ENDPOINT:*]], [[IC.PRINCIPLE:*]],
|
|
4389
|
+
[[CONVENTION:*]], [[DIALOG-PATTERN:*]], [[STORYBOARD:*]], [[ELEMENT:*]],
|
|
4390
|
+
[[CV.ENTITY:*]], [[FV.COMPONENT:*]], [[UNIT:*]], [[ASPECT:*]], [[DV.TIER:*]],
|
|
4391
|
+
[[AREA:*]], [[NODE:*]], [[NETWORK:*]], [[TACTIC:*]],
|
|
4097
4392
|
[[TS.TIER:*.COMPONENT:*]], [[CODE-PATTERN:*]]"
|
|
4098
4393
|
labeled: true
|
|
4099
4394
|
qualified: true
|
|
@@ -4130,6 +4425,15 @@
|
|
|
4130
4425
|
and only exceptionally a premise alone, and a decision finding no
|
|
4131
4426
|
requirement to name reveals a missing one rather than a needless reference.
|
|
4132
4427
|
value: list([[NR.*]], [[PREMISE:*]])
|
|
4428
|
+
- name: GUIDED-BY
|
|
4429
|
+
desc: >
|
|
4430
|
+
Comma-separated references to the ARCHITECTURE-TENETS objects the decision
|
|
4431
|
+
applies (e.g. the `Buy before Build` maxim settling the choice of a managed
|
|
4432
|
+
service, the `Async between Contexts` principle settling the integration
|
|
4433
|
+
style), anchoring the principles the rationale `WHY` rests on; omitted for
|
|
4434
|
+
a decision applying no modeled tenet.
|
|
4435
|
+
value: list([[MAXIM:*]], [[AT.PRINCIPLE:*]])
|
|
4436
|
+
optional: true
|
|
4133
4437
|
- name: AFFECTS
|
|
4134
4438
|
desc: >
|
|
4135
4439
|
Comma-separated references to the objects of the DATA, APIS, UXUI, or ARCH
|
|
@@ -4141,18 +4445,19 @@
|
|
|
4141
4445
|
chosen over a native one, the components split, the external system
|
|
4142
4446
|
integrated); omitted for a decision shaping no modeled element.
|
|
4143
4447
|
value: list([[DM.ENTITY:*]], [[LIFECYCLE:*]], [[ROLE:*]], [[INTERFACE:*]],
|
|
4144
|
-
[[TYPE:*]], [[ENDPOINT:*]], [[PRINCIPLE:*]], [[CONVENTION:*]],
|
|
4448
|
+
[[TYPE:*]], [[ENDPOINT:*]], [[IC.PRINCIPLE:*]], [[CONVENTION:*]],
|
|
4145
4449
|
[[DIALOG-PATTERN:*]], [[STORYBOARD:*]], [[ELEMENT:*]], [[CV.ENTITY:*]],
|
|
4146
4450
|
[[FV.COMPONENT:*]], [[UNIT:*]], [[ASPECT:*]], [[DV.TIER:*]], [[AREA:*]],
|
|
4147
4451
|
[[NODE:*]], [[NETWORK:*]])
|
|
4148
4452
|
optional: true
|
|
4149
4453
|
- name: DECIDES
|
|
4150
4454
|
desc: >
|
|
4151
|
-
Comma-separated references to the
|
|
4152
|
-
TECHNOLOGY-STACK components the decision
|
|
4153
|
-
i.e. the mechanism or product
|
|
4154
|
-
when the decision chose no
|
|
4155
|
-
|
|
4455
|
+
Comma-separated references to the ARCHITECTURE-PATTERNS objects,
|
|
4456
|
+
QUALITY-PERSPECTIVES tactics, or TECHNOLOGY-STACK components the decision
|
|
4457
|
+
chose over their alternatives, i.e. the pattern, mechanism, or product
|
|
4458
|
+
which exists because of this decision; omitted when the decision chose no
|
|
4459
|
+
modeled pattern, tactic, or product.
|
|
4460
|
+
value: list([[PATTERN:*]], [[TACTIC:*]], [[TS.TIER:*.COMPONENT:*]])
|
|
4156
4461
|
optional: true
|
|
4157
4462
|
- name: ALTERNATIVES
|
|
4158
4463
|
desc: >
|
|
@@ -4242,7 +4547,7 @@
|
|
|
4242
4547
|
- kind: ARCH
|
|
4243
4548
|
name: Code Patterns
|
|
4244
4549
|
id: CP
|
|
4245
|
-
file:
|
|
4550
|
+
file: 33-ARCH-CP-Code-Patterns.md
|
|
4246
4551
|
desc: >
|
|
4247
4552
|
The implementation patterns the source code of the solution follows, each prescribing how
|
|
4248
4553
|
one recurring concern (e.g. authorization enforcement, entity persistence, error
|
|
@@ -4283,8 +4588,9 @@
|
|
|
4283
4588
|
short (typically 10-30 lines) and the prose names what the listing cannot: the
|
|
4284
4589
|
places the pattern applies and the deviation it rules out (`AVOID`).
|
|
4285
4590
|
|
|
4286
|
-
A pattern states how a concern is coded, and nothing else: the
|
|
4287
|
-
it implements is
|
|
4591
|
+
A pattern states how a concern is coded, and nothing else: the structure or the
|
|
4592
|
+
quality mechanism it implements is an Architecture Patterns pattern or a Quality
|
|
4593
|
+
Perspectives tactic referenced through `REALIZES`, the
|
|
4288
4594
|
trade-off that chose its approach over alternatives is a Design Decisions decision
|
|
4289
4595
|
referenced through `DECIDED-BY` (a pattern weighs no alternatives itself), the
|
|
4290
4596
|
product it codes against is a Technology Stack component referenced through
|
|
@@ -4299,7 +4605,7 @@
|
|
|
4299
4605
|
center: self
|
|
4300
4606
|
nodes: "[[CODE-PATTERN:*]], [[FV.COMPONENT:*]], [[UNIT:*]], [[DM.ENTITY:*]],
|
|
4301
4607
|
[[ROLE:*]], [[INTERFACE:*]], [[ENDPOINT:*]], [[TS.TIER:*.COMPONENT:*]],
|
|
4302
|
-
[[TACTIC:*]], [[DECISION:*]]"
|
|
4608
|
+
[[PATTERN:*]], [[TACTIC:*]], [[DECISION:*]]"
|
|
4303
4609
|
labeled: true
|
|
4304
4610
|
qualified: true
|
|
4305
4611
|
config:
|
|
@@ -4317,10 +4623,12 @@
|
|
|
4317
4623
|
optional: true
|
|
4318
4624
|
- name: REALIZES
|
|
4319
4625
|
desc: >
|
|
4320
|
-
Comma-separated references to the
|
|
4321
|
-
is the coded form of (e.g. the
|
|
4322
|
-
|
|
4323
|
-
|
|
4626
|
+
Comma-separated references to the ARCHITECTURE-PATTERNS objects or
|
|
4627
|
+
QUALITY-PERSPECTIVES tactics the pattern is the coded form of (e.g. the
|
|
4628
|
+
port interface coding the hexagonal architecture, the token check
|
|
4629
|
+
implementing the access security tactic); omitted for a pattern serving
|
|
4630
|
+
no modeled architecture pattern or tactic.
|
|
4631
|
+
value: list([[PATTERN:*]], [[TACTIC:*]])
|
|
4324
4632
|
optional: true
|
|
4325
4633
|
- name: DECIDED-BY
|
|
4326
4634
|
desc: >
|
|
@@ -4355,7 +4663,7 @@
|
|
|
4355
4663
|
- kind: TEST
|
|
4356
4664
|
name: Test Cases
|
|
4357
4665
|
id: TC
|
|
4358
|
-
file:
|
|
4666
|
+
file: 34-TEST-TC-Test-Cases.md
|
|
4359
4667
|
desc: >
|
|
4360
4668
|
The verifiable conditions and steps used to confirm that requirements, domain rules, use
|
|
4361
4669
|
case scenarios, state transitions, and the mechanisms, procedures, and decisions of the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rse/specbook",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"publishConfig": { "access": "public" },
|
|
5
5
|
"description": "Markdown-based Specification Format (API, CLI and MCP service)",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@rse/mrcs": "0.9.2",
|
|
29
29
|
"@rse/gradia": "1.4.2",
|
|
30
30
|
"beautiful-mermaid": "1.1.3",
|
|
31
|
-
"@
|
|
31
|
+
"@d2lang/d2": "0.1.34",
|
|
32
32
|
"shiki": "4.5.0",
|
|
33
33
|
"pdfjs-dist": "6.4.299",
|
|
34
34
|
"@napi-rs/canvas": "1.0.10",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"picomatch": "4.0.7",
|
|
49
49
|
"es-toolkit": "1.52.0",
|
|
50
50
|
"fastify": "5.12.5",
|
|
51
|
-
"@fastify/websocket": "11.3.
|
|
51
|
+
"@fastify/websocket": "11.3.4",
|
|
52
52
|
"@modelcontextprotocol/sdk": "1.32.1",
|
|
53
53
|
"zod": "4.6.5"
|
|
54
54
|
},
|
|
@@ -58,12 +58,12 @@
|
|
|
58
58
|
"@eslint/js": "10.0.1",
|
|
59
59
|
"typescript-eslint": "8.71.1",
|
|
60
60
|
"eslint-plugin-promise": "7.3.0",
|
|
61
|
-
"neostandard": "0.14.0
|
|
61
|
+
"neostandard": "0.14.0",
|
|
62
62
|
"globals": "17.13.0",
|
|
63
|
-
"eslint-plugin-yml": "3.
|
|
63
|
+
"eslint-plugin-yml": "3.9.0",
|
|
64
64
|
"markdownlint": "0.41.1",
|
|
65
65
|
"markdownlint-cli2": "0.23.3",
|
|
66
|
-
"@types/node": "26.6.
|
|
66
|
+
"@types/node": "26.6.5",
|
|
67
67
|
"@types/picomatch": "4.0.3",
|
|
68
68
|
"@types/subset-font": "2.3.0",
|
|
69
69
|
"@types/nunjucks": "3.2.6",
|