@nahisaho/musubix-core 1.0.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/bin/musubix.js +18 -0
- package/dist/__tests__/index.test.d.ts +2 -0
- package/dist/__tests__/index.test.d.ts.map +1 -0
- package/dist/__tests__/index.test.js +27 -0
- package/dist/__tests__/index.test.js.map +1 -0
- package/dist/auth/auth-manager.d.ts +320 -0
- package/dist/auth/auth-manager.d.ts.map +1 -0
- package/dist/auth/auth-manager.js +580 -0
- package/dist/auth/auth-manager.js.map +1 -0
- package/dist/cli/base.d.ts +58 -0
- package/dist/cli/base.d.ts.map +1 -0
- package/dist/cli/base.js +93 -0
- package/dist/cli/base.js.map +1 -0
- package/dist/cli/commands/help.d.ts +17 -0
- package/dist/cli/commands/help.d.ts.map +1 -0
- package/dist/cli/commands/help.js +228 -0
- package/dist/cli/commands/help.js.map +1 -0
- package/dist/cli/commands/index.d.ts +14 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +25 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/init.d.ts +38 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +258 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +9 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/codegen/coding-standards.d.ts +250 -0
- package/dist/codegen/coding-standards.d.ts.map +1 -0
- package/dist/codegen/coding-standards.js +976 -0
- package/dist/codegen/coding-standards.js.map +1 -0
- package/dist/codegen/coverage-reporter.d.ts +264 -0
- package/dist/codegen/coverage-reporter.d.ts.map +1 -0
- package/dist/codegen/coverage-reporter.js +697 -0
- package/dist/codegen/coverage-reporter.js.map +1 -0
- package/dist/codegen/dependency-analyzer.d.ts +271 -0
- package/dist/codegen/dependency-analyzer.d.ts.map +1 -0
- package/dist/codegen/dependency-analyzer.js +661 -0
- package/dist/codegen/dependency-analyzer.js.map +1 -0
- package/dist/codegen/generator.d.ts +275 -0
- package/dist/codegen/generator.d.ts.map +1 -0
- package/dist/codegen/generator.js +781 -0
- package/dist/codegen/generator.js.map +1 -0
- package/dist/codegen/index.d.ts +18 -0
- package/dist/codegen/index.d.ts.map +1 -0
- package/dist/codegen/index.js +27 -0
- package/dist/codegen/index.js.map +1 -0
- package/dist/codegen/integration-test-generator.d.ts +312 -0
- package/dist/codegen/integration-test-generator.d.ts.map +1 -0
- package/dist/codegen/integration-test-generator.js +765 -0
- package/dist/codegen/integration-test-generator.js.map +1 -0
- package/dist/codegen/pattern-conformance.d.ts +309 -0
- package/dist/codegen/pattern-conformance.d.ts.map +1 -0
- package/dist/codegen/pattern-conformance.js +590 -0
- package/dist/codegen/pattern-conformance.js.map +1 -0
- package/dist/codegen/quality-metrics.d.ts +235 -0
- package/dist/codegen/quality-metrics.d.ts.map +1 -0
- package/dist/codegen/quality-metrics.js +439 -0
- package/dist/codegen/quality-metrics.js.map +1 -0
- package/dist/codegen/security-scanner.d.ts +179 -0
- package/dist/codegen/security-scanner.d.ts.map +1 -0
- package/dist/codegen/security-scanner.js +495 -0
- package/dist/codegen/security-scanner.js.map +1 -0
- package/dist/codegen/static-analyzer.d.ts +188 -0
- package/dist/codegen/static-analyzer.d.ts.map +1 -0
- package/dist/codegen/static-analyzer.js +490 -0
- package/dist/codegen/static-analyzer.js.map +1 -0
- package/dist/codegen/unit-test-generator.d.ts +289 -0
- package/dist/codegen/unit-test-generator.d.ts.map +1 -0
- package/dist/codegen/unit-test-generator.js +634 -0
- package/dist/codegen/unit-test-generator.js.map +1 -0
- package/dist/design/adr-generator.d.ts +227 -0
- package/dist/design/adr-generator.d.ts.map +1 -0
- package/dist/design/adr-generator.js +423 -0
- package/dist/design/adr-generator.js.map +1 -0
- package/dist/design/c4-generator.d.ts +267 -0
- package/dist/design/c4-generator.d.ts.map +1 -0
- package/dist/design/c4-generator.js +453 -0
- package/dist/design/c4-generator.js.map +1 -0
- package/dist/design/framework-optimizer.d.ts +190 -0
- package/dist/design/framework-optimizer.d.ts.map +1 -0
- package/dist/design/framework-optimizer.js +589 -0
- package/dist/design/framework-optimizer.js.map +1 -0
- package/dist/design/index.d.ts +12 -0
- package/dist/design/index.d.ts.map +1 -0
- package/dist/design/index.js +13 -0
- package/dist/design/index.js.map +1 -0
- package/dist/design/pattern-detector.d.ts +270 -0
- package/dist/design/pattern-detector.d.ts.map +1 -0
- package/dist/design/pattern-detector.js +621 -0
- package/dist/design/pattern-detector.js.map +1 -0
- package/dist/design/solid-validator.d.ts +188 -0
- package/dist/design/solid-validator.d.ts.map +1 -0
- package/dist/design/solid-validator.js +579 -0
- package/dist/design/solid-validator.js.map +1 -0
- package/dist/error/data-persistence.d.ts +311 -0
- package/dist/error/data-persistence.d.ts.map +1 -0
- package/dist/error/data-persistence.js +586 -0
- package/dist/error/data-persistence.js.map +1 -0
- package/dist/error/graceful-degradation.d.ts +309 -0
- package/dist/error/graceful-degradation.d.ts.map +1 -0
- package/dist/error/graceful-degradation.js +510 -0
- package/dist/error/graceful-degradation.js.map +1 -0
- package/dist/error/index.d.ts +11 -0
- package/dist/error/index.d.ts.map +1 -0
- package/dist/error/index.js +19 -0
- package/dist/error/index.js.map +1 -0
- package/dist/explanation/explanation-generator.d.ts +228 -0
- package/dist/explanation/explanation-generator.d.ts.map +1 -0
- package/dist/explanation/explanation-generator.js +662 -0
- package/dist/explanation/explanation-generator.js.map +1 -0
- package/dist/explanation/index.d.ts +11 -0
- package/dist/explanation/index.d.ts.map +1 -0
- package/dist/explanation/index.js +19 -0
- package/dist/explanation/index.js.map +1 -0
- package/dist/explanation/reasoning-chain.d.ts +314 -0
- package/dist/explanation/reasoning-chain.d.ts.map +1 -0
- package/dist/explanation/reasoning-chain.js +414 -0
- package/dist/explanation/reasoning-chain.js.map +1 -0
- package/dist/explanation/visual-explanation.d.ts +315 -0
- package/dist/explanation/visual-explanation.d.ts.map +1 -0
- package/dist/explanation/visual-explanation.js +667 -0
- package/dist/explanation/visual-explanation.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/requirements/decomposer.d.ts +235 -0
- package/dist/requirements/decomposer.d.ts.map +1 -0
- package/dist/requirements/decomposer.js +587 -0
- package/dist/requirements/decomposer.js.map +1 -0
- package/dist/requirements/related-finder.d.ts +261 -0
- package/dist/requirements/related-finder.d.ts.map +1 -0
- package/dist/requirements/related-finder.js +629 -0
- package/dist/requirements/related-finder.js.map +1 -0
- package/dist/traceability/impact.d.ts +196 -0
- package/dist/traceability/impact.d.ts.map +1 -0
- package/dist/traceability/impact.js +438 -0
- package/dist/traceability/impact.js.map +1 -0
- package/dist/traceability/index.d.ts +9 -0
- package/dist/traceability/index.d.ts.map +1 -0
- package/dist/traceability/index.js +10 -0
- package/dist/traceability/index.js.map +1 -0
- package/dist/traceability/manager.d.ts +266 -0
- package/dist/traceability/manager.d.ts.map +1 -0
- package/dist/traceability/manager.js +412 -0
- package/dist/traceability/manager.js.map +1 -0
- package/dist/types/common.d.ts +294 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +15 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/ears.d.ts +158 -0
- package/dist/types/ears.d.ts.map +1 -0
- package/dist/types/ears.js +33 -0
- package/dist/types/ears.js.map +1 -0
- package/dist/types/errors.d.ts +176 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +55 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +10 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/data-protector.d.ts +122 -0
- package/dist/utils/data-protector.d.ts.map +1 -0
- package/dist/utils/data-protector.js +275 -0
- package/dist/utils/data-protector.js.map +1 -0
- package/dist/utils/error-handler.d.ts +101 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +324 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/i18n-manager.d.ts +259 -0
- package/dist/utils/i18n-manager.d.ts.map +1 -0
- package/dist/utils/i18n-manager.js +554 -0
- package/dist/utils/i18n-manager.js.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +10 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +120 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +237 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/performance-profiler.d.ts +251 -0
- package/dist/utils/performance-profiler.d.ts.map +1 -0
- package/dist/utils/performance-profiler.js +458 -0
- package/dist/utils/performance-profiler.js.map +1 -0
- package/dist/utils/scalability-optimizer.d.ts +294 -0
- package/dist/utils/scalability-optimizer.d.ts.map +1 -0
- package/dist/utils/scalability-optimizer.js +606 -0
- package/dist/utils/scalability-optimizer.js.map +1 -0
- package/dist/utils/structured-logger.d.ts +294 -0
- package/dist/utils/structured-logger.d.ts.map +1 -0
- package/dist/utils/structured-logger.js +630 -0
- package/dist/utils/structured-logger.js.map +1 -0
- package/dist/utils/version-compatibility.d.ts +217 -0
- package/dist/utils/version-compatibility.d.ts.map +1 -0
- package/dist/utils/version-compatibility.js +443 -0
- package/dist/utils/version-compatibility.js.map +1 -0
- package/dist/validators/ears-validator.d.ts +182 -0
- package/dist/validators/ears-validator.d.ts.map +1 -0
- package/dist/validators/ears-validator.js +357 -0
- package/dist/validators/ears-validator.js.map +1 -0
- package/dist/validators/index.d.ts +8 -0
- package/dist/validators/index.d.ts.map +1 -0
- package/dist/validators/index.js +9 -0
- package/dist/validators/index.js.map +1 -0
- package/dist/version.d.ts +8 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +8 -0
- package/dist/version.js.map +1 -0
- package/package.json +100 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/traceability/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EAUzB,2BAA2B,GAC5B,MAAM,cAAc,CAAC;AAEtB,mDAAmD;AAEnD,OAAO,EACL,cAAc,EACd,oBAAoB,EAUpB,qBAAqB,GACtB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Traceability Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages bidirectional traceability between requirements, design, and code
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
* @module traceability/manager
|
|
8
|
+
*
|
|
9
|
+
* @see REQ-TRA-001 - Bidirectional Traceability
|
|
10
|
+
* @see Article IV - Traceability Requirements
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Traceable artifact types
|
|
14
|
+
*/
|
|
15
|
+
export type ArtifactType = 'requirement' | 'design' | 'code' | 'test' | 'task' | 'documentation';
|
|
16
|
+
/**
|
|
17
|
+
* Trace link types
|
|
18
|
+
*/
|
|
19
|
+
export type TraceLinkType = 'derives' | 'implements' | 'satisfies' | 'verifies' | 'decomposes' | 'relates' | 'conflicts';
|
|
20
|
+
/**
|
|
21
|
+
* Traceable artifact
|
|
22
|
+
*/
|
|
23
|
+
export interface TraceableArtifact {
|
|
24
|
+
/** Unique identifier */
|
|
25
|
+
id: string;
|
|
26
|
+
/** Artifact type */
|
|
27
|
+
type: ArtifactType;
|
|
28
|
+
/** Display name */
|
|
29
|
+
name: string;
|
|
30
|
+
/** Description */
|
|
31
|
+
description?: string;
|
|
32
|
+
/** Version */
|
|
33
|
+
version?: string;
|
|
34
|
+
/** Status */
|
|
35
|
+
status: ArtifactStatus;
|
|
36
|
+
/** Source file/location */
|
|
37
|
+
source?: {
|
|
38
|
+
file: string;
|
|
39
|
+
line?: number;
|
|
40
|
+
column?: number;
|
|
41
|
+
};
|
|
42
|
+
/** Metadata */
|
|
43
|
+
metadata?: Record<string, unknown>;
|
|
44
|
+
/** Created timestamp */
|
|
45
|
+
createdAt: string;
|
|
46
|
+
/** Updated timestamp */
|
|
47
|
+
updatedAt: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Artifact status
|
|
51
|
+
*/
|
|
52
|
+
export type ArtifactStatus = 'draft' | 'active' | 'deprecated' | 'deleted';
|
|
53
|
+
/**
|
|
54
|
+
* Trace link between artifacts
|
|
55
|
+
*/
|
|
56
|
+
export interface TraceLink {
|
|
57
|
+
/** Link identifier */
|
|
58
|
+
id: string;
|
|
59
|
+
/** Source artifact ID */
|
|
60
|
+
sourceId: string;
|
|
61
|
+
/** Target artifact ID */
|
|
62
|
+
targetId: string;
|
|
63
|
+
/** Link type */
|
|
64
|
+
type: TraceLinkType;
|
|
65
|
+
/** Confidence score (0-1) */
|
|
66
|
+
confidence: number;
|
|
67
|
+
/** Is manually verified */
|
|
68
|
+
verified: boolean;
|
|
69
|
+
/** Rationale for link */
|
|
70
|
+
rationale?: string;
|
|
71
|
+
/** Created by (user/system) */
|
|
72
|
+
createdBy: string;
|
|
73
|
+
/** Created timestamp */
|
|
74
|
+
createdAt: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Traceability matrix entry
|
|
78
|
+
*/
|
|
79
|
+
export interface MatrixEntry {
|
|
80
|
+
/** Requirement ID */
|
|
81
|
+
requirementId: string;
|
|
82
|
+
/** Design artifacts */
|
|
83
|
+
designs: string[];
|
|
84
|
+
/** Code artifacts */
|
|
85
|
+
code: string[];
|
|
86
|
+
/** Test artifacts */
|
|
87
|
+
tests: string[];
|
|
88
|
+
/** Coverage score (0-1) */
|
|
89
|
+
coverage: number;
|
|
90
|
+
/** Status */
|
|
91
|
+
status: 'covered' | 'partial' | 'uncovered';
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Traceability gap
|
|
95
|
+
*/
|
|
96
|
+
export interface TraceabilityGap {
|
|
97
|
+
/** Artifact with gap */
|
|
98
|
+
artifactId: string;
|
|
99
|
+
/** Gap type */
|
|
100
|
+
gapType: 'no-parent' | 'no-child' | 'no-test' | 'no-impl';
|
|
101
|
+
/** Severity */
|
|
102
|
+
severity: 'high' | 'medium' | 'low';
|
|
103
|
+
/** Description */
|
|
104
|
+
description: string;
|
|
105
|
+
/** Suggestions */
|
|
106
|
+
suggestions: string[];
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Traceability report
|
|
110
|
+
*/
|
|
111
|
+
export interface TraceabilityReport {
|
|
112
|
+
/** Generated timestamp */
|
|
113
|
+
generatedAt: string;
|
|
114
|
+
/** Total artifacts */
|
|
115
|
+
totalArtifacts: number;
|
|
116
|
+
/** Total links */
|
|
117
|
+
totalLinks: number;
|
|
118
|
+
/** Coverage statistics */
|
|
119
|
+
coverage: {
|
|
120
|
+
requirements: CoverageStats;
|
|
121
|
+
designs: CoverageStats;
|
|
122
|
+
code: CoverageStats;
|
|
123
|
+
tests: CoverageStats;
|
|
124
|
+
};
|
|
125
|
+
/** Identified gaps */
|
|
126
|
+
gaps: TraceabilityGap[];
|
|
127
|
+
/** Matrix (requirements view) */
|
|
128
|
+
matrix: MatrixEntry[];
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Coverage statistics
|
|
132
|
+
*/
|
|
133
|
+
export interface CoverageStats {
|
|
134
|
+
/** Total items */
|
|
135
|
+
total: number;
|
|
136
|
+
/** Covered items */
|
|
137
|
+
covered: number;
|
|
138
|
+
/** Partial items */
|
|
139
|
+
partial: number;
|
|
140
|
+
/** Uncovered items */
|
|
141
|
+
uncovered: number;
|
|
142
|
+
/** Coverage percentage */
|
|
143
|
+
percentage: number;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Traceability Manager configuration
|
|
147
|
+
*/
|
|
148
|
+
export interface TraceabilityConfig {
|
|
149
|
+
/** Auto-detect links from code comments */
|
|
150
|
+
autoDetect: boolean;
|
|
151
|
+
/** Minimum confidence for auto-detected links */
|
|
152
|
+
autoDetectThreshold: number;
|
|
153
|
+
/** Require verification for links */
|
|
154
|
+
requireVerification: boolean;
|
|
155
|
+
/** Gap detection severity levels */
|
|
156
|
+
gapSeverity: {
|
|
157
|
+
noParent: 'high' | 'medium' | 'low';
|
|
158
|
+
noChild: 'high' | 'medium' | 'low';
|
|
159
|
+
noTest: 'high' | 'medium' | 'low';
|
|
160
|
+
noImpl: 'high' | 'medium' | 'low';
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Default configuration
|
|
165
|
+
*/
|
|
166
|
+
export declare const DEFAULT_TRACEABILITY_CONFIG: TraceabilityConfig;
|
|
167
|
+
/**
|
|
168
|
+
* Traceability Manager
|
|
169
|
+
*
|
|
170
|
+
* Manages artifacts and their trace links
|
|
171
|
+
*/
|
|
172
|
+
export declare class TraceabilityManager {
|
|
173
|
+
private config;
|
|
174
|
+
private artifacts;
|
|
175
|
+
private links;
|
|
176
|
+
private artifactsByType;
|
|
177
|
+
constructor(config?: Partial<TraceabilityConfig>);
|
|
178
|
+
/**
|
|
179
|
+
* Register an artifact
|
|
180
|
+
*/
|
|
181
|
+
registerArtifact(artifact: TraceableArtifact): void;
|
|
182
|
+
/**
|
|
183
|
+
* Register multiple artifacts
|
|
184
|
+
*/
|
|
185
|
+
registerArtifacts(artifacts: TraceableArtifact[]): void;
|
|
186
|
+
/**
|
|
187
|
+
* Get artifact by ID
|
|
188
|
+
*/
|
|
189
|
+
getArtifact(id: string): TraceableArtifact | undefined;
|
|
190
|
+
/**
|
|
191
|
+
* Get artifacts by type
|
|
192
|
+
*/
|
|
193
|
+
getArtifactsByType(type: ArtifactType): TraceableArtifact[];
|
|
194
|
+
/**
|
|
195
|
+
* Create a trace link
|
|
196
|
+
*/
|
|
197
|
+
createLink(sourceId: string, targetId: string, type: TraceLinkType, options?: {
|
|
198
|
+
confidence?: number;
|
|
199
|
+
rationale?: string;
|
|
200
|
+
createdBy?: string;
|
|
201
|
+
verified?: boolean;
|
|
202
|
+
}): TraceLink;
|
|
203
|
+
/**
|
|
204
|
+
* Get links from an artifact
|
|
205
|
+
*/
|
|
206
|
+
getLinksFrom(artifactId: string): TraceLink[];
|
|
207
|
+
/**
|
|
208
|
+
* Get links to an artifact
|
|
209
|
+
*/
|
|
210
|
+
getLinksTo(artifactId: string): TraceLink[];
|
|
211
|
+
/**
|
|
212
|
+
* Get all links for an artifact (both directions)
|
|
213
|
+
*/
|
|
214
|
+
getAllLinks(artifactId: string): TraceLink[];
|
|
215
|
+
/**
|
|
216
|
+
* Find path between two artifacts
|
|
217
|
+
*/
|
|
218
|
+
findPath(fromId: string, toId: string, maxDepth?: number): string[] | null;
|
|
219
|
+
/**
|
|
220
|
+
* Get downstream artifacts (artifacts that depend on this one)
|
|
221
|
+
*/
|
|
222
|
+
getDownstream(artifactId: string): TraceableArtifact[];
|
|
223
|
+
/**
|
|
224
|
+
* Get upstream artifacts (artifacts this one depends on)
|
|
225
|
+
*/
|
|
226
|
+
getUpstream(artifactId: string): TraceableArtifact[];
|
|
227
|
+
/**
|
|
228
|
+
* Generate traceability matrix
|
|
229
|
+
*/
|
|
230
|
+
generateMatrix(): MatrixEntry[];
|
|
231
|
+
/**
|
|
232
|
+
* Detect traceability gaps
|
|
233
|
+
*/
|
|
234
|
+
detectGaps(): TraceabilityGap[];
|
|
235
|
+
/**
|
|
236
|
+
* Generate traceability report
|
|
237
|
+
*/
|
|
238
|
+
generateReport(): TraceabilityReport;
|
|
239
|
+
/**
|
|
240
|
+
* Auto-detect links from code annotations
|
|
241
|
+
*/
|
|
242
|
+
autoDetectLinks(codeContent: string, codeArtifactId: string): TraceLink[];
|
|
243
|
+
/**
|
|
244
|
+
* Export to JSON
|
|
245
|
+
*/
|
|
246
|
+
toJSON(): {
|
|
247
|
+
artifacts: TraceableArtifact[];
|
|
248
|
+
links: TraceLink[];
|
|
249
|
+
};
|
|
250
|
+
/**
|
|
251
|
+
* Import from JSON
|
|
252
|
+
*/
|
|
253
|
+
fromJSON(data: {
|
|
254
|
+
artifacts: TraceableArtifact[];
|
|
255
|
+
links: TraceLink[];
|
|
256
|
+
}): void;
|
|
257
|
+
/**
|
|
258
|
+
* Clear all data
|
|
259
|
+
*/
|
|
260
|
+
clear(): void;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Create traceability manager instance
|
|
264
|
+
*/
|
|
265
|
+
export declare function createTraceabilityManager(config?: Partial<TraceabilityConfig>): TraceabilityManager;
|
|
266
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/traceability/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Traceability Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages bidirectional traceability between requirements, design, and code
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
* @module traceability/manager
|
|
8
|
+
*
|
|
9
|
+
* @see REQ-TRA-001 - Bidirectional Traceability
|
|
10
|
+
* @see Article IV - Traceability Requirements
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Default configuration
|
|
14
|
+
*/
|
|
15
|
+
export const DEFAULT_TRACEABILITY_CONFIG = {
|
|
16
|
+
autoDetect: true,
|
|
17
|
+
autoDetectThreshold: 0.7,
|
|
18
|
+
requireVerification: false,
|
|
19
|
+
gapSeverity: {
|
|
20
|
+
noParent: 'low',
|
|
21
|
+
noChild: 'medium',
|
|
22
|
+
noTest: 'high',
|
|
23
|
+
noImpl: 'high',
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Traceability Manager
|
|
28
|
+
*
|
|
29
|
+
* Manages artifacts and their trace links
|
|
30
|
+
*/
|
|
31
|
+
export class TraceabilityManager {
|
|
32
|
+
config;
|
|
33
|
+
artifacts = new Map();
|
|
34
|
+
links = new Map();
|
|
35
|
+
artifactsByType = new Map();
|
|
36
|
+
constructor(config) {
|
|
37
|
+
this.config = { ...DEFAULT_TRACEABILITY_CONFIG, ...config };
|
|
38
|
+
// Initialize type index
|
|
39
|
+
const types = ['requirement', 'design', 'code', 'test', 'task', 'documentation'];
|
|
40
|
+
for (const type of types) {
|
|
41
|
+
this.artifactsByType.set(type, new Set());
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Register an artifact
|
|
46
|
+
*/
|
|
47
|
+
registerArtifact(artifact) {
|
|
48
|
+
this.artifacts.set(artifact.id, artifact);
|
|
49
|
+
this.artifactsByType.get(artifact.type)?.add(artifact.id);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Register multiple artifacts
|
|
53
|
+
*/
|
|
54
|
+
registerArtifacts(artifacts) {
|
|
55
|
+
for (const artifact of artifacts) {
|
|
56
|
+
this.registerArtifact(artifact);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get artifact by ID
|
|
61
|
+
*/
|
|
62
|
+
getArtifact(id) {
|
|
63
|
+
return this.artifacts.get(id);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get artifacts by type
|
|
67
|
+
*/
|
|
68
|
+
getArtifactsByType(type) {
|
|
69
|
+
const ids = this.artifactsByType.get(type) ?? new Set();
|
|
70
|
+
return Array.from(ids)
|
|
71
|
+
.map((id) => this.artifacts.get(id))
|
|
72
|
+
.filter((a) => a !== undefined);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create a trace link
|
|
76
|
+
*/
|
|
77
|
+
createLink(sourceId, targetId, type, options) {
|
|
78
|
+
const source = this.artifacts.get(sourceId);
|
|
79
|
+
const target = this.artifacts.get(targetId);
|
|
80
|
+
if (!source) {
|
|
81
|
+
throw new Error(`Source artifact not found: ${sourceId}`);
|
|
82
|
+
}
|
|
83
|
+
if (!target) {
|
|
84
|
+
throw new Error(`Target artifact not found: ${targetId}`);
|
|
85
|
+
}
|
|
86
|
+
const link = {
|
|
87
|
+
id: `${sourceId}-${type}-${targetId}`,
|
|
88
|
+
sourceId,
|
|
89
|
+
targetId,
|
|
90
|
+
type,
|
|
91
|
+
confidence: options?.confidence ?? 1.0,
|
|
92
|
+
verified: options?.verified ?? !this.config.requireVerification,
|
|
93
|
+
rationale: options?.rationale,
|
|
94
|
+
createdBy: options?.createdBy ?? 'system',
|
|
95
|
+
createdAt: new Date().toISOString(),
|
|
96
|
+
};
|
|
97
|
+
this.links.set(link.id, link);
|
|
98
|
+
return link;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get links from an artifact
|
|
102
|
+
*/
|
|
103
|
+
getLinksFrom(artifactId) {
|
|
104
|
+
return Array.from(this.links.values())
|
|
105
|
+
.filter((link) => link.sourceId === artifactId);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get links to an artifact
|
|
109
|
+
*/
|
|
110
|
+
getLinksTo(artifactId) {
|
|
111
|
+
return Array.from(this.links.values())
|
|
112
|
+
.filter((link) => link.targetId === artifactId);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get all links for an artifact (both directions)
|
|
116
|
+
*/
|
|
117
|
+
getAllLinks(artifactId) {
|
|
118
|
+
return Array.from(this.links.values())
|
|
119
|
+
.filter((link) => link.sourceId === artifactId || link.targetId === artifactId);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Find path between two artifacts
|
|
123
|
+
*/
|
|
124
|
+
findPath(fromId, toId, maxDepth = 5) {
|
|
125
|
+
const visited = new Set();
|
|
126
|
+
const queue = [
|
|
127
|
+
{ id: fromId, path: [fromId] },
|
|
128
|
+
];
|
|
129
|
+
while (queue.length > 0) {
|
|
130
|
+
const { id, path } = queue.shift();
|
|
131
|
+
if (id === toId) {
|
|
132
|
+
return path;
|
|
133
|
+
}
|
|
134
|
+
if (path.length >= maxDepth || visited.has(id)) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
visited.add(id);
|
|
138
|
+
// Get connected artifacts
|
|
139
|
+
const links = this.getAllLinks(id);
|
|
140
|
+
for (const link of links) {
|
|
141
|
+
const nextId = link.sourceId === id ? link.targetId : link.sourceId;
|
|
142
|
+
if (!visited.has(nextId)) {
|
|
143
|
+
queue.push({ id: nextId, path: [...path, nextId] });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get downstream artifacts (artifacts that depend on this one)
|
|
151
|
+
*/
|
|
152
|
+
getDownstream(artifactId) {
|
|
153
|
+
const downstream = new Set();
|
|
154
|
+
const queue = [artifactId];
|
|
155
|
+
while (queue.length > 0) {
|
|
156
|
+
const current = queue.shift();
|
|
157
|
+
const links = this.getLinksFrom(current);
|
|
158
|
+
for (const link of links) {
|
|
159
|
+
if (!downstream.has(link.targetId)) {
|
|
160
|
+
downstream.add(link.targetId);
|
|
161
|
+
queue.push(link.targetId);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return Array.from(downstream)
|
|
166
|
+
.map((id) => this.artifacts.get(id))
|
|
167
|
+
.filter((a) => a !== undefined);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get upstream artifacts (artifacts this one depends on)
|
|
171
|
+
*/
|
|
172
|
+
getUpstream(artifactId) {
|
|
173
|
+
const upstream = new Set();
|
|
174
|
+
const queue = [artifactId];
|
|
175
|
+
while (queue.length > 0) {
|
|
176
|
+
const current = queue.shift();
|
|
177
|
+
const links = this.getLinksTo(current);
|
|
178
|
+
for (const link of links) {
|
|
179
|
+
if (!upstream.has(link.sourceId)) {
|
|
180
|
+
upstream.add(link.sourceId);
|
|
181
|
+
queue.push(link.sourceId);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return Array.from(upstream)
|
|
186
|
+
.map((id) => this.artifacts.get(id))
|
|
187
|
+
.filter((a) => a !== undefined);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Generate traceability matrix
|
|
191
|
+
*/
|
|
192
|
+
generateMatrix() {
|
|
193
|
+
const requirements = this.getArtifactsByType('requirement');
|
|
194
|
+
const matrix = [];
|
|
195
|
+
for (const req of requirements) {
|
|
196
|
+
const downstream = this.getDownstream(req.id);
|
|
197
|
+
const designs = downstream
|
|
198
|
+
.filter((a) => a.type === 'design')
|
|
199
|
+
.map((a) => a.id);
|
|
200
|
+
const code = downstream
|
|
201
|
+
.filter((a) => a.type === 'code')
|
|
202
|
+
.map((a) => a.id);
|
|
203
|
+
const tests = downstream
|
|
204
|
+
.filter((a) => a.type === 'test')
|
|
205
|
+
.map((a) => a.id);
|
|
206
|
+
// Calculate coverage
|
|
207
|
+
let coverage = 0;
|
|
208
|
+
if (designs.length > 0)
|
|
209
|
+
coverage += 0.3;
|
|
210
|
+
if (code.length > 0)
|
|
211
|
+
coverage += 0.4;
|
|
212
|
+
if (tests.length > 0)
|
|
213
|
+
coverage += 0.3;
|
|
214
|
+
matrix.push({
|
|
215
|
+
requirementId: req.id,
|
|
216
|
+
designs,
|
|
217
|
+
code,
|
|
218
|
+
tests,
|
|
219
|
+
coverage,
|
|
220
|
+
status: coverage >= 0.9 ? 'covered' : coverage > 0 ? 'partial' : 'uncovered',
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
return matrix;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Detect traceability gaps
|
|
227
|
+
*/
|
|
228
|
+
detectGaps() {
|
|
229
|
+
const gaps = [];
|
|
230
|
+
// Check requirements
|
|
231
|
+
for (const req of this.getArtifactsByType('requirement')) {
|
|
232
|
+
// No downstream links
|
|
233
|
+
if (this.getLinksFrom(req.id).length === 0) {
|
|
234
|
+
gaps.push({
|
|
235
|
+
artifactId: req.id,
|
|
236
|
+
gapType: 'no-child',
|
|
237
|
+
severity: this.config.gapSeverity.noChild,
|
|
238
|
+
description: `Requirement ${req.id} has no implementing artifacts`,
|
|
239
|
+
suggestions: [
|
|
240
|
+
'Create design elements that satisfy this requirement',
|
|
241
|
+
'Link existing design or code to this requirement',
|
|
242
|
+
],
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
// No test coverage
|
|
246
|
+
const downstream = this.getDownstream(req.id);
|
|
247
|
+
const hasTest = downstream.some((a) => a.type === 'test');
|
|
248
|
+
if (!hasTest) {
|
|
249
|
+
gaps.push({
|
|
250
|
+
artifactId: req.id,
|
|
251
|
+
gapType: 'no-test',
|
|
252
|
+
severity: this.config.gapSeverity.noTest,
|
|
253
|
+
description: `Requirement ${req.id} has no test coverage`,
|
|
254
|
+
suggestions: [
|
|
255
|
+
'Create tests that verify this requirement',
|
|
256
|
+
'Link existing tests to this requirement chain',
|
|
257
|
+
],
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// Check code artifacts
|
|
262
|
+
for (const code of this.getArtifactsByType('code')) {
|
|
263
|
+
const upstream = this.getLinksTo(code.id);
|
|
264
|
+
if (upstream.length === 0) {
|
|
265
|
+
gaps.push({
|
|
266
|
+
artifactId: code.id,
|
|
267
|
+
gapType: 'no-parent',
|
|
268
|
+
severity: this.config.gapSeverity.noParent,
|
|
269
|
+
description: `Code ${code.id} is not linked to any requirement`,
|
|
270
|
+
suggestions: [
|
|
271
|
+
'Link this code to a requirement it implements',
|
|
272
|
+
'Create a requirement for this functionality',
|
|
273
|
+
],
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// Check designs without implementation
|
|
278
|
+
for (const design of this.getArtifactsByType('design')) {
|
|
279
|
+
const downstream = this.getDownstream(design.id);
|
|
280
|
+
const hasImpl = downstream.some((a) => a.type === 'code');
|
|
281
|
+
if (!hasImpl) {
|
|
282
|
+
gaps.push({
|
|
283
|
+
artifactId: design.id,
|
|
284
|
+
gapType: 'no-impl',
|
|
285
|
+
severity: this.config.gapSeverity.noImpl,
|
|
286
|
+
description: `Design ${design.id} has no implementation`,
|
|
287
|
+
suggestions: [
|
|
288
|
+
'Implement this design in code',
|
|
289
|
+
'Link existing code to this design',
|
|
290
|
+
],
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return gaps;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Generate traceability report
|
|
298
|
+
*/
|
|
299
|
+
generateReport() {
|
|
300
|
+
const matrix = this.generateMatrix();
|
|
301
|
+
const gaps = this.detectGaps();
|
|
302
|
+
const calculateStats = (type) => {
|
|
303
|
+
const artifacts = this.getArtifactsByType(type);
|
|
304
|
+
let covered = 0;
|
|
305
|
+
let partial = 0;
|
|
306
|
+
for (const artifact of artifacts) {
|
|
307
|
+
const links = this.getAllLinks(artifact.id);
|
|
308
|
+
if (links.length > 1) {
|
|
309
|
+
covered++;
|
|
310
|
+
}
|
|
311
|
+
else if (links.length === 1) {
|
|
312
|
+
partial++;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
const total = artifacts.length;
|
|
316
|
+
return {
|
|
317
|
+
total,
|
|
318
|
+
covered,
|
|
319
|
+
partial,
|
|
320
|
+
uncovered: total - covered - partial,
|
|
321
|
+
percentage: total > 0 ? ((covered + partial * 0.5) / total) * 100 : 0,
|
|
322
|
+
};
|
|
323
|
+
};
|
|
324
|
+
return {
|
|
325
|
+
generatedAt: new Date().toISOString(),
|
|
326
|
+
totalArtifacts: this.artifacts.size,
|
|
327
|
+
totalLinks: this.links.size,
|
|
328
|
+
coverage: {
|
|
329
|
+
requirements: calculateStats('requirement'),
|
|
330
|
+
designs: calculateStats('design'),
|
|
331
|
+
code: calculateStats('code'),
|
|
332
|
+
tests: calculateStats('test'),
|
|
333
|
+
},
|
|
334
|
+
gaps,
|
|
335
|
+
matrix,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Auto-detect links from code annotations
|
|
340
|
+
*/
|
|
341
|
+
autoDetectLinks(codeContent, codeArtifactId) {
|
|
342
|
+
if (!this.config.autoDetect) {
|
|
343
|
+
return [];
|
|
344
|
+
}
|
|
345
|
+
const detectedLinks = [];
|
|
346
|
+
// Pattern: @see REQ-XXX, @implements REQ-XXX, @satisfies DES-XXX
|
|
347
|
+
const patterns = [
|
|
348
|
+
{ regex: /@see\s+(REQ-\w+)/gi, type: 'relates' },
|
|
349
|
+
{ regex: /@implements\s+(REQ-\w+)/gi, type: 'implements' },
|
|
350
|
+
{ regex: /@satisfies\s+(DES-\w+)/gi, type: 'satisfies' },
|
|
351
|
+
{ regex: /@verifies\s+(REQ-\w+)/gi, type: 'verifies' },
|
|
352
|
+
];
|
|
353
|
+
for (const { regex, type } of patterns) {
|
|
354
|
+
let match;
|
|
355
|
+
while ((match = regex.exec(codeContent)) !== null) {
|
|
356
|
+
const targetId = match[1];
|
|
357
|
+
if (this.artifacts.has(targetId)) {
|
|
358
|
+
try {
|
|
359
|
+
const link = this.createLink(codeArtifactId, targetId, type, {
|
|
360
|
+
confidence: this.config.autoDetectThreshold,
|
|
361
|
+
rationale: 'Auto-detected from code annotation',
|
|
362
|
+
createdBy: 'auto-detect',
|
|
363
|
+
verified: false,
|
|
364
|
+
});
|
|
365
|
+
detectedLinks.push(link);
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
// Link creation failed (e.g., duplicate)
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return detectedLinks;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Export to JSON
|
|
377
|
+
*/
|
|
378
|
+
toJSON() {
|
|
379
|
+
return {
|
|
380
|
+
artifacts: Array.from(this.artifacts.values()),
|
|
381
|
+
links: Array.from(this.links.values()),
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Import from JSON
|
|
386
|
+
*/
|
|
387
|
+
fromJSON(data) {
|
|
388
|
+
for (const artifact of data.artifacts) {
|
|
389
|
+
this.registerArtifact(artifact);
|
|
390
|
+
}
|
|
391
|
+
for (const link of data.links) {
|
|
392
|
+
this.links.set(link.id, link);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Clear all data
|
|
397
|
+
*/
|
|
398
|
+
clear() {
|
|
399
|
+
this.artifacts.clear();
|
|
400
|
+
this.links.clear();
|
|
401
|
+
for (const set of this.artifactsByType.values()) {
|
|
402
|
+
set.clear();
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Create traceability manager instance
|
|
408
|
+
*/
|
|
409
|
+
export function createTraceabilityManager(config) {
|
|
410
|
+
return new TraceabilityManager(config);
|
|
411
|
+
}
|
|
412
|
+
//# sourceMappingURL=manager.js.map
|