mirror of
https://github.com/samiyev/puaros.git
synced 2025-12-27 23:06:54 +05:00
fix: allow internal bounded context imports in aggregate detection (v0.7.3)
This commit is contained in:
@@ -5,6 +5,16 @@ All notable changes to @samiyev/guardian will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [0.7.3] - 2025-11-25
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- 🐛 **False positive: repository importing its own aggregate:**
|
||||||
|
- Added `isInternalBoundedContextImport()` method to detect internal imports
|
||||||
|
- Imports like `../aggregates/Entity` from `repositories/Repo` are now allowed
|
||||||
|
- This correctly allows `ICodeProjectRepository` to import `CodeProject` from the same bounded context
|
||||||
|
- Cross-aggregate imports (with multiple `../..`) are still detected as violations
|
||||||
|
|
||||||
## [0.7.2] - 2025-11-25
|
## [0.7.2] - 2025-11-25
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@samiyev/guardian",
|
"name": "@samiyev/guardian",
|
||||||
"version": "0.7.2",
|
"version": "0.7.3",
|
||||||
"description": "Research-backed code quality guardian for AI-assisted development. Detects hardcodes, circular deps, framework leaks, entity exposure, and 8 architecture violations. Enforces Clean Architecture/DDD principles. Works with GitHub Copilot, Cursor, Windsurf, Claude, ChatGPT, Cline, and any AI coding tool.",
|
"description": "Research-backed code quality guardian for AI-assisted development. Detects hardcodes, circular deps, framework leaks, entity exposure, and 8 architecture violations. Enforces Clean Architecture/DDD principles. Works with GitHub Copilot, Cursor, Windsurf, Claude, ChatGPT, Cline, and any AI coding tool.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"puaros",
|
"puaros",
|
||||||
|
|||||||
@@ -195,6 +195,11 @@ export class AggregateBoundaryDetector implements IAggregateBoundaryDetector {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if import stays within the same bounded context
|
||||||
|
if (this.isInternalBoundedContextImport(normalizedPath)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
const targetAggregate = this.extractAggregateFromImport(normalizedPath)
|
const targetAggregate = this.extractAggregateFromImport(normalizedPath)
|
||||||
if (!targetAggregate || targetAggregate === currentAggregate) {
|
if (!targetAggregate || targetAggregate === currentAggregate) {
|
||||||
return false
|
return false
|
||||||
@@ -207,6 +212,36 @@ export class AggregateBoundaryDetector implements IAggregateBoundaryDetector {
|
|||||||
return this.seemsLikeEntityImport(normalizedPath)
|
return this.seemsLikeEntityImport(normalizedPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the import is internal to the same bounded context
|
||||||
|
*
|
||||||
|
* An import like "../aggregates/Entity" from "repositories/Repo" stays within
|
||||||
|
* the same bounded context (one level up goes to the bounded context root).
|
||||||
|
*
|
||||||
|
* An import like "../../other-context/Entity" crosses bounded context boundaries.
|
||||||
|
*/
|
||||||
|
private isInternalBoundedContextImport(normalizedPath: string): boolean {
|
||||||
|
const parts = normalizedPath.split("/")
|
||||||
|
const dotDotCount = parts.filter((p) => p === "..").length
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If only one ".." and path goes into aggregates/entities folder,
|
||||||
|
* it's likely an internal import within the same bounded context
|
||||||
|
*/
|
||||||
|
if (dotDotCount === 1) {
|
||||||
|
const nonDotParts = parts.filter((p) => p !== ".." && p !== ".")
|
||||||
|
if (nonDotParts.length >= 1) {
|
||||||
|
const firstFolder = nonDotParts[0]
|
||||||
|
// Importing from aggregates/entities within same bounded context is allowed
|
||||||
|
if (this.entityFolderNames.has(firstFolder)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the import path is from an allowed folder (value-objects, events, etc.)
|
* Checks if the import path is from an allowed folder (value-objects, events, etc.)
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user