feat: aact v2 — CLI, auto-fix, Structurizr, новые правила#17
Open
ChS23 wants to merge 62 commits intoByndyusoft:mainfrom
Open
feat: aact v2 — CLI, auto-fix, Structurizr, новые правила#17ChS23 wants to merge 62 commits intoByndyusoft:mainfrom
ChS23 wants to merge 62 commits intoByndyusoft:mainfrom
Conversation
- Migrate from yarn to pnpm - Upgrade TypeScript to 5.9, ESLint to 9 (flat config), Prettier to 3 - Replace Jest with Vitest 4, add unbuild - Upgrade Husky to 9, commitlint to 20, lint-staged to 16 - Add Structurizr workspace support - Fix all ESLint warnings (cognitive complexity, type safety, slow regex) - Update GitHub Actions to latest versions
- Rename PumlFile → ArchitectureModel - Export Relation from entities/index.ts - Rewrite analyzer.ts with generic entities, remove plantuml-parser coupling - analyzer now accepts ArchitectureModel instead of filename - Separate analysis results (BoundaryAnalysis, AnalysisReport) from input data - Switch structurizr test to workspace.json fixture
Move directories to target structure (entities→model, plantuml→loaders/plantuml, structurizr→loaders/structurizr, deployConfigs→loaders/kubernetes). Extract architecture validation logic into reusable rule functions (checkAcl, checkCrud, checkAcyclic, checkCohesion) in src/rules/. Add unit tests on in-memory fixtures for all rules and integration tests for loaders. Remove dead code (groupElements.ts).
checkApiGateway validates that ACL containers reach external systems through an API Gateway (matching technology pattern). checkStableDependencies enforces the Stable Dependencies Principle: a component should only depend on more stable components (lower instability index).
Move example tests into examples/plantuml/ subdirectory and add a rules.test.ts demonstrating ACL, acyclic, API Gateway, and stable dependencies checks against C4L2.puml.
Replace dead workshop branch links with actual test file paths for ACL, CRUD, API Gateway, Database per service, Stable Dependencies, and Acyclic rules.
- Fix import sorting, utf8 encoding identifiers, nested template literals - Replace any with unknown in RuleDefinition via type-safe defineRule helper - Restore exhaustive switch check in loadModel - Extract computeCoupling to reduce cognitive complexity - Add eslint-disable for intentional complexity (plantuml generator, check command) - Add eslint-disable for http:// in test fixtures (internal service URLs) - Add .markdownlintignore for legacy documentation files - Extend test ESLint overrides to examples directory
- Remove hardcoded resources/architecture/ from loaders, accept real paths - Add generatePlantumlFromModel for symmetric model-based PlantUML generation - Narrow public API: drop internal re-exports from barrel files - Sync package.json version to 2.0.0 - Set failOnWarn: true in build config - Add error path tests for config validation and loaders - Extract K8s loader exclude list into configurable option
Rename examples/plantuml → examples/banking-plantuml and add examples/microservices-structurizr with Structurizr pipeline demo.
- README: add CLI quick start, library usage, examples and docs sections - patterns.md: add example links, replace TBD with dashes, add Cohesion - roadmap.md: reflect v2 progress (CLI, Structurizr, rules, generators) - ADRs: update test links to actual paths in test/rules/ and examples/
- build.config: prepend shebang to CLI entry for npx support - package.json: add keywords, fix bin path, bump version - README: fix video link spacing
GITHUB_ACTIONS env causes detectFormat to return "github" instead of "text", which skips consola.success calls the test asserts on.
- Add structurizrDslSyntax implementing SourceSyntax for DSL write-back - Fix loader: detect external systems via tags when location !== "External" - Fix loader: fall back rel.description as technology when no spaces - Add source.writePath config field for DSL path separate from JSON path - check --fix: route structurizr fixes to writePath, skip re-check for DSL - check --fix: warn when structurizr source has no writePath configured
Three bounded contexts (Orders, Inventory, Fulfillment) with external systems, ACL containers, and repo-tagged DB accessors — covers all rules.
fixAcl: - redesign algorithm: one Rel(svc, acl), N replacements Rel(svc, ext) -> Rel(acl, ext) - warn and skip when acl container already exists fixDbPerService: - prefer repo/relay-tagged container as DB owner over first-in-list - add ownerTags option (default ["repo", "relay"]) - warn when relation not found in flatMap applyEdits: - warn when pattern not found in source - warn when pattern matches multiple lines tests: - fix cohesion test: parent boundary containers must be empty (leaf-only) - update fixAcl and fixDbPerService tests to reflect new behaviour
- remaining violations count after fix - violations with no auto-fix available (acyclic) - structurizr --fix without writePath → warn + throw - structurizr --fix with writePath → writes DSL, warns to regenerate
- analyze: unknown format falls back to text output - analyze: coupling relations are logged per boundary - generate: kubernetes writes no files when model has no deployable containers - init: throws when file write fails
rules: - acyclic: self-cycle A→A, empty container list - acl: empty list, violation message lists all external deps - dbPerService: custom dbType option - stableDependencies: custom externalType option loaders: - structurizr: empty workspace, async relation tag, external by tags - plantuml: no throw on relation to unknown container
- analyzer: pre-build nameSet/parentMap/childNames per boundary, extract classifyRelation and isSyncApiCall helpers, use Set for db name lookups in analyzeDatabases - cohesion: pre-build boundary name Set once per call - fix: use splice for line insertion, single findIndex scan
- check: extract formatResults, handleFixMode, writeFixes, suggestFixes; run() is now a flat coordinator, eslint-disable removed - generate: load model once in run(), pass to runPlantuml/runKubernetes
…re dbPerService fix - Use DSL identifier (structurizr.dsl.identifier) as container name in Structurizr loader - Redesign check output: ruff-style grouping, aligned columns, picocolors, summary line - Rewrite violation messages across all rules to be human-readable - fixDbPerService: cross-boundary violators now redirect to public API, not internal repo - Add violations-demo example with intentional ACL and dbPerService violations
applyEdits now detects leading whitespace from the matched line and applies it to inserted/replaced content, so generated blocks align with surrounding DSL instead of starting at column 0.
- fixCrud redirects non-repo DB accessors through existing repo or creates a new one (deriving name from DB, e.g. orders_db → orders_repo) - fixCrud removes non-database dependencies from repo-tagged containers - Add repoSuffix option to CrudOptions for configurable naming - Fix plantumlSyntax.containerPattern to match any container type (Container, ContainerDb, etc.) using (name, instead of Container(name,
…tils - buildContainerBoundaryMap and findPublicApiCandidate moved to boundaryUtils.ts - resolveRedirectTarget added: same-boundary → repo, cross-boundary → public API - fixDbPerService and fixCrud both use shared utils - fixCrud Type 1 is now boundary-aware: cross-boundary with no existing repo warns and skips instead of creating a repo in the wrong context
- check.ts: add null coalescing for edit.content, return exitWithViolations() for TS narrowing - check.test.ts: replace readonly relations mutation with Object.assign - generate.test.ts: cast mockMkdir to void-returning type to allow mockResolvedValue() without args - loadConfig.test.ts: add as unknown as for overlapping type cast
Extract detectNamingConvention + joinName into namingUtils.ts. fixCrud and fixAcl now derive repo/acl names using the model's actual convention (snake_case, camelCase, kebab-case) instead of hardcoded suffixes. Remove repoSuffix and aclSuffix options.
- fix.ts: use RegExp.exec() instead of String.match() - fixCrud.ts: replace slow-regex patterns with endsWith/slice stripDbWord helper covering _db, -db, db, _database, -database, database suffixes - add tests for database suffix stripping and repo label derivation
- boundaryUtils.test.ts: direct tests for buildContainerBoundaryMap, findPublicApiCandidate (in-degree ranking) and resolveRedirectTarget - fixCrud: cross-boundary redirect to public API, warn+skip scenarios - fixDbPerService: cross-boundary redirect, no public API, mixed boundaries - fixAcl: camelCase (myServiceAcl) and kebab-case (my-service-acl) naming - loadConfig: verify removed aclSuffix field is rejected by schema
Checks that if a consumer boundary uses at least one public service of a provider boundary, it uses all of them. Public = has incoming relations from outside the boundary.
Three bounded contexts with intentional CRP violation: inventory uses orders_api but not orders_events.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
aact v2
CLI и конфигурация, авто-фикс нарушений, поддержка Structurizr DSL, новые правила валидации.
CLI
Вывод группирует нарушения по правилам, форматы: text, json, github (CI аннотации).
Правила
Auto-fix
Boundary-aware: cross-boundary редирект через публичный API контекста, same-boundary через repo. Автоматически определяет naming convention (snake_case / camelCase / kebab-case) и генерирует имена в ней. Правки пишутся в PlantUML или Structurizr DSL с сохранением отступов.
Источники
Конфиг
ADR
Примеры
267 тестов, 0 lint errors, 0 tsc errors.