@girardelli/architect 1.1.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/CONTRIBUTING.md +140 -0
- package/LICENSE +21 -0
- package/PROJECT_STRUCTURE.txt +168 -0
- package/README.md +269 -0
- package/dist/analyzer.d.ts +17 -0
- package/dist/analyzer.d.ts.map +1 -0
- package/dist/analyzer.js +254 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/anti-patterns.d.ts +17 -0
- package/dist/anti-patterns.d.ts.map +1 -0
- package/dist/anti-patterns.js +211 -0
- package/dist/anti-patterns.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +164 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +73 -0
- package/dist/config.js.map +1 -0
- package/dist/diagram.d.ts +9 -0
- package/dist/diagram.d.ts.map +1 -0
- package/dist/diagram.js +116 -0
- package/dist/diagram.js.map +1 -0
- package/dist/html-reporter.d.ts +23 -0
- package/dist/html-reporter.d.ts.map +1 -0
- package/dist/html-reporter.js +454 -0
- package/dist/html-reporter.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +151 -0
- package/dist/index.js.map +1 -0
- package/dist/reporter.d.ts +13 -0
- package/dist/reporter.d.ts.map +1 -0
- package/dist/reporter.js +135 -0
- package/dist/reporter.js.map +1 -0
- package/dist/scanner.d.ts +25 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +288 -0
- package/dist/scanner.js.map +1 -0
- package/dist/scorer.d.ts +15 -0
- package/dist/scorer.d.ts.map +1 -0
- package/dist/scorer.js +172 -0
- package/dist/scorer.js.map +1 -0
- package/dist/types.d.ts +106 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/examples/sample-report.md +207 -0
- package/jest.config.js +18 -0
- package/package.json +70 -0
- package/src/analyzer.ts +310 -0
- package/src/anti-patterns.ts +264 -0
- package/src/cli.ts +183 -0
- package/src/config.ts +82 -0
- package/src/diagram.ts +144 -0
- package/src/html-reporter.ts +485 -0
- package/src/index.ts +212 -0
- package/src/reporter.ts +166 -0
- package/src/scanner.ts +298 -0
- package/src/scorer.ts +193 -0
- package/src/types.ts +114 -0
- package/tests/anti-patterns.test.ts +94 -0
- package/tests/scanner.test.ts +55 -0
- package/tests/scorer.test.ts +80 -0
- package/tsconfig.json +24 -0
package/dist/scorer.js
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
export class ArchitectureScorer {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.modularity = 0;
|
|
4
|
+
this.coupling = 0;
|
|
5
|
+
this.cohesion = 0;
|
|
6
|
+
this.layering = 0;
|
|
7
|
+
}
|
|
8
|
+
score(edges, antiPatterns, totalFiles) {
|
|
9
|
+
this.calculateModularity(edges, totalFiles);
|
|
10
|
+
this.calculateCoupling(edges, totalFiles);
|
|
11
|
+
this.calculateCohesion(edges);
|
|
12
|
+
this.calculateLayering(antiPatterns);
|
|
13
|
+
const components = [
|
|
14
|
+
{
|
|
15
|
+
name: 'Modularity',
|
|
16
|
+
score: Math.round(this.modularity),
|
|
17
|
+
maxScore: 100,
|
|
18
|
+
weight: 0.4,
|
|
19
|
+
explanation: 'Measures appropriate module boundaries and single responsibility principle adherence',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'Coupling',
|
|
23
|
+
score: Math.round(this.coupling),
|
|
24
|
+
maxScore: 100,
|
|
25
|
+
weight: 0.25,
|
|
26
|
+
explanation: 'Evaluates interdependencies between modules; lower coupling is better',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'Cohesion',
|
|
30
|
+
score: Math.round(this.cohesion),
|
|
31
|
+
maxScore: 100,
|
|
32
|
+
weight: 0.2,
|
|
33
|
+
explanation: 'Assesses how closely related functionality is grouped together',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'Layering',
|
|
37
|
+
score: Math.round(this.layering),
|
|
38
|
+
maxScore: 100,
|
|
39
|
+
weight: 0.15,
|
|
40
|
+
explanation: 'Checks adherence to architectural layer separation',
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
const overall = Math.round(components[0].score * components[0].weight +
|
|
44
|
+
components[1].score * components[1].weight +
|
|
45
|
+
components[2].score * components[2].weight +
|
|
46
|
+
components[3].score * components[3].weight);
|
|
47
|
+
return {
|
|
48
|
+
overall: Math.min(100, Math.max(0, overall)),
|
|
49
|
+
components,
|
|
50
|
+
breakdown: {
|
|
51
|
+
modularity: Math.round(this.modularity),
|
|
52
|
+
coupling: Math.round(this.coupling),
|
|
53
|
+
cohesion: Math.round(this.cohesion),
|
|
54
|
+
layering: Math.round(this.layering),
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
calculateModularity(edges, totalFiles) {
|
|
59
|
+
if (totalFiles === 0) {
|
|
60
|
+
this.modularity = 50;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const avgEdgesPerFile = edges.length / totalFiles;
|
|
64
|
+
if (avgEdgesPerFile < 2) {
|
|
65
|
+
this.modularity = 95;
|
|
66
|
+
}
|
|
67
|
+
else if (avgEdgesPerFile < 4) {
|
|
68
|
+
this.modularity = 85;
|
|
69
|
+
}
|
|
70
|
+
else if (avgEdgesPerFile < 6) {
|
|
71
|
+
this.modularity = 70;
|
|
72
|
+
}
|
|
73
|
+
else if (avgEdgesPerFile < 10) {
|
|
74
|
+
this.modularity = 50;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
this.modularity = 30;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
calculateCoupling(edges, totalFiles) {
|
|
81
|
+
if (totalFiles === 0) {
|
|
82
|
+
this.coupling = 50;
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const nodeWithMaxEdges = this.findNodeWithMaxEdges(edges);
|
|
86
|
+
const maxEdgeCount = nodeWithMaxEdges ? nodeWithMaxEdges.count : 0;
|
|
87
|
+
const couplingRatio = maxEdgeCount / (totalFiles - 1);
|
|
88
|
+
if (couplingRatio < 0.2) {
|
|
89
|
+
this.coupling = 95;
|
|
90
|
+
}
|
|
91
|
+
else if (couplingRatio < 0.4) {
|
|
92
|
+
this.coupling = 85;
|
|
93
|
+
}
|
|
94
|
+
else if (couplingRatio < 0.6) {
|
|
95
|
+
this.coupling = 70;
|
|
96
|
+
}
|
|
97
|
+
else if (couplingRatio < 0.8) {
|
|
98
|
+
this.coupling = 50;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.coupling = 30;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
findNodeWithMaxEdges(edges) {
|
|
105
|
+
const nodeEdgeCount = {};
|
|
106
|
+
for (const edge of edges) {
|
|
107
|
+
nodeEdgeCount[edge.from] = (nodeEdgeCount[edge.from] || 0) + 1;
|
|
108
|
+
nodeEdgeCount[edge.to] = (nodeEdgeCount[edge.to] || 0) + 1;
|
|
109
|
+
}
|
|
110
|
+
let maxNode = null;
|
|
111
|
+
let maxCount = 0;
|
|
112
|
+
for (const [node, count] of Object.entries(nodeEdgeCount)) {
|
|
113
|
+
if (count > maxCount) {
|
|
114
|
+
maxCount = count;
|
|
115
|
+
maxNode = node;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return maxNode ? { node: maxNode, count: maxCount } : null;
|
|
119
|
+
}
|
|
120
|
+
calculateCohesion(edges) {
|
|
121
|
+
if (edges.length === 0) {
|
|
122
|
+
this.cohesion = 50;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const internalEdges = edges.filter((e) => this.isInternalDependency(e.from, e.to)).length;
|
|
126
|
+
const cohesionRatio = internalEdges / edges.length;
|
|
127
|
+
if (cohesionRatio > 0.7) {
|
|
128
|
+
this.cohesion = 95;
|
|
129
|
+
}
|
|
130
|
+
else if (cohesionRatio > 0.5) {
|
|
131
|
+
this.cohesion = 80;
|
|
132
|
+
}
|
|
133
|
+
else if (cohesionRatio > 0.3) {
|
|
134
|
+
this.cohesion = 65;
|
|
135
|
+
}
|
|
136
|
+
else if (cohesionRatio > 0.1) {
|
|
137
|
+
this.cohesion = 45;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.cohesion = 30;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
isInternalDependency(from, to) {
|
|
144
|
+
const fromModule = from.split('/').slice(0, -1).join('/');
|
|
145
|
+
const toModule = to.split('/').slice(0, -1).join('/');
|
|
146
|
+
return fromModule === toModule;
|
|
147
|
+
}
|
|
148
|
+
calculateLayering(antiPatterns) {
|
|
149
|
+
const layeringViolations = antiPatterns.filter((p) => p.name === 'Leaky Abstraction' ||
|
|
150
|
+
p.name === 'Shotgun Surgery' ||
|
|
151
|
+
p.name === 'Circular Dependency').length;
|
|
152
|
+
if (layeringViolations === 0) {
|
|
153
|
+
this.layering = 95;
|
|
154
|
+
}
|
|
155
|
+
else if (layeringViolations === 1) {
|
|
156
|
+
this.layering = 85;
|
|
157
|
+
}
|
|
158
|
+
else if (layeringViolations === 2) {
|
|
159
|
+
this.layering = 70;
|
|
160
|
+
}
|
|
161
|
+
else if (layeringViolations === 3) {
|
|
162
|
+
this.layering = 55;
|
|
163
|
+
}
|
|
164
|
+
else if (layeringViolations <= 5) {
|
|
165
|
+
this.layering = 40;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
this.layering = 25;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=scorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scorer.js","sourceRoot":"","sources":["../src/scorer.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export interface FileNode {
|
|
2
|
+
path: string;
|
|
3
|
+
name: string;
|
|
4
|
+
type: 'file' | 'directory';
|
|
5
|
+
extension?: string;
|
|
6
|
+
lines?: number;
|
|
7
|
+
language?: string;
|
|
8
|
+
children?: FileNode[];
|
|
9
|
+
imports?: string[];
|
|
10
|
+
exports?: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface DependencyEdge {
|
|
13
|
+
from: string;
|
|
14
|
+
to: string;
|
|
15
|
+
type: 'import' | 'export' | 'inheritance' | 'composition';
|
|
16
|
+
weight: number;
|
|
17
|
+
}
|
|
18
|
+
export interface Layer {
|
|
19
|
+
name: 'API' | 'Service' | 'Data' | 'UI' | 'Infrastructure';
|
|
20
|
+
files: string[];
|
|
21
|
+
description: string;
|
|
22
|
+
}
|
|
23
|
+
export interface AntiPattern {
|
|
24
|
+
name: string;
|
|
25
|
+
severity: 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
|
|
26
|
+
location: string;
|
|
27
|
+
description: string;
|
|
28
|
+
suggestion: string;
|
|
29
|
+
affectedFiles?: string[];
|
|
30
|
+
metrics?: Record<string, number | string>;
|
|
31
|
+
}
|
|
32
|
+
export interface ScoreComponent {
|
|
33
|
+
name: string;
|
|
34
|
+
score: number;
|
|
35
|
+
maxScore: number;
|
|
36
|
+
weight: number;
|
|
37
|
+
explanation: string;
|
|
38
|
+
}
|
|
39
|
+
export interface ArchitectureScore {
|
|
40
|
+
overall: number;
|
|
41
|
+
components: ScoreComponent[];
|
|
42
|
+
breakdown: {
|
|
43
|
+
modularity: number;
|
|
44
|
+
coupling: number;
|
|
45
|
+
cohesion: number;
|
|
46
|
+
layering: number;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export interface ProjectInfo {
|
|
50
|
+
path: string;
|
|
51
|
+
name: string;
|
|
52
|
+
frameworks: string[];
|
|
53
|
+
totalFiles: number;
|
|
54
|
+
totalLines: number;
|
|
55
|
+
primaryLanguages: string[];
|
|
56
|
+
fileTree?: FileNode;
|
|
57
|
+
}
|
|
58
|
+
export interface AnalysisReport {
|
|
59
|
+
timestamp: string;
|
|
60
|
+
projectInfo: ProjectInfo;
|
|
61
|
+
score: ArchitectureScore;
|
|
62
|
+
antiPatterns: AntiPattern[];
|
|
63
|
+
layers: Layer[];
|
|
64
|
+
dependencyGraph: {
|
|
65
|
+
nodes: string[];
|
|
66
|
+
edges: DependencyEdge[];
|
|
67
|
+
};
|
|
68
|
+
suggestions: {
|
|
69
|
+
priority: 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
|
|
70
|
+
title: string;
|
|
71
|
+
description: string;
|
|
72
|
+
impact: string;
|
|
73
|
+
}[];
|
|
74
|
+
diagram: {
|
|
75
|
+
mermaid: string;
|
|
76
|
+
type: 'component' | 'layer' | 'dependency';
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export interface ArchitectConfig {
|
|
80
|
+
ignore?: string[];
|
|
81
|
+
frameworks?: {
|
|
82
|
+
detect?: boolean;
|
|
83
|
+
};
|
|
84
|
+
antiPatterns?: {
|
|
85
|
+
godClass?: {
|
|
86
|
+
linesThreshold?: number;
|
|
87
|
+
methodsThreshold?: number;
|
|
88
|
+
};
|
|
89
|
+
shotgunSurgery?: {
|
|
90
|
+
changePropagationThreshold?: number;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
score?: {
|
|
94
|
+
modularity?: number;
|
|
95
|
+
coupling?: number;
|
|
96
|
+
cohesion?: number;
|
|
97
|
+
layering?: number;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export interface ParsedImport {
|
|
101
|
+
source: string;
|
|
102
|
+
names: string[];
|
|
103
|
+
isDefault: boolean;
|
|
104
|
+
isNamespace: boolean;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Architecture Analysis Report
|
|
2
|
+
|
|
3
|
+
Generated: 2026-03-15 14:23:45
|
|
4
|
+
Project: ecommerce-api
|
|
5
|
+
Path: /projects/ecommerce-api
|
|
6
|
+
|
|
7
|
+
## Project Summary
|
|
8
|
+
|
|
9
|
+
| Metric | Value |
|
|
10
|
+
|--------|-------|
|
|
11
|
+
| Total Files | 147 |
|
|
12
|
+
| Lines of Code | 24,583 |
|
|
13
|
+
| Primary Languages | TypeScript, Python |
|
|
14
|
+
| Frameworks | Express.js, React, PostgreSQL |
|
|
15
|
+
|
|
16
|
+
## Architecture Quality Score
|
|
17
|
+
|
|
18
|
+
### Overall Score: **72/100**
|
|
19
|
+
|
|
20
|
+
Component Breakdown:
|
|
21
|
+
|
|
22
|
+
- **Modularity**: 78/100 (weight: 40%)
|
|
23
|
+
Measures appropriate module boundaries and single responsibility principle adherence
|
|
24
|
+
|
|
25
|
+
- **Coupling**: 65/100 (weight: 25%)
|
|
26
|
+
Evaluates interdependencies between modules; lower coupling is better
|
|
27
|
+
|
|
28
|
+
- **Cohesion**: 72/100 (weight: 20%)
|
|
29
|
+
Assesses how closely related functionality is grouped together
|
|
30
|
+
|
|
31
|
+
- **Layering**: 68/100 (weight: 15%)
|
|
32
|
+
Checks adherence to architectural layer separation
|
|
33
|
+
|
|
34
|
+
## Anti-Patterns Detected
|
|
35
|
+
|
|
36
|
+
Found **3** anti-pattern(s):
|
|
37
|
+
|
|
38
|
+
### X God Class [CRITICAL]
|
|
39
|
+
|
|
40
|
+
**Location**: `src/services/UserManager.ts`
|
|
41
|
+
|
|
42
|
+
**Description**: Class with 834 lines and 16 methods violates single responsibility principle
|
|
43
|
+
|
|
44
|
+
**Suggestion**: Consider splitting into smaller, focused classes with specific responsibilities
|
|
45
|
+
|
|
46
|
+
**Metrics**:
|
|
47
|
+
- lines: 834
|
|
48
|
+
- methods: 16
|
|
49
|
+
|
|
50
|
+
### W Circular Dependency [HIGH]
|
|
51
|
+
|
|
52
|
+
**Location**: src/utils/auth.ts -> src/services/cache.ts -> src/utils/auth.ts
|
|
53
|
+
|
|
54
|
+
**Description**: Circular dependency detected: auth.ts -> cache.ts -> auth.ts
|
|
55
|
+
|
|
56
|
+
**Suggestion**: Refactor code to break the circular dependency using dependency injection or intermediate abstractions
|
|
57
|
+
|
|
58
|
+
### o Leaky Abstraction [MEDIUM]
|
|
59
|
+
|
|
60
|
+
**Location**: `src/models/Database.ts`
|
|
61
|
+
|
|
62
|
+
**Description**: Exports 12 internal types that should be private
|
|
63
|
+
|
|
64
|
+
**Suggestion**: Use private/internal access modifiers and facade patterns to hide implementation details
|
|
65
|
+
|
|
66
|
+
**Metrics**:
|
|
67
|
+
- exportedInternalTypes: 12
|
|
68
|
+
|
|
69
|
+
## Architectural Layers
|
|
70
|
+
|
|
71
|
+
### API Layer
|
|
72
|
+
|
|
73
|
+
Handles external interfaces and routing
|
|
74
|
+
|
|
75
|
+
**Files**: 12
|
|
76
|
+
```
|
|
77
|
+
src/routes/users.ts
|
|
78
|
+
src/routes/products.ts
|
|
79
|
+
src/routes/orders.ts
|
|
80
|
+
src/routes/auth.ts
|
|
81
|
+
src/middleware/errorHandler.ts
|
|
82
|
+
... and 7 more files
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Service Layer
|
|
86
|
+
|
|
87
|
+
Business logic and orchestration
|
|
88
|
+
|
|
89
|
+
**Files**: 34
|
|
90
|
+
```
|
|
91
|
+
src/services/UserService.ts
|
|
92
|
+
src/services/ProductService.ts
|
|
93
|
+
src/services/OrderService.ts
|
|
94
|
+
src/services/PaymentService.ts
|
|
95
|
+
src/services/NotificationService.ts
|
|
96
|
+
... and 29 more files
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Data Layer
|
|
100
|
+
|
|
101
|
+
Database access and persistence
|
|
102
|
+
|
|
103
|
+
**Files**: 18
|
|
104
|
+
```
|
|
105
|
+
src/repositories/UserRepository.ts
|
|
106
|
+
src/repositories/ProductRepository.ts
|
|
107
|
+
src/repositories/OrderRepository.ts
|
|
108
|
+
src/models/User.ts
|
|
109
|
+
src/models/Product.ts
|
|
110
|
+
... and 13 more files
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### UI Layer
|
|
114
|
+
|
|
115
|
+
User interface components and views
|
|
116
|
+
|
|
117
|
+
**Files**: 42
|
|
118
|
+
```
|
|
119
|
+
src/components/Header.tsx
|
|
120
|
+
src/components/ProductCard.tsx
|
|
121
|
+
src/components/CartItem.tsx
|
|
122
|
+
src/pages/Home.tsx
|
|
123
|
+
src/pages/Product.tsx
|
|
124
|
+
... and 37 more files
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Infrastructure Layer
|
|
128
|
+
|
|
129
|
+
Configuration and setup
|
|
130
|
+
|
|
131
|
+
**Files**: 8
|
|
132
|
+
```
|
|
133
|
+
config/database.ts
|
|
134
|
+
config/logging.ts
|
|
135
|
+
config/cache.ts
|
|
136
|
+
scripts/migrate.ts
|
|
137
|
+
docker-compose.yml
|
|
138
|
+
... and 3 more files
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Architecture Diagram
|
|
142
|
+
|
|
143
|
+
Type: layer
|
|
144
|
+
|
|
145
|
+
```mermaid
|
|
146
|
+
graph LR
|
|
147
|
+
UI["UI<br/>(42 files)"]:::uiStyle
|
|
148
|
+
API["API<br/>(12 files)"]:::apiStyle
|
|
149
|
+
Service["Service<br/>(34 files)"]:::serviceStyle
|
|
150
|
+
Data["Data<br/>(18 files)"]:::dataStyle
|
|
151
|
+
Infrastructure["Infrastructure<br/>(8 files)"]:::infraStyle
|
|
152
|
+
|
|
153
|
+
UI --> API
|
|
154
|
+
API --> Service
|
|
155
|
+
Service --> Data
|
|
156
|
+
Data --> Infrastructure
|
|
157
|
+
|
|
158
|
+
classDef apiStyle fill:#FFB6C1,stroke:#333,color:#000
|
|
159
|
+
classDef serviceStyle fill:#87CEEB,stroke:#333,color:#000
|
|
160
|
+
classDef dataStyle fill:#90EE90,stroke:#333,color:#000
|
|
161
|
+
classDef uiStyle fill:#FFD700,stroke:#333,color:#000
|
|
162
|
+
classDef infraStyle fill:#D3D3D3,stroke:#333,color:#000
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Refactoring Suggestions
|
|
166
|
+
|
|
167
|
+
### CRITICAL Priority
|
|
168
|
+
|
|
169
|
+
1. **God Class**
|
|
170
|
+
Split UserManager into Repository, Service, and Manager classes following single responsibility principle
|
|
171
|
+
Impact: Addressing this God Class will improve overall architecture score
|
|
172
|
+
|
|
173
|
+
### HIGH Priority
|
|
174
|
+
|
|
175
|
+
1. **Circular Dependency**
|
|
176
|
+
Break circular dependency between auth and cache modules using dependency inversion
|
|
177
|
+
Impact: Addressing this Circular Dependency will improve overall architecture score
|
|
178
|
+
|
|
179
|
+
2. **Reduce Coupling**
|
|
180
|
+
Use dependency injection and invert control to reduce module interdependencies
|
|
181
|
+
Impact: Can improve coupling score by 15-20 points
|
|
182
|
+
|
|
183
|
+
### MEDIUM Priority
|
|
184
|
+
|
|
185
|
+
1. **Leaky Abstraction**
|
|
186
|
+
Hide internal database types behind facade pattern
|
|
187
|
+
Impact: Addressing this Leaky Abstraction will improve overall architecture score
|
|
188
|
+
|
|
189
|
+
2. **Improve Cohesion**
|
|
190
|
+
Group related functionality closer together; consider extracting utility modules
|
|
191
|
+
Impact: Can improve cohesion score by 10-15 points
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Key Takeaways
|
|
196
|
+
|
|
197
|
+
This e-commerce API demonstrates a reasonable architectural foundation with good modularity and separation of concerns. The main areas for improvement are:
|
|
198
|
+
|
|
199
|
+
1. Breaking down the oversized UserManager class (critical issue)
|
|
200
|
+
2. Resolving circular dependencies in the utility and cache modules
|
|
201
|
+
3. Tightening module coupling through better dependency management
|
|
202
|
+
4. Hiding internal implementation details from public APIs
|
|
203
|
+
|
|
204
|
+
Implementing these suggestions could bring the overall score from 72/100 to approximately 85-90/100, achieving a highly maintainable and scalable architecture.
|
|
205
|
+
|
|
206
|
+
**Estimated Effort**: 3-4 weeks for a team of 2-3 developers
|
|
207
|
+
**Expected ROI**: Significantly improved code maintainability, reduced future technical debt, easier testing
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
|
2
|
+
export default {
|
|
3
|
+
preset: 'ts-jest/presets/default-esm',
|
|
4
|
+
testEnvironment: 'node',
|
|
5
|
+
extensionsToTreatAsEsm: ['.ts'],
|
|
6
|
+
moduleNameMapper: {
|
|
7
|
+
'^(\\.{1,2}/.*)\\.js$': '$1',
|
|
8
|
+
},
|
|
9
|
+
transform: {
|
|
10
|
+
'^.+\\.tsx?$': [
|
|
11
|
+
'ts-jest',
|
|
12
|
+
{
|
|
13
|
+
useESM: true,
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
testMatch: ['**/tests/**/*.test.ts'],
|
|
18
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@girardelli/architect",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "AI-powered architecture analysis for Claude Code",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Camilo Girardelli",
|
|
8
|
+
"email": "contact@girardelli.tech",
|
|
9
|
+
"url": "https://girardelli.tech"
|
|
10
|
+
},
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"main": "dist/index.js",
|
|
13
|
+
"types": "dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"bin": {
|
|
21
|
+
"architect": "./dist/cli.js"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"clean": "rm -rf dist",
|
|
26
|
+
"dev": "tsc --watch",
|
|
27
|
+
"analyze": "node dist/cli.js analyze",
|
|
28
|
+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
29
|
+
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
|
|
30
|
+
"lint": "eslint src --ext .ts",
|
|
31
|
+
"prepublishOnly": "npm run build && npm run test"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"glob": "^10.3.10",
|
|
35
|
+
"acorn": "^8.11.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^20.10.0",
|
|
39
|
+
"@types/jest": "^29.5.0",
|
|
40
|
+
"typescript": "^5.3.0",
|
|
41
|
+
"jest": "^29.7.0",
|
|
42
|
+
"ts-jest": "^29.1.1",
|
|
43
|
+
"eslint": "^8.55.0",
|
|
44
|
+
"@typescript-eslint/eslint-plugin": "^6.13.0",
|
|
45
|
+
"@typescript-eslint/parser": "^6.13.0"
|
|
46
|
+
},
|
|
47
|
+
"keywords": [
|
|
48
|
+
"architecture",
|
|
49
|
+
"analysis",
|
|
50
|
+
"Claude Code",
|
|
51
|
+
"plugin",
|
|
52
|
+
"code quality",
|
|
53
|
+
"anti-patterns",
|
|
54
|
+
"refactoring",
|
|
55
|
+
"visualization",
|
|
56
|
+
"dependency graph",
|
|
57
|
+
"mermaid"
|
|
58
|
+
],
|
|
59
|
+
"repository": {
|
|
60
|
+
"type": "git",
|
|
61
|
+
"url": "https://github.com/camilooscargbaptista/architect"
|
|
62
|
+
},
|
|
63
|
+
"bugs": {
|
|
64
|
+
"url": "https://github.com/camilooscargbaptista/architect/issues"
|
|
65
|
+
},
|
|
66
|
+
"homepage": "https://github.com/camilooscargbaptista/architect#readme",
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=18.0.0"
|
|
69
|
+
}
|
|
70
|
+
}
|