UNPKG

@samiyev/guardian

Version:

Research-backed code quality guardian for AI-assisted development. Detects hardcodes, secrets, circular deps, framework leaks, entity exposure, and 9 architecture violations. Enforces Clean Architecture/DDD principles. Works with GitHub Copilot, Cursor, W

113 lines (108 loc) 3.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AggregateBoundaryViolation = void 0; const ValueObject_1 = require("./ValueObject"); const Messages_1 = require("../constants/Messages"); /** * Represents an aggregate boundary violation in the codebase * * Aggregate boundary violations occur when an entity from one aggregate * directly references an entity from another aggregate, violating DDD principles: * - Aggregates should reference each other only by ID or Value Objects * - Direct entity references create tight coupling between aggregates * - Changes to one aggregate should not require changes to another * * @example * ```typescript * // Bad: Direct entity reference across aggregates * const violation = AggregateBoundaryViolation.create( * 'order', * 'user', * 'User', * '../user/User', * 'src/domain/aggregates/order/Order.ts', * 5 * ) * * console.log(violation.getMessage()) * // "Order aggregate should not directly reference User entity from User aggregate" * ``` */ class AggregateBoundaryViolation extends ValueObject_1.ValueObject { constructor(props) { super(props); } static create(fromAggregate, toAggregate, entityName, importPath, filePath, line) { return new AggregateBoundaryViolation({ fromAggregate, toAggregate, entityName, importPath, filePath, line, }); } get fromAggregate() { return this.props.fromAggregate; } get toAggregate() { return this.props.toAggregate; } get entityName() { return this.props.entityName; } get importPath() { return this.props.importPath; } get filePath() { return this.props.filePath; } get line() { return this.props.line; } getMessage() { return `${this.capitalizeFirst(this.props.fromAggregate)} aggregate should not directly reference ${this.props.entityName} entity from ${this.capitalizeFirst(this.props.toAggregate)} aggregate`; } getSuggestion() { const suggestions = [ Messages_1.AGGREGATE_VIOLATION_MESSAGES.USE_ID_REFERENCE, Messages_1.AGGREGATE_VIOLATION_MESSAGES.USE_VALUE_OBJECT, Messages_1.AGGREGATE_VIOLATION_MESSAGES.AVOID_DIRECT_REFERENCE, Messages_1.AGGREGATE_VIOLATION_MESSAGES.MAINTAIN_INDEPENDENCE, ]; return suggestions.join("\n"); } getExampleFix() { return ` // ❌ Bad: Direct entity reference across aggregates // domain/aggregates/order/Order.ts import { User } from '../user/User' class Order { constructor(private user: User) {} } // ✅ Good: Reference by ID // domain/aggregates/order/Order.ts import { UserId } from '../user/value-objects/UserId' class Order { constructor(private userId: UserId) {} } // ✅ Good: Use Value Object for needed data // domain/aggregates/order/value-objects/CustomerInfo.ts class CustomerInfo { constructor( readonly customerId: string, readonly customerName: string, readonly customerEmail: string ) {} } // domain/aggregates/order/Order.ts class Order { constructor(private customerInfo: CustomerInfo) {} }`; } capitalizeFirst(str) { return str.charAt(0).toUpperCase() + str.slice(1); } } exports.AggregateBoundaryViolation = AggregateBoundaryViolation; //# sourceMappingURL=AggregateBoundaryViolation.js.map