@transitrix/diagrams 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +47 -47
- package/dist/__tests__/edge-path.test.js +8 -0
- package/dist/activity-card/__tests__/example.test.js +20 -1
- package/dist/activity-card/__tests__/layout.test.js +102 -11
- package/dist/activity-card/__tests__/resolver.test.js +139 -6
- package/dist/activity-card/index.d.ts +1 -1
- package/dist/activity-card/layout.d.ts +1 -1
- package/dist/activity-card/layout.js +220 -103
- package/dist/activity-card/resolver.js +107 -26
- package/dist/activity-card/types.d.ts +150 -27
- package/dist/activity-card/validate.js +3 -0
- package/dist/actor/__tests__/validate.test.js +63 -31
- package/dist/actor/index.d.ts +1 -1
- package/dist/actor/index.js +1 -1
- package/dist/actor/types.d.ts +7 -3
- package/dist/actor/types.js +17 -3
- package/dist/actor/validate.js +55 -26
- package/dist/assertion/types.d.ts +3 -1
- package/dist/assertion/types.js +1 -1
- package/dist/change/__tests__/validate.test.js +40 -34
- package/dist/change/index.d.ts +1 -0
- package/dist/change/types.d.ts +1 -1
- package/dist/change/types.js +2 -2
- package/dist/change/validate.d.ts +6 -1
- package/dist/change/validate.js +68 -41
- package/dist/compliance/__tests__/classify.test.js +34 -0
- package/dist/compliance/__tests__/coverage-metric.test.js +146 -46
- package/dist/compliance/__tests__/html.test.js +2 -2
- package/dist/compliance/__tests__/impact.test.js +311 -6
- package/dist/compliance/classify.d.ts +6 -0
- package/dist/compliance/classify.js +9 -1
- package/dist/compliance/coverage-metric.d.ts +31 -11
- package/dist/compliance/coverage-metric.js +149 -39
- package/dist/compliance/html.js +77 -74
- package/dist/compliance/impact.d.ts +77 -16
- package/dist/compliance/impact.js +193 -25
- package/dist/compliance/index.d.ts +2 -2
- package/dist/compliance/index.js +1 -1
- package/dist/compliance/markdown.js +1 -0
- package/dist/compliance/types.d.ts +25 -6
- package/dist/edge-path.d.ts +8 -4
- package/dist/edge-path.js +11 -6
- package/dist/factor/__tests__/validate.test.js +74 -45
- package/dist/factor/index.d.ts +3 -2
- package/dist/factor/index.js +1 -1
- package/dist/factor/types.d.ts +4 -7
- package/dist/factor/types.js +10 -5
- package/dist/factor/validate.d.ts +6 -1
- package/dist/factor/validate.js +68 -50
- package/dist/fgca/__tests__/resolver.test.js +185 -0
- package/dist/fgca/index.d.ts +2 -0
- package/dist/fgca/index.js +1 -0
- package/dist/fgca/resolver.d.ts +49 -0
- package/dist/fgca/resolver.js +124 -0
- package/dist/goals/index.d.ts +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/process-blueprint/__tests__/layout.test.js +37 -0
- package/dist/process-blueprint/layout.js +5 -1
- package/dist/process-blueprint/types.d.ts +22 -1
- package/dist/stakeholder/__tests__/validate.test.js +49 -47
- package/dist/stakeholder/index.d.ts +1 -0
- package/dist/stakeholder/types.d.ts +3 -4
- package/dist/stakeholder/types.js +2 -3
- package/dist/stakeholder/validate.d.ts +6 -1
- package/dist/stakeholder/validate.js +71 -50
- package/dist/target-state/__tests__/validate.test.js +43 -27
- package/dist/target-state/index.d.ts +2 -0
- package/dist/target-state/index.js +1 -0
- package/dist/target-state/types.d.ts +6 -1
- package/dist/target-state/types.js +8 -7
- package/dist/target-state/validate.d.ts +6 -1
- package/dist/target-state/validate.js +69 -45
- package/dist/theme/themes.js +69 -69
- package/dist/webview/__tests__/entry.test.js +11 -11
- package/dist/webview/render-activities.d.ts +3 -1
- package/dist/webview/render-activities.js +2 -2
- package/dist/webview/render-activity-card.js +104 -77
- package/dist/webview/render-fgca.d.ts +4 -0
- package/dist/webview/render-fgca.js +2 -5
- package/dist/webview/render-goals.d.ts +1 -0
- package/dist/webview/render-goals.js +15 -15
- package/dist/webview/render-process-blueprint.js +10 -10
- package/package.json +40 -40
- package/src/__tests__/edge-path.test.ts +58 -46
- package/src/__tests__/scope.test.ts +27 -27
- package/src/__tests__/yaml-normalize.test.ts +158 -158
- package/src/activities/__tests__/cpm.test.ts +164 -164
- package/src/activities/__tests__/gantt.test.ts +245 -245
- package/src/activities/__tests__/layout.test.ts +112 -112
- package/src/activities/__tests__/validate.test.ts +409 -409
- package/src/activities/cpm.ts +95 -95
- package/src/activities/gantt.ts +276 -276
- package/src/activities/index.ts +28 -28
- package/src/activities/layout.ts +112 -112
- package/src/activities/types.ts +148 -148
- package/src/activities/validate.ts +357 -357
- package/src/activity-card/__tests__/example.test.ts +85 -66
- package/src/activity-card/__tests__/layout.test.ts +169 -63
- package/src/activity-card/__tests__/resolver.test.ts +307 -161
- package/src/activity-card/__tests__/validate.test.ts +131 -131
- package/src/activity-card/index.ts +38 -32
- package/src/activity-card/layout.ts +324 -194
- package/src/activity-card/resolver.ts +415 -337
- package/src/activity-card/types.ts +376 -237
- package/src/activity-card/validate.ts +162 -158
- package/src/actor/__tests__/validate.test.ts +70 -31
- package/src/actor/index.ts +1 -1
- package/src/actor/types.ts +21 -7
- package/src/actor/validate.ts +59 -27
- package/src/applications/__tests__/validate.test.ts +256 -256
- package/src/applications/index.ts +11 -11
- package/src/applications/types.ts +43 -43
- package/src/applications/validate.ts +131 -131
- package/src/assertion/__tests__/example.test.ts +37 -37
- package/src/assertion/__tests__/validate.test.ts +142 -142
- package/src/assertion/index.ts +12 -12
- package/src/assertion/types.ts +60 -58
- package/src/assertion/validate.ts +145 -145
- package/src/blocks/__tests__/layout.test.ts +169 -169
- package/src/blocks/__tests__/validate.test.ts +260 -260
- package/src/blocks/index.ts +17 -17
- package/src/blocks/layout.ts +186 -186
- package/src/blocks/types.ts +62 -62
- package/src/blocks/validate.ts +206 -206
- package/src/capability-map/__tests__/validate.test.ts +238 -238
- package/src/capability-map/index.ts +8 -8
- package/src/capability-map/types.ts +29 -29
- package/src/capability-map/validate.ts +127 -127
- package/src/change/__tests__/validate.test.ts +43 -34
- package/src/change/index.ts +1 -0
- package/src/change/types.ts +5 -3
- package/src/change/validate.ts +75 -43
- package/src/compliance/__tests__/classify.test.ts +64 -27
- package/src/compliance/__tests__/confidence.test.ts +98 -98
- package/src/compliance/__tests__/coverage-metric.test.ts +300 -188
- package/src/compliance/__tests__/demo-scenario.test.ts +273 -273
- package/src/compliance/__tests__/example.test.ts +57 -57
- package/src/compliance/__tests__/gap-report.test.ts +128 -128
- package/src/compliance/__tests__/html.test.ts +141 -141
- package/src/compliance/__tests__/impact.test.ts +840 -481
- package/src/compliance/__tests__/markdown.test.ts +94 -94
- package/src/compliance/__tests__/views.test.ts +64 -64
- package/src/compliance/classify.ts +100 -84
- package/src/compliance/confidence.ts +69 -69
- package/src/compliance/coverage-metric.ts +404 -263
- package/src/compliance/gap-report.ts +94 -94
- package/src/compliance/html.ts +298 -295
- package/src/compliance/impact.ts +861 -677
- package/src/compliance/index.ts +57 -56
- package/src/compliance/markdown.ts +136 -135
- package/src/compliance/reverse-index.ts +33 -33
- package/src/compliance/types.ts +136 -120
- package/src/compliance/views.ts +46 -46
- package/src/compliance-matrix/__tests__/build.test.ts +200 -200
- package/src/compliance-matrix/__tests__/example.test.ts +57 -57
- package/src/compliance-matrix/index.ts +11 -11
- package/src/compliance-matrix/types.ts +102 -102
- package/src/edge-path.ts +50 -44
- package/src/factor/__tests__/validate.test.ts +80 -45
- package/src/factor/index.ts +3 -7
- package/src/factor/types.ts +14 -18
- package/src/factor/validate.ts +77 -51
- package/src/fgca/__tests__/chain-table.test.ts +172 -172
- package/src/fgca/__tests__/layout.test.ts +179 -179
- package/src/fgca/__tests__/parse-canonical.test.ts +248 -248
- package/src/fgca/__tests__/preview-layout.test.ts +124 -124
- package/src/fgca/__tests__/resolver.test.ts +209 -0
- package/src/fgca/__tests__/validate.test.ts +142 -142
- package/src/fgca/chain-table.ts +225 -225
- package/src/fgca/index.ts +47 -45
- package/src/fgca/layout.ts +204 -204
- package/src/fgca/nodeTypes.ts +11 -11
- package/src/fgca/nodes/FGCAActivityNode.tsx +65 -65
- package/src/fgca/nodes/FGCAChangeNode.tsx +64 -64
- package/src/fgca/nodes/FGCAFactorNode.tsx +64 -64
- package/src/fgca/nodes/FGCAGoalNode.tsx +72 -72
- package/src/fgca/parse-canonical.ts +400 -400
- package/src/fgca/preview-layout.ts +217 -217
- package/src/fgca/resolver.ts +157 -0
- package/src/fgca/types.ts +50 -50
- package/src/fgca/validate.ts +126 -126
- package/src/geometry.ts +9 -9
- package/src/goals/__tests__/layout.test.ts +175 -175
- package/src/goals/__tests__/mutations.test.ts +111 -111
- package/src/goals/__tests__/parse-canonical.test.ts +145 -145
- package/src/goals/__tests__/validate.test.ts +202 -202
- package/src/goals/index.ts +20 -21
- package/src/goals/layout.ts +172 -172
- package/src/goals/mutations.ts +123 -123
- package/src/goals/parse-canonical.ts +286 -286
- package/src/goals/types.ts +85 -85
- package/src/goals/validate.ts +136 -136
- package/src/index.ts +28 -23
- package/src/process-blueprint/__tests__/compliance-lane.test.ts +320 -320
- package/src/process-blueprint/__tests__/layout.test.ts +240 -195
- package/src/process-blueprint/__tests__/validate.test.ts +310 -310
- package/src/process-blueprint/index.ts +31 -31
- package/src/process-blueprint/layout.ts +535 -531
- package/src/process-blueprint/types.ts +263 -242
- package/src/process-blueprint/validate.ts +181 -181
- package/src/process-map/__tests__/validate.test.ts +223 -223
- package/src/process-map/index.ts +10 -10
- package/src/process-map/types.ts +36 -36
- package/src/process-map/validate.ts +135 -135
- package/src/products/__tests__/validate.test.ts +239 -239
- package/src/products/index.ts +9 -9
- package/src/products/types.ts +31 -31
- package/src/products/validate.ts +112 -112
- package/src/repo-validate/__tests__/validate-repo.test.ts +149 -149
- package/src/repo-validate/index.ts +2 -2
- package/src/repo-validate/types.ts +50 -50
- package/src/repo-validate/validate-repo.ts +196 -196
- package/src/requirement/__tests__/example.test.ts +24 -24
- package/src/requirement/__tests__/validate.test.ts +96 -96
- package/src/requirement/index.ts +4 -4
- package/src/requirement/types.ts +35 -35
- package/src/requirement/validate.ts +92 -92
- package/src/scenarios/__tests__/validate.test.ts +209 -209
- package/src/scenarios/index.ts +15 -15
- package/src/scenarios/types.ts +37 -37
- package/src/scenarios/validate.ts +122 -122
- package/src/schema-version.ts +16 -16
- package/src/scope.ts +46 -46
- package/src/stakeholder/__tests__/validate.test.ts +51 -47
- package/src/stakeholder/index.ts +1 -0
- package/src/stakeholder/types.ts +7 -7
- package/src/stakeholder/validate.ts +79 -52
- package/src/target-state/__tests__/validate.test.ts +48 -27
- package/src/target-state/index.ts +2 -0
- package/src/target-state/types.ts +11 -7
- package/src/target-state/validate.ts +76 -46
- package/src/theme/index.ts +4 -4
- package/src/theme/themes.ts +237 -237
- package/src/theme/tokens.ts +133 -133
- package/src/typed-id.ts +56 -56
- package/src/validation-types.ts +36 -36
- package/src/webview/__tests__/entry-notations.test.ts +77 -77
- package/src/webview/__tests__/entry.test.ts +64 -64
- package/src/webview/__tests__/render-goals.test.ts +72 -72
- package/src/webview/entry.ts +292 -292
- package/src/webview/render-activities.ts +5 -3
- package/src/webview/render-activity-card.ts +266 -234
- package/src/webview/render-fgca.ts +6 -5
- package/src/webview/render-goals.ts +111 -110
- package/src/webview/render-process-blueprint.ts +207 -207
- package/src/webview/styles.css +322 -323
- package/src/yaml-normalize.ts +56 -56
- package/dist/element-envelope.d.ts +0 -15
- package/dist/element-envelope.js +0 -55
- package/dist/issues/__tests__/layout.test.js +0 -62
- package/dist/issues/__tests__/validate.test.d.ts +0 -1
- package/dist/issues/__tests__/validate.test.js +0 -82
- package/dist/issues/index.d.ts +0 -4
- package/dist/issues/index.js +0 -2
- package/dist/issues/layout.d.ts +0 -10
- package/dist/issues/layout.js +0 -82
- package/dist/issues/types.d.ts +0 -61
- package/dist/issues/types.js +0 -6
- package/dist/issues/validate.d.ts +0 -3
- package/dist/issues/validate.js +0 -143
- package/dist/webview/transitrix-render.css +0 -323
- package/dist/webview/transitrix-render.js +0 -6452
- package/dist/webview/transitrix-render.js.map +0 -7
- package/src/element-envelope.ts +0 -76
- /package/dist/{issues/__tests__/layout.test.d.ts → fgca/__tests__/resolver.test.d.ts} +0 -0
|
@@ -17,6 +17,11 @@ export interface ActivityCardBlock {
|
|
|
17
17
|
project: string;
|
|
18
18
|
description?: string;
|
|
19
19
|
milestones?: RawMilestone[];
|
|
20
|
+
/**
|
|
21
|
+
* Supplementary notes shown in the card footer. Free text; stored in the
|
|
22
|
+
* view file (not in canon elements) as report-level context.
|
|
23
|
+
*/
|
|
24
|
+
notes?: string;
|
|
20
25
|
}
|
|
21
26
|
export interface ActivityCardDoc {
|
|
22
27
|
notation: string;
|
|
@@ -41,6 +46,17 @@ export interface ResolvedProject {
|
|
|
41
46
|
/** Planned work range. */
|
|
42
47
|
start_date?: string;
|
|
43
48
|
end_date?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Activity scale: programme | project | workstream | task (or any custom
|
|
51
|
+
* value). Shown in the card header so the reader knows what level this card
|
|
52
|
+
* represents. Optional — card shows "—" when absent.
|
|
53
|
+
*/
|
|
54
|
+
activity_type?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Current execution state: planned | in_progress | on_track | at_risk |
|
|
57
|
+
* blocked | completed | cancelled. Optional — card shows "—" when absent.
|
|
58
|
+
*/
|
|
59
|
+
status?: string;
|
|
44
60
|
}
|
|
45
61
|
export interface ResolvedMilestone {
|
|
46
62
|
id: string;
|
|
@@ -50,15 +66,32 @@ export interface ResolvedMilestone {
|
|
|
50
66
|
/** CHANGE-… IDs this milestone delivers (subset of the project's). */
|
|
51
67
|
deliversChanges: string[];
|
|
52
68
|
}
|
|
53
|
-
export interface
|
|
69
|
+
export interface ResolvedDriver {
|
|
70
|
+
id: string;
|
|
71
|
+
name: string;
|
|
72
|
+
}
|
|
73
|
+
/** @deprecated Use {@link ResolvedDriver}. */
|
|
74
|
+
export type ResolvedFactor = ResolvedDriver;
|
|
75
|
+
/**
|
|
76
|
+
* A dated finding about the current state of a Driver, answering the
|
|
77
|
+
* question "what specific problem are we solving?" (pain point).
|
|
78
|
+
* Resolved from ASSESSMENT elements whose `assesses` field points to a
|
|
79
|
+
* Driver that is in scope for this activity's motivation chain.
|
|
80
|
+
*/
|
|
81
|
+
export interface ResolvedAssessment {
|
|
54
82
|
id: string;
|
|
55
83
|
name: string;
|
|
84
|
+
/** ID of the Driver this assessment observes. */
|
|
85
|
+
driverId: string;
|
|
86
|
+
description?: string;
|
|
87
|
+
/** ISO 8601 date when the finding was observed. */
|
|
88
|
+
observed_at?: string;
|
|
56
89
|
}
|
|
57
90
|
export interface ResolvedGoal {
|
|
58
91
|
id: string;
|
|
59
92
|
name: string;
|
|
60
|
-
/**
|
|
61
|
-
|
|
93
|
+
/** DRIVER-… IDs that motivate this goal (canonical `goal.factors` YAML field). */
|
|
94
|
+
driverIds: string[];
|
|
62
95
|
}
|
|
63
96
|
export interface ResolvedChange {
|
|
64
97
|
id: string;
|
|
@@ -66,9 +99,9 @@ export interface ResolvedChange {
|
|
|
66
99
|
/** GOAL-… IDs this change advances (canonical `change.goals`). */
|
|
67
100
|
goalIds: string[];
|
|
68
101
|
}
|
|
69
|
-
/** Motivation chain:
|
|
102
|
+
/** Motivation chain: Drivers → Goals → Changes, scoped to the project. */
|
|
70
103
|
export interface ResolvedMotivation {
|
|
71
|
-
|
|
104
|
+
drivers: ResolvedDriver[];
|
|
72
105
|
goals: ResolvedGoal[];
|
|
73
106
|
changes: ResolvedChange[];
|
|
74
107
|
}
|
|
@@ -80,6 +113,21 @@ export interface ResolvedChildActivity {
|
|
|
80
113
|
end_date?: string;
|
|
81
114
|
owner?: string;
|
|
82
115
|
}
|
|
116
|
+
/** A STAKEHOLDER element linked to the project (via `activity_stakeholder`). */
|
|
117
|
+
export interface ResolvedStakeholder {
|
|
118
|
+
id: string;
|
|
119
|
+
name: string;
|
|
120
|
+
/** internal | external (STAKEHOLDER `type`). */
|
|
121
|
+
type?: string;
|
|
122
|
+
interest?: string;
|
|
123
|
+
influence?: string;
|
|
124
|
+
/**
|
|
125
|
+
* Project role from the `activity_stakeholder` relation:
|
|
126
|
+
* initiator | owner | sponsor | project_manager.
|
|
127
|
+
* Optional — card shows the name without a role badge when absent.
|
|
128
|
+
*/
|
|
129
|
+
role?: string;
|
|
130
|
+
}
|
|
83
131
|
export interface ResolvedActivityCard {
|
|
84
132
|
cardId: string;
|
|
85
133
|
/** The card's own executive-summary description (distinct from the project's). */
|
|
@@ -88,8 +136,31 @@ export interface ResolvedActivityCard {
|
|
|
88
136
|
/** Sorted ascending by `date`. */
|
|
89
137
|
milestones: ResolvedMilestone[];
|
|
90
138
|
motivation: ResolvedMotivation;
|
|
139
|
+
/**
|
|
140
|
+
* Assessments (pain points) for the in-scope Drivers, sorted by
|
|
141
|
+
* `observed_at` ascending. Empty when no Assessment elements are found —
|
|
142
|
+
* the gap is intentionally visible on the card.
|
|
143
|
+
*/
|
|
144
|
+
assessments: ResolvedAssessment[];
|
|
91
145
|
/** Activities whose `parent` = the project Activity id. */
|
|
92
146
|
childActivities: ResolvedChildActivity[];
|
|
147
|
+
/**
|
|
148
|
+
* Names of the GOALs the project DIRECTLY serves (the `activity_goal`
|
|
149
|
+
* targets, not the wider motivation chain) — painted as the "Project goal"
|
|
150
|
+
* text field. Empty when the project serves no goal.
|
|
151
|
+
*/
|
|
152
|
+
goalNames?: string[];
|
|
153
|
+
/**
|
|
154
|
+
* Stakeholders linked to the project via active `activity_stakeholder`
|
|
155
|
+
* relations. Empty when none are linked (the card still shows the field
|
|
156
|
+
* with a "—" placeholder).
|
|
157
|
+
*/
|
|
158
|
+
stakeholders?: ResolvedStakeholder[];
|
|
159
|
+
/**
|
|
160
|
+
* Supplementary notes for the card footer (from `activity_card.notes` in
|
|
161
|
+
* the view YAML). Not a canonical element field.
|
|
162
|
+
*/
|
|
163
|
+
notes?: string;
|
|
93
164
|
}
|
|
94
165
|
import type { LayoutBounds } from '../geometry.js';
|
|
95
166
|
export type { LayoutBounds };
|
|
@@ -102,45 +173,89 @@ export interface DateField {
|
|
|
102
173
|
width: number;
|
|
103
174
|
height: number;
|
|
104
175
|
}
|
|
105
|
-
/**
|
|
106
|
-
export interface
|
|
107
|
-
|
|
176
|
+
/** A small badge shown in the header (activity type or status). */
|
|
177
|
+
export interface Badge {
|
|
178
|
+
label: string;
|
|
179
|
+
x: number;
|
|
180
|
+
y: number;
|
|
181
|
+
width: number;
|
|
182
|
+
height: number;
|
|
183
|
+
}
|
|
184
|
+
/** One stakeholder role slot in the header roles row. Always rendered; `name` is "—" when unfilled. */
|
|
185
|
+
export interface StakeholderRoleSlot {
|
|
186
|
+
/** Display label: "Initiator", "Owner", "Sponsor", "PM". */
|
|
187
|
+
role: string;
|
|
188
|
+
/** Stakeholder name or "—". */
|
|
108
189
|
name: string;
|
|
109
|
-
date: string;
|
|
110
|
-
/** ArchiMate class label appended by the renderer (§5.1). */
|
|
111
|
-
archimateClass: string;
|
|
112
190
|
x: number;
|
|
113
191
|
y: number;
|
|
114
192
|
width: number;
|
|
115
193
|
height: number;
|
|
116
194
|
}
|
|
117
|
-
/** One node in a
|
|
195
|
+
/** One node in a chain section (driver / assessment / goal / change). */
|
|
118
196
|
export interface ChainNode {
|
|
119
197
|
id: string;
|
|
120
198
|
name: string;
|
|
199
|
+
/** Supplementary text shown below the name (e.g. observed_at date for assessments). */
|
|
200
|
+
meta?: string;
|
|
121
201
|
x: number;
|
|
122
202
|
y: number;
|
|
123
203
|
width: number;
|
|
124
204
|
height: number;
|
|
125
205
|
}
|
|
126
|
-
/** An edge between two chain nodes (
|
|
206
|
+
/** An edge between two chain nodes (for SVG connectors). */
|
|
127
207
|
export interface ChainEdge {
|
|
128
208
|
sourceId: string;
|
|
129
209
|
targetId: string;
|
|
130
210
|
}
|
|
131
|
-
|
|
211
|
+
/**
|
|
212
|
+
* One vertical section of the body chain: Drivers | Assessments | Goals | Changes.
|
|
213
|
+
* When `isEmpty` is true the section has no nodes and renders a gap indicator
|
|
214
|
+
* so the author sees the missing data.
|
|
215
|
+
*/
|
|
216
|
+
export interface ChainSectionLayout {
|
|
217
|
+
type: 'drivers' | 'assessments' | 'goals' | 'changes';
|
|
218
|
+
/** Section header label. */
|
|
219
|
+
label: string;
|
|
220
|
+
/** Short question answered by this section, shown in grey after the label. */
|
|
221
|
+
subtitle: string;
|
|
222
|
+
nodes: ChainNode[];
|
|
223
|
+
isEmpty: boolean;
|
|
224
|
+
x: number;
|
|
225
|
+
y: number;
|
|
226
|
+
width: number;
|
|
227
|
+
height: number;
|
|
228
|
+
}
|
|
229
|
+
/** One milestone marker. */
|
|
230
|
+
export interface MilestoneMarker {
|
|
132
231
|
id: string;
|
|
133
232
|
name: string;
|
|
233
|
+
date: string;
|
|
134
234
|
/** ArchiMate class label appended by the renderer (§5.1). */
|
|
135
235
|
archimateClass: string;
|
|
136
|
-
meta: string;
|
|
137
236
|
x: number;
|
|
138
237
|
y: number;
|
|
139
238
|
width: number;
|
|
140
239
|
height: number;
|
|
141
240
|
}
|
|
142
|
-
|
|
241
|
+
/**
|
|
242
|
+
* A labeled, full-width text row with wrapped value lines.
|
|
243
|
+
* Used for the Description (body) and Notes (footer).
|
|
244
|
+
*/
|
|
245
|
+
export interface InfoRow {
|
|
143
246
|
label: string;
|
|
247
|
+
valueLines: string[];
|
|
248
|
+
x: number;
|
|
249
|
+
y: number;
|
|
250
|
+
width: number;
|
|
251
|
+
height: number;
|
|
252
|
+
}
|
|
253
|
+
export interface ChildActivityRow {
|
|
254
|
+
id: string;
|
|
255
|
+
name: string;
|
|
256
|
+
/** ArchiMate class label appended by the renderer (§5.1). */
|
|
257
|
+
archimateClass: string;
|
|
258
|
+
meta: string;
|
|
144
259
|
x: number;
|
|
145
260
|
y: number;
|
|
146
261
|
width: number;
|
|
@@ -149,27 +264,35 @@ export interface SectionHeader {
|
|
|
149
264
|
export interface ActivityCardLayoutOptions {
|
|
150
265
|
/** Outer card width (px). */
|
|
151
266
|
cardWidth?: number;
|
|
152
|
-
/** Horizontal gap (px) between the three motivation-chain columns. */
|
|
153
|
-
columnGap?: number;
|
|
154
267
|
/** Vertical gap (px) between stacked rows within a section. */
|
|
155
268
|
rowGap?: number;
|
|
156
269
|
}
|
|
157
270
|
export interface ActivityCardLayout {
|
|
158
271
|
bounds: LayoutBounds;
|
|
159
|
-
title
|
|
272
|
+
/** Project name, positioned in the title row. */
|
|
273
|
+
titleRow: {
|
|
160
274
|
name: string;
|
|
161
275
|
x: number;
|
|
162
276
|
y: number;
|
|
163
277
|
};
|
|
278
|
+
/** Activity-type badge (programme / project / workstream / task). Absent when field is unset. */
|
|
279
|
+
activityTypeBadge?: Badge;
|
|
280
|
+
/** Status badge (planned / in_progress / on_track / …). Absent when field is unset. */
|
|
281
|
+
statusBadge?: Badge;
|
|
282
|
+
/** Three date cells: Initiation, Planned start, Planned end. */
|
|
164
283
|
dateFields: DateField[];
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
};
|
|
284
|
+
/** Four role slots always rendered: Initiator, Owner, Sponsor, PM. Name is "—" when unfilled. */
|
|
285
|
+
stakeholderRoleSlots: StakeholderRoleSlot[];
|
|
286
|
+
/** Executive-summary description row. Absent when `cardDescription` is empty. */
|
|
287
|
+
descriptionRow?: InfoRow;
|
|
288
|
+
/** Vertical chain: Drivers → Assessments → Goals → Changes. */
|
|
289
|
+
chainSections: ChainSectionLayout[];
|
|
290
|
+
/** Node-level edges within the chain (driver→assessment, driver→goal, goal→change). */
|
|
173
291
|
chainEdges: ChainEdge[];
|
|
292
|
+
/** Milestone markers below the chain, wrapped left→right by date. */
|
|
293
|
+
milestones: MilestoneMarker[];
|
|
294
|
+
/** Child activities below milestones. */
|
|
174
295
|
childActivities: ChildActivityRow[];
|
|
296
|
+
/** Notes row from `activity_card.notes`. Absent when empty. */
|
|
297
|
+
footerRow?: InfoRow;
|
|
175
298
|
}
|
|
@@ -75,6 +75,9 @@ export function validateActivityCard(input) {
|
|
|
75
75
|
if (card['description'] !== undefined && typeof card['description'] !== 'string') {
|
|
76
76
|
errors.push({ code: 'AC-001', message: 'activity_card.description must be a string' });
|
|
77
77
|
}
|
|
78
|
+
if (card['notes'] !== undefined && typeof card['notes'] !== 'string') {
|
|
79
|
+
errors.push({ code: 'AC-001', message: 'activity_card.notes must be a string' });
|
|
80
|
+
}
|
|
78
81
|
// ── milestones[] (optional) ─────────────────────────────────────────────────
|
|
79
82
|
const milestonesRaw = card['milestones'];
|
|
80
83
|
if (milestonesRaw !== undefined) {
|
|
@@ -3,55 +3,87 @@ import { validateActor } from '../validate.js';
|
|
|
3
3
|
function valid() {
|
|
4
4
|
return {
|
|
5
5
|
notation: 'actor',
|
|
6
|
-
id: 'ACTOR-
|
|
7
|
-
name: '
|
|
8
|
-
type: '
|
|
9
|
-
description: '
|
|
10
|
-
contact: '
|
|
6
|
+
id: 'ACTOR-OPS-1',
|
|
7
|
+
name: 'Operations',
|
|
8
|
+
type: 'business_unit',
|
|
9
|
+
description: 'The operations organisation.',
|
|
10
|
+
contact: 'ops@acme.example',
|
|
11
11
|
zone: 'canon',
|
|
12
12
|
admitted_at: '2026-05-29',
|
|
13
13
|
admitted_by: 'v.korobeinikov',
|
|
14
14
|
gate_checks: { uniqueness: 'pass', consistency: 'pass', completeness: 'pass' },
|
|
15
|
-
valid_from: '
|
|
15
|
+
valid_from: '2024-01-01',
|
|
16
16
|
valid_to: null,
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
const codes = (input) => validateActor(input).errors.map(e => e.code);
|
|
20
20
|
describe('validateActor — positive', () => {
|
|
21
|
-
it('accepts
|
|
21
|
+
it('accepts a well-formed business_unit actor', () => {
|
|
22
22
|
const r = validateActor(valid());
|
|
23
23
|
expect(r.valid, JSON.stringify(r.errors)).toBe(true);
|
|
24
|
-
expect(r.errors).toHaveLength(0);
|
|
25
24
|
});
|
|
26
|
-
it('accepts
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
it('accepts a person actor with no optional fields', () => {
|
|
26
|
+
const a = valid();
|
|
27
|
+
a.id = 'ACTOR-JANE-DOE-1';
|
|
28
|
+
a.name = 'Jane Doe';
|
|
29
|
+
a.type = 'person';
|
|
30
|
+
delete a.description;
|
|
31
|
+
delete a.contact;
|
|
32
|
+
expect(validateActor(a).valid).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
it('accepts a system actor with external_ref', () => {
|
|
35
|
+
const a = valid();
|
|
36
|
+
a.id = 'ACTOR-ORDER-MGMT-SYS-1';
|
|
37
|
+
a.name = 'Order Management System';
|
|
38
|
+
a.type = 'system';
|
|
39
|
+
a.external_ref = 'https://oms.acme.example/api';
|
|
40
|
+
expect(validateActor(a).valid).toBe(true);
|
|
30
41
|
});
|
|
31
42
|
});
|
|
32
|
-
describe('validateActor — ACTOR-001 (
|
|
33
|
-
it('flags a
|
|
34
|
-
|
|
43
|
+
describe('validateActor — ACTOR-001 (shape / id grammar)', () => {
|
|
44
|
+
it('flags a missing required envelope field', () => {
|
|
45
|
+
const a = valid();
|
|
46
|
+
delete a.name;
|
|
47
|
+
expect(codes(a)).toContain('ACTOR-001');
|
|
48
|
+
});
|
|
49
|
+
it('flags an id that violates the grammar', () => {
|
|
50
|
+
expect(codes({ ...valid(), id: 'ACTOR-OPS-001' })).toContain('ACTOR-001');
|
|
51
|
+
expect(codes({ ...valid(), id: 'A-1' })).toContain('ACTOR-001');
|
|
52
|
+
});
|
|
53
|
+
it('flags a wrong notation tag and non-canon zone', () => {
|
|
54
|
+
expect(codes({ ...valid(), notation: 'business_actor' })).toContain('ACTOR-001');
|
|
55
|
+
expect(codes({ ...valid(), zone: 'sandbox' })).toContain('ACTOR-001');
|
|
56
|
+
});
|
|
57
|
+
it('flags a missing type', () => {
|
|
58
|
+
const a = valid();
|
|
59
|
+
delete a.type;
|
|
60
|
+
expect(codes(a)).toContain('ACTOR-001');
|
|
35
61
|
});
|
|
36
|
-
it('flags a
|
|
37
|
-
|
|
62
|
+
it('flags a missing valid_to key', () => {
|
|
63
|
+
const a = valid();
|
|
64
|
+
delete a.valid_to;
|
|
65
|
+
expect(codes(a)).toContain('ACTOR-001');
|
|
38
66
|
});
|
|
39
|
-
it('
|
|
40
|
-
expect(codes(
|
|
67
|
+
it('rejects a non-object', () => {
|
|
68
|
+
expect(codes(null)).toEqual(['ACTOR-001']);
|
|
41
69
|
});
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
expect(codes(
|
|
70
|
+
});
|
|
71
|
+
describe('validateActor — ACTOR-002 (type enum)', () => {
|
|
72
|
+
it('flags a type outside {person, business_unit, system}', () => {
|
|
73
|
+
expect(codes({ ...valid(), type: 'organisation' })).toContain('ACTOR-002');
|
|
46
74
|
});
|
|
47
75
|
});
|
|
48
|
-
describe('validateActor — ACTOR-
|
|
49
|
-
it('flags
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
76
|
+
describe('validateActor — ACTOR-003 (engagement fields forbidden inline)', () => {
|
|
77
|
+
it('flags inline employment', () => {
|
|
78
|
+
expect(codes({ ...valid(), employment: 'REL-EMP-1' })).toContain('ACTOR-003');
|
|
79
|
+
});
|
|
80
|
+
it('flags inline unit_parent', () => {
|
|
81
|
+
expect(codes({ ...valid(), unit_parent: 'ACTOR-PARENT-1' })).toContain('ACTOR-003');
|
|
82
|
+
});
|
|
83
|
+
it('flags inline roles', () => {
|
|
84
|
+
expect(codes({ ...valid(), roles: ['ROLE-OPS-1'] })).toContain('ACTOR-003');
|
|
85
|
+
});
|
|
86
|
+
it('flags inline owner', () => {
|
|
87
|
+
expect(codes({ ...valid(), owner: 'ACTOR-OPS-1' })).toContain('ACTOR-003');
|
|
56
88
|
});
|
|
57
89
|
});
|
package/dist/actor/index.d.ts
CHANGED
package/dist/actor/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { ACTOR_TYPES } from './types.js';
|
|
1
|
+
export { ACTOR_TYPES, ACTOR_FORBIDDEN_INLINE_FIELDS } from './types.js';
|
|
2
2
|
export { validateActor } from './validate.js';
|
package/dist/actor/types.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type { GateChecks } from '../requirement/types.js';
|
|
2
|
-
/** Identity discriminator — what kind of actor (person, business_unit, system). */
|
|
3
|
-
export type ActorType = 'person' | 'business_unit' | 'system';
|
|
4
2
|
export declare const ACTOR_TYPES: readonly ["person", "business_unit", "system"];
|
|
3
|
+
export type ActorType = typeof ACTOR_TYPES[number];
|
|
4
|
+
/**
|
|
5
|
+
* Fields that record engagement / org-hierarchy and therefore MUST NOT appear
|
|
6
|
+
* inline on an ACTOR file (§7.10, ACTOR-003). They belong in time-aware REL
|
|
7
|
+
* records, never on the identity primitive.
|
|
8
|
+
*/
|
|
9
|
+
export declare const ACTOR_FORBIDDEN_INLINE_FIELDS: readonly ["employment", "candidacy", "alumni_membership", "community_membership", "contracting", "unit_parent", "roles", "owner"];
|
|
5
10
|
export interface Actor {
|
|
6
11
|
notation: 'actor';
|
|
7
12
|
id: string;
|
|
8
13
|
name: string;
|
|
9
|
-
/** Required identity discriminator. */
|
|
10
14
|
type: ActorType;
|
|
11
15
|
description?: string;
|
|
12
16
|
contact?: string;
|
package/dist/actor/types.js
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
|
-
// ACTOR —
|
|
2
|
-
// Schema: methodology notations/ELEMENT_PRIMITIVES.md §7.10
|
|
3
|
-
// notations/elements/19-actors.md + envelope §3.
|
|
1
|
+
// ACTOR — active-structure identity primitive (ArchiMate Business Actor).
|
|
2
|
+
// Schema: methodology notations/elements/19-actors.md + ELEMENT_PRIMITIVES.md §7.10.
|
|
4
3
|
export const ACTOR_TYPES = ['person', 'business_unit', 'system'];
|
|
4
|
+
/**
|
|
5
|
+
* Fields that record engagement / org-hierarchy and therefore MUST NOT appear
|
|
6
|
+
* inline on an ACTOR file (§7.10, ACTOR-003). They belong in time-aware REL
|
|
7
|
+
* records, never on the identity primitive.
|
|
8
|
+
*/
|
|
9
|
+
export const ACTOR_FORBIDDEN_INLINE_FIELDS = [
|
|
10
|
+
'employment',
|
|
11
|
+
'candidacy',
|
|
12
|
+
'alumni_membership',
|
|
13
|
+
'community_membership',
|
|
14
|
+
'contracting',
|
|
15
|
+
'unit_parent',
|
|
16
|
+
'roles',
|
|
17
|
+
'owner',
|
|
18
|
+
];
|
package/dist/actor/validate.js
CHANGED
|
@@ -1,34 +1,63 @@
|
|
|
1
|
-
// ACTOR validator — methodology notations/
|
|
2
|
-
// notations/elements/19-actors.md.
|
|
1
|
+
// ACTOR validator — methodology notations/elements/19-actors.md §5.
|
|
3
2
|
//
|
|
4
|
-
// Implements ACTOR-001..
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
import {
|
|
8
|
-
import { ACTOR_TYPES } from './types.js';
|
|
3
|
+
// Implements ACTOR-001..003. The shared HDR-/LIFECYCLE- rules are
|
|
4
|
+
// cross-cutting concerns (CONTRACT.md §8) and out of scope for the
|
|
5
|
+
// single-artefact validator.
|
|
6
|
+
import { isCanonicalIdOfType } from '../typed-id.js';
|
|
7
|
+
import { ACTOR_TYPES, ACTOR_FORBIDDEN_INLINE_FIELDS } from './types.js';
|
|
8
|
+
const REQUIRED_STRING_FIELDS = [
|
|
9
|
+
'name', 'admitted_at', 'admitted_by', 'valid_from',
|
|
10
|
+
];
|
|
11
|
+
const TYPES = ACTOR_TYPES;
|
|
9
12
|
export function validateActor(input) {
|
|
10
13
|
const errors = [];
|
|
11
14
|
const warnings = [];
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
idType: 'ACTOR',
|
|
15
|
-
code: 'ACTOR-001',
|
|
16
|
-
});
|
|
17
|
-
errors.push(...envErrors);
|
|
18
|
-
if (!record)
|
|
15
|
+
if (input === null || typeof input !== 'object' || Array.isArray(input)) {
|
|
16
|
+
errors.push({ code: 'ACTOR-001', message: 'Actor must be a YAML mapping.' });
|
|
19
17
|
return { valid: false, errors, warnings };
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
//
|
|
23
|
-
if (
|
|
24
|
-
errors.push({ code: 'ACTOR-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
errors.push({
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
18
|
+
}
|
|
19
|
+
const a = input;
|
|
20
|
+
// ACTOR-001 — id grammar + notation tag + envelope.
|
|
21
|
+
if (!isCanonicalIdOfType(a.id, 'ACTOR')) {
|
|
22
|
+
errors.push({ code: 'ACTOR-001', message: `id "${String(a.id)}" must match ACTOR-[<middle>-]<INTEGER>.`, path: 'id' });
|
|
23
|
+
}
|
|
24
|
+
if (a.notation !== 'actor') {
|
|
25
|
+
errors.push({ code: 'ACTOR-001', message: 'notation must be the fixed value "actor".', path: 'notation' });
|
|
26
|
+
}
|
|
27
|
+
if (a.zone !== undefined && a.zone !== 'canon') {
|
|
28
|
+
errors.push({ code: 'ACTOR-001', message: 'zone must be "canon" for an ACTOR.', path: 'zone' });
|
|
29
|
+
}
|
|
30
|
+
else if (a.zone === undefined) {
|
|
31
|
+
errors.push({ code: 'ACTOR-001', message: 'zone is required.', path: 'zone' });
|
|
32
|
+
}
|
|
33
|
+
for (const field of REQUIRED_STRING_FIELDS) {
|
|
34
|
+
const v = a[field];
|
|
35
|
+
if (typeof v !== 'string' || v.trim() === '') {
|
|
36
|
+
errors.push({ code: 'ACTOR-001', message: `${field} is required.`, path: field });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (a.gate_checks === null || typeof a.gate_checks !== 'object') {
|
|
40
|
+
errors.push({ code: 'ACTOR-001', message: 'gate_checks is required and must be a mapping.', path: 'gate_checks' });
|
|
41
|
+
}
|
|
42
|
+
if (!('valid_to' in a) || !(typeof a.valid_to === 'string' || a.valid_to === null)) {
|
|
43
|
+
errors.push({ code: 'ACTOR-001', message: 'valid_to is required (an ISO date string or null).', path: 'valid_to' });
|
|
44
|
+
}
|
|
45
|
+
if (typeof a.type !== 'string' || a.type.trim() === '') {
|
|
46
|
+
errors.push({ code: 'ACTOR-001', message: 'type is required.', path: 'type' });
|
|
47
|
+
}
|
|
48
|
+
else if (!TYPES.includes(a.type)) {
|
|
49
|
+
// ACTOR-002 — type enum.
|
|
50
|
+
errors.push({ code: 'ACTOR-002', message: `type "${a.type}" must be one of ${TYPES.join(', ')}.`, path: 'type' });
|
|
51
|
+
}
|
|
52
|
+
// ACTOR-003 — engagement / hierarchy fields belong on REL records, not here.
|
|
53
|
+
for (const field of ACTOR_FORBIDDEN_INLINE_FIELDS) {
|
|
54
|
+
if (field in a) {
|
|
55
|
+
errors.push({
|
|
56
|
+
code: 'ACTOR-003',
|
|
57
|
+
message: `${field} is engagement/hierarchy data — it must live in a REL-… record, not inline on the actor.`,
|
|
58
|
+
path: field,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
32
61
|
}
|
|
33
62
|
return { valid: errors.length === 0, errors, warnings };
|
|
34
63
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { GateChecks } from '../requirement/types.js';
|
|
2
2
|
/** Compliance status vocabulary (16-assertion.md §3). */
|
|
3
|
-
export type AssertionStatus = 'compliant' | 'partial' | 'non_compliant' | 'under_review' | 'n_a';
|
|
3
|
+
export type AssertionStatus = 'compliant' | 'partial' | 'non_compliant' | 'under_review' | 'pending_owner' | 'n_a';
|
|
4
4
|
export declare const ASSERTION_STATUSES: readonly AssertionStatus[];
|
|
5
5
|
/** TYPEs a `subject` may resolve to (16-assertion.md §2, ASSERT-003). */
|
|
6
6
|
export declare const ASSERTION_SUBJECT_TYPES: readonly ["PRODUCT", "PROCESS", "CAPABILITY"];
|
|
@@ -34,6 +34,8 @@ export interface Assertion {
|
|
|
34
34
|
assessed_at?: string;
|
|
35
35
|
assessed_by?: string;
|
|
36
36
|
next_review_at?: string;
|
|
37
|
+
/** ID or name of the party who must confirm this assertion (pending-owner state). */
|
|
38
|
+
owner_to_confirm?: string;
|
|
37
39
|
zone: 'canon';
|
|
38
40
|
admitted_at: string;
|
|
39
41
|
admitted_by: string;
|
package/dist/assertion/types.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ASSERTION — REQUIREMENT realisation claim.
|
|
2
2
|
// Schema: methodology notations/elements/16-assertion.md §2.
|
|
3
3
|
export const ASSERTION_STATUSES = [
|
|
4
|
-
'compliant', 'partial', 'non_compliant', 'under_review', 'n_a',
|
|
4
|
+
'compliant', 'partial', 'non_compliant', 'under_review', 'pending_owner', 'n_a',
|
|
5
5
|
];
|
|
6
6
|
/** TYPEs a `subject` may resolve to (16-assertion.md §2, ASSERT-003). */
|
|
7
7
|
export const ASSERTION_SUBJECT_TYPES = ['PRODUCT', 'PROCESS', 'CAPABILITY'];
|