eva4j 1.0.14 → 1.0.16
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/.agents/skills/skill-creator/LICENSE.txt +202 -0
- package/.agents/skills/skill-creator/SKILL.md +485 -0
- package/.agents/skills/skill-creator/agents/analyzer.md +274 -0
- package/.agents/skills/skill-creator/agents/comparator.md +202 -0
- package/.agents/skills/skill-creator/agents/grader.md +223 -0
- package/.agents/skills/skill-creator/assets/eval_review.html +146 -0
- package/.agents/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.agents/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.agents/skills/skill-creator/references/schemas.md +430 -0
- package/.agents/skills/skill-creator/scripts/__init__.py +0 -0
- package/.agents/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.agents/skills/skill-creator/scripts/generate_report.py +326 -0
- package/.agents/skills/skill-creator/scripts/improve_description.py +247 -0
- package/.agents/skills/skill-creator/scripts/package_skill.py +136 -0
- package/.agents/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/.agents/skills/skill-creator/scripts/run_eval.py +310 -0
- package/.agents/skills/skill-creator/scripts/run_loop.py +328 -0
- package/.agents/skills/skill-creator/scripts/utils.py +47 -0
- package/AGENTS.md +268 -6
- package/COMMAND_EVALUATION.md +15 -16
- package/DOMAIN_YAML_GUIDE.md +430 -14
- package/FUTURE_FEATURES.md +1627 -1168
- package/README.md +461 -13
- package/bin/eva4j.js +32 -14
- package/config/defaults.json +1 -0
- package/docs/commands/EVALUATE_SYSTEM.md +746 -261
- package/docs/commands/EXPORT_DIAGRAM.md +153 -0
- package/docs/commands/GENERATE_ENTITIES.md +599 -6
- package/docs/commands/INDEX.md +7 -0
- package/examples/domain-events.yaml +166 -20
- package/examples/domain-listeners.yaml +212 -0
- package/examples/domain-one-to-many.yaml +1 -0
- package/examples/domain-one-to-one.yaml +1 -0
- package/examples/domain-ports.yaml +414 -0
- package/examples/domain-soft-delete.yaml +47 -44
- package/examples/system/notification.yaml +147 -0
- package/examples/system/product.yaml +185 -0
- package/examples/system/system.yaml +112 -0
- package/examples/system-report.html +971 -0
- package/examples/system.yaml +46 -3
- package/package.json +2 -1
- package/src/agents/design-reviewer.agent.md +163 -0
- package/src/commands/build.js +714 -0
- package/src/commands/create.js +1 -0
- package/src/commands/detach.js +149 -108
- package/src/commands/evaluate-system.js +234 -8
- package/src/commands/export-diagram.js +522 -0
- package/src/commands/generate-entities.js +685 -66
- package/src/commands/generate-http-exchange.js +2 -0
- package/src/commands/generate-kafka-event.js +43 -10
- package/src/generators/base-generator.js +18 -6
- package/src/generators/postman-generator.js +188 -0
- package/src/generators/shared-generator.js +12 -2
- package/src/skills/build-system-yaml/SKILL.md +323 -0
- package/src/skills/build-system-yaml/references/domain-yaml-spec.md +410 -0
- package/src/skills/build-system-yaml/references/module-spec.md +367 -0
- package/src/skills/build-system-yaml/references/system-yaml-spec.md +178 -0
- package/src/utils/config-manager.js +54 -0
- package/src/utils/context-builder.js +1 -0
- package/src/utils/domain-diagram.js +192 -0
- package/src/utils/domain-validator.js +1020 -0
- package/src/utils/fake-data.js +376 -0
- package/src/utils/system-validator.js +319 -199
- package/src/utils/yaml-to-entity.js +272 -7
- package/templates/aggregate/AggregateMapper.java.ejs +3 -2
- package/templates/aggregate/AggregateRepository.java.ejs +3 -2
- package/templates/aggregate/AggregateRepositoryImpl.java.ejs +6 -5
- package/templates/aggregate/AggregateRoot.java.ejs +60 -2
- package/templates/aggregate/DomainEventHandler.java.ejs +4 -1
- package/templates/aggregate/DomainEventRecord.java.ejs +24 -8
- package/templates/aggregate/DomainEventSnapshot.java.ejs +46 -0
- package/templates/aggregate/JpaAggregateRoot.java.ejs +6 -0
- package/templates/base/docker/Dockerfile.ejs +21 -0
- package/templates/base/gradle/build.gradle.ejs +3 -2
- package/templates/base/root/AGENTS.md.ejs +306 -45
- package/templates/crud/ApplicationMapper.java.ejs +4 -0
- package/templates/crud/Controller.java.ejs +4 -4
- package/templates/crud/CreateCommand.java.ejs +4 -0
- package/templates/crud/CreateCommandHandler.java.ejs +3 -6
- package/templates/crud/CreateItemDto.java.ejs +4 -0
- package/templates/crud/CreateValueObjectDto.java.ejs +4 -0
- package/templates/crud/DeleteCommandHandler.java.ejs +12 -6
- package/templates/crud/EndpointsController.java.ejs +6 -6
- package/templates/crud/FindByQuery.java.ejs +1 -1
- package/templates/crud/FindByQueryHandler.java.ejs +3 -9
- package/templates/crud/GetQueryHandler.java.ejs +2 -5
- package/templates/crud/ListQuery.java.ejs +1 -1
- package/templates/crud/ListQueryHandler.java.ejs +8 -14
- package/templates/crud/ScaffoldCommandHandler.java.ejs +2 -4
- package/templates/crud/ScaffoldQuery.java.ejs +3 -2
- package/templates/crud/ScaffoldQueryHandler.java.ejs +5 -6
- package/templates/crud/SubEntityAddCommand.java.ejs +4 -0
- package/templates/crud/SubEntityAddCommandHandler.java.ejs +2 -6
- package/templates/crud/SubEntityRemoveCommandHandler.java.ejs +2 -7
- package/templates/crud/TransitionCommandHandler.java.ejs +2 -6
- package/templates/crud/UpdateCommand.java.ejs +4 -0
- package/templates/crud/UpdateCommandHandler.java.ejs +2 -5
- package/templates/evaluate/report.html.ejs +394 -2
- package/templates/kafka-event/DomainEventHandlerMethod.ejs +3 -1
- package/templates/kafka-event/Event.java.ejs +9 -0
- package/templates/kafka-listener/KafkaController.java.ejs +1 -1
- package/templates/kafka-listener/KafkaListenerClass.java.ejs +1 -1
- package/templates/kafka-listener/ListenerClass.java.ejs +65 -0
- package/templates/kafka-listener/ListenerCommand.java.ejs +31 -0
- package/templates/kafka-listener/ListenerCommandHandler.java.ejs +25 -0
- package/templates/kafka-listener/ListenerIntegrationEvent.java.ejs +37 -0
- package/templates/kafka-listener/ListenerMethod.java.ejs +1 -1
- package/templates/kafka-listener/ListenerNestedType.java.ejs +28 -0
- package/templates/mock/MockEvent.java.ejs +10 -0
- package/templates/mock/MockMessageBrokerImpl.java.ejs +35 -0
- package/templates/mock/MockMessageBrokerImplMethod.java.ejs +6 -0
- package/templates/mock/SpringEventListener.java.ejs +61 -0
- package/templates/ports/PortDomainModel.java.ejs +35 -0
- package/templates/ports/PortFeignAdapter.java.ejs +67 -0
- package/templates/ports/PortFeignClient.java.ejs +45 -0
- package/templates/ports/PortFeignConfig.java.ejs +24 -0
- package/templates/ports/PortInterface.java.ejs +45 -0
- package/templates/ports/PortNestedType.java.ejs +28 -0
- package/templates/ports/PortRequestDto.java.ejs +30 -0
- package/templates/ports/PortResponseDto.java.ejs +28 -0
- package/templates/postman/Collection.json.ejs +1 -1
- package/templates/postman/UnifiedCollection.json.ejs +185 -0
- package/templates/shared/annotations/LogAfter.java.ejs +2 -0
- package/templates/shared/annotations/LogBefore.java.ejs +2 -0
- package/templates/shared/annotations/LogExceptions.java.ejs +2 -0
- package/templates/shared/annotations/LogLevel.java.ejs +8 -0
- package/templates/shared/annotations/LogTimer.java.ejs +1 -0
- package/templates/shared/annotations/Loggable.java.ejs +17 -0
- package/templates/shared/configurations/eventPublicationConfig/EventPublicationSchemaConfig.java.ejs +109 -0
- package/templates/shared/configurations/loggerConfig/HandlerLogs.java.ejs +120 -32
- package/templates/shared/errorMessage/ErrorResponse.java.ejs +23 -0
- package/templates/shared/handlerException/HandlerExceptions.java.ejs +99 -79
- package/src/commands/generate-system.js +0 -243
- package/templates/base/root/skill-build-domain-yaml-references-generate-entities.md.ejs +0 -1103
- package/templates/base/root/skill-build-domain-yaml.ejs +0 -292
- package/templates/base/root/skill-build-system-yaml.ejs +0 -252
- package/templates/shared/errorMessage/ErrorMessage.java.ejs +0 -5
- package/templates/shared/errorMessage/FullErrorMessage.java.ejs +0 -9
- package/templates/shared/errorMessage/ShortErrorMessage.java.ejs +0 -6
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generates Mermaid classDiagram text per module from parsed domain.yaml objects.
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} domainConfigs Plain object { [moduleName]: parsedDomainYaml }
|
|
7
|
+
* @returns {{ [moduleName]: string }} Map of module → Mermaid diagram text (empty string if no aggregates)
|
|
8
|
+
*/
|
|
9
|
+
function generateDomainDiagrams(domainConfigs) {
|
|
10
|
+
const result = {};
|
|
11
|
+
for (const [moduleName, config] of Object.entries(domainConfigs)) {
|
|
12
|
+
result[moduleName] = generateModuleDiagram(moduleName, config);
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
18
|
+
|
|
19
|
+
const AUDIT_FIELDS = new Set(['createdAt', 'updatedAt', 'createdBy', 'updatedBy']);
|
|
20
|
+
|
|
21
|
+
/** Normalize to PascalCase (capitalize first letter only). */
|
|
22
|
+
function toPascal(name) {
|
|
23
|
+
if (!name) return name;
|
|
24
|
+
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function fieldPrefix(field) {
|
|
28
|
+
if (field.hidden) return '-';
|
|
29
|
+
if (field.readOnly) return '~';
|
|
30
|
+
return '+';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ── Per-module diagram builder ────────────────────────────────────────────────
|
|
34
|
+
|
|
35
|
+
function generateModuleDiagram(moduleName, config) {
|
|
36
|
+
const aggregates = config.aggregates || [];
|
|
37
|
+
if (aggregates.length === 0) return '';
|
|
38
|
+
|
|
39
|
+
// Flat diagram — namespace blocks are avoided because Mermaid's layout engine
|
|
40
|
+
// can place inner classes outside the visual boundary, causing overflow.
|
|
41
|
+
// Aggregates are separated by %% comment dividers instead.
|
|
42
|
+
const lines = ['classDiagram'];
|
|
43
|
+
const relationships = []; // Collected per-aggregate, emitted at the end
|
|
44
|
+
const notes = []; // `note for ClassName "..."` — for cross-aggregate refs
|
|
45
|
+
|
|
46
|
+
// Build a set of all entity/VO/enum PascalCase class names defined in this module
|
|
47
|
+
// so we can distinguish intra-module from cross-aggregate relationships.
|
|
48
|
+
const localClasses = new Set();
|
|
49
|
+
for (const aggregate of aggregates) {
|
|
50
|
+
for (const e of aggregate.entities || []) localClasses.add(toPascal(e.name));
|
|
51
|
+
for (const v of aggregate.valueObjects || []) localClasses.add(toPascal(v.name));
|
|
52
|
+
for (const en of aggregate.enums || []) localClasses.add(toPascal(en.name));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
for (const aggregate of aggregates) {
|
|
56
|
+
const entities = aggregate.entities || [];
|
|
57
|
+
const valueObjects = aggregate.valueObjects || [];
|
|
58
|
+
const enums = aggregate.enums || [];
|
|
59
|
+
|
|
60
|
+
lines.push('');
|
|
61
|
+
lines.push(` %% ── Aggregate: ${aggregate.name} ─────────────────────`);
|
|
62
|
+
|
|
63
|
+
// ── Entities ─────────────────────────────────────────────────────────────
|
|
64
|
+
for (const entity of entities) {
|
|
65
|
+
const className = toPascal(entity.name);
|
|
66
|
+
lines.push(` class ${className} {`);
|
|
67
|
+
lines.push(` ${entity.isRoot ? '<<aggregate root>>' : '<<entity>>'}`);
|
|
68
|
+
|
|
69
|
+
for (const field of entity.fields || []) {
|
|
70
|
+
if (AUDIT_FIELDS.has(field.name)) continue;
|
|
71
|
+
lines.push(` ${fieldPrefix(field)}${field.type} ${field.name}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (entity.audit?.enabled) {
|
|
75
|
+
lines.push(` +LocalDateTime createdAt`);
|
|
76
|
+
lines.push(` +LocalDateTime updatedAt`);
|
|
77
|
+
}
|
|
78
|
+
if (entity.audit?.trackUser) {
|
|
79
|
+
lines.push(` +String createdBy`);
|
|
80
|
+
lines.push(` +String updatedBy`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
lines.push(` }`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ── Value objects ─────────────────────────────────────────────────────────
|
|
87
|
+
for (const vo of valueObjects) {
|
|
88
|
+
const className = toPascal(vo.name);
|
|
89
|
+
lines.push(` class ${className} {`);
|
|
90
|
+
lines.push(` <<value object>>`);
|
|
91
|
+
for (const field of vo.fields || []) {
|
|
92
|
+
lines.push(` +${field.type} ${field.name}`);
|
|
93
|
+
}
|
|
94
|
+
lines.push(` }`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ── Enums ─────────────────────────────────────────────────────────────────
|
|
98
|
+
for (const en of enums) {
|
|
99
|
+
const className = toPascal(en.name);
|
|
100
|
+
lines.push(` class ${className} {`);
|
|
101
|
+
lines.push(` <<enumeration>>`);
|
|
102
|
+
for (const val of en.values || []) {
|
|
103
|
+
lines.push(` ${val}`);
|
|
104
|
+
}
|
|
105
|
+
lines.push(` }`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ── Collect relationships ─────────────────────────────────────────────────
|
|
109
|
+
const voNames = new Set(valueObjects.map((v) => toPascal(v.name)));
|
|
110
|
+
const enumNames = new Set(enums.map((e) => toPascal(e.name)));
|
|
111
|
+
|
|
112
|
+
for (const entity of entities) {
|
|
113
|
+
const srcClass = toPascal(entity.name);
|
|
114
|
+
|
|
115
|
+
// Structural JPA relationships — only emit if target is a local class
|
|
116
|
+
for (const rel of entity.relationships || []) {
|
|
117
|
+
const target = toPascal(rel.target || rel.targetEntity || '');
|
|
118
|
+
if (!target) continue;
|
|
119
|
+
if (!localClasses.has(target)) continue; // skip cross-aggregate targets
|
|
120
|
+
const label = rel.mappedBy ? ` : ${rel.mappedBy}` : '';
|
|
121
|
+
switch (rel.type) {
|
|
122
|
+
case 'OneToMany':
|
|
123
|
+
relationships.push(` ${srcClass} "1" --o "*" ${target}${label}`);
|
|
124
|
+
break;
|
|
125
|
+
case 'OneToOne':
|
|
126
|
+
relationships.push(` ${srcClass} "1" --o "1" ${target}${label}`);
|
|
127
|
+
break;
|
|
128
|
+
case 'ManyToOne':
|
|
129
|
+
relationships.push(` ${srcClass} "*" --> "1" ${target}`);
|
|
130
|
+
break;
|
|
131
|
+
case 'ManyToMany':
|
|
132
|
+
relationships.push(` ${srcClass} "*" --> "*" ${target}`);
|
|
133
|
+
break;
|
|
134
|
+
default:
|
|
135
|
+
relationships.push(` ${srcClass} --> ${target}${label}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Field-level type references within the same module (deduplicated)
|
|
140
|
+
const seenEdges = new Set();
|
|
141
|
+
const crossRefs = []; // cross-aggregate reference fields for this entity
|
|
142
|
+
|
|
143
|
+
for (const field of entity.fields || []) {
|
|
144
|
+
if (AUDIT_FIELDS.has(field.name)) continue;
|
|
145
|
+
|
|
146
|
+
const fieldType = toPascal(field.type);
|
|
147
|
+
|
|
148
|
+
if (enumNames.has(fieldType)) {
|
|
149
|
+
const key = `${srcClass}-->${fieldType}`;
|
|
150
|
+
if (!seenEdges.has(key)) {
|
|
151
|
+
relationships.push(` ${srcClass} --> ${fieldType} : ${field.name}`);
|
|
152
|
+
seenEdges.add(key);
|
|
153
|
+
}
|
|
154
|
+
} else if (voNames.has(fieldType)) {
|
|
155
|
+
const key = `${srcClass}*--${fieldType}`;
|
|
156
|
+
if (!seenEdges.has(key)) {
|
|
157
|
+
relationships.push(` ${srcClass} *-- ${fieldType} : ${field.name}`);
|
|
158
|
+
seenEdges.add(key);
|
|
159
|
+
}
|
|
160
|
+
} else if (field.reference) {
|
|
161
|
+
// Cross-aggregate reference: render as a note instead of an arrow
|
|
162
|
+
// to avoid undefined ghost nodes appearing outside the diagram.
|
|
163
|
+
const refModule = field.reference.module;
|
|
164
|
+
const refAggregate = field.reference.aggregate;
|
|
165
|
+
const label =
|
|
166
|
+
refModule && refModule !== moduleName
|
|
167
|
+
? `${field.name} → ${refAggregate} (${refModule})`
|
|
168
|
+
: `${field.name} → ${refAggregate}`;
|
|
169
|
+
crossRefs.push(label);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (crossRefs.length > 0) {
|
|
174
|
+
notes.push(` note for ${srcClass} "refs: ${crossRefs.join(', ')}"`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (relationships.length > 0) {
|
|
180
|
+
lines.push('');
|
|
181
|
+
lines.push(...relationships);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (notes.length > 0) {
|
|
185
|
+
lines.push('');
|
|
186
|
+
lines.push(...notes);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return lines.join('\n');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
module.exports = { generateDomainDiagrams };
|