feat(guardian): add guardian package - code quality analyzer

Add @puaros/guardian package v0.1.0 - code quality guardian for vibe coders and enterprise teams.

Features:
- Hardcode detection (magic numbers, magic strings)
- Circular dependency detection
- Naming convention enforcement (Clean Architecture)
- Architecture violation detection
- CLI tool with comprehensive reporting
- 159 tests with 80%+ coverage
- Smart suggestions for fixes
- Built for AI-assisted development

Built with Clean Architecture and DDD principles.
Works with Claude, GPT, Copilot, Cursor, and any AI coding assistant.
This commit is contained in:
imfozilbek
2025-11-24 02:54:39 +05:00
parent 9f97509b06
commit 03705b5264
96 changed files with 9520 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
import { PlaceOrder, PlaceOrderRequest } from "../../application/use-cases/PlaceOrder"
import { OrderResponseDto } from "../../application/dtos/OrderResponseDto"
/**
* Order Controller
*
* Infrastructure Layer: HTTP Controller
* - No business logic
* - Returns DTOs (not domain entities!)
* - Delegates to use cases
*/
export class OrderController {
constructor(private readonly placeOrder: PlaceOrder) {}
/**
* POST /orders
*
* ✅ Good: Returns DTO
* ✅ Good: Delegates to use case
* ✅ Good: No business logic
*/
public async placeOrder(request: PlaceOrderRequest): Promise<OrderResponseDto> {
try {
return await this.placeOrder.execute(request)
} catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to place order: ${error.message}`)
}
throw error
}
}
}

View File

@@ -0,0 +1,46 @@
import { CreateUser } from "../../application/use-cases/CreateUser"
import { CreateUserRequest } from "../../application/dtos/CreateUserRequest"
import { UserResponseDto } from "../../application/dtos/UserResponseDto"
/**
* User Controller
*
* Clean Architecture: Infrastructure / Presentation Layer
* - HTTP concerns (not in use case)
* - Request/Response handling
* - Error handling
* - Delegates to use cases
*
* SOLID Principles:
* - SRP: HTTP handling only
* - DIP: depends on use case abstraction
* - OCP: can add new endpoints
*
* Important:
* - NO business logic here
* - NO domain entities exposed
* - Returns DTOs only
* - Use cases do the work
*/
export class UserController {
constructor(private readonly createUser: CreateUser) {}
/**
* POST /users
*
* Clean Code:
* - Returns DTO, not domain entity
* - Delegates to use case
* - Focused method
*/
public async createUser(request: CreateUserRequest): Promise<UserResponseDto> {
try {
return await this.createUser.execute(request)
} catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to create user: ${error.message}`)
}
throw error
}
}
}

View File

@@ -0,0 +1,45 @@
import { IOrderRepository } from "../../domain/repositories/IOrderRepository"
import { Order } from "../../domain/aggregates/Order"
import { OrderId } from "../../domain/value-objects/OrderId"
import { UserId } from "../../domain/value-objects/UserId"
/**
* In-Memory Order Repository
*/
export class InMemoryOrderRepository implements IOrderRepository {
private readonly orders: Map<string, Order> = new Map()
public async save(order: Order): Promise<void> {
this.orders.set(order.orderId.value, order)
}
public async findById(id: OrderId): Promise<Order | null> {
return this.orders.get(id.value) ?? null
}
public async findByUserId(userId: UserId): Promise<Order[]> {
return Array.from(this.orders.values()).filter(
(order) => order.userId.value === userId.value,
)
}
public async findByStatus(status: string): Promise<Order[]> {
return Array.from(this.orders.values()).filter((order) => order.status.value === status)
}
public async findAll(): Promise<Order[]> {
return Array.from(this.orders.values())
}
public async delete(id: OrderId): Promise<void> {
this.orders.delete(id.value)
}
public async exists(id: OrderId): Promise<boolean> {
return this.orders.has(id.value)
}
public clear(): void {
this.orders.clear()
}
}

View File

@@ -0,0 +1,63 @@
import { IUserRepository } from "../../domain/repositories/IUserRepository"
import { User } from "../../domain/aggregates/User"
import { UserId } from "../../domain/value-objects/UserId"
import { Email } from "../../domain/value-objects/Email"
/**
* In-Memory User Repository
*
* DDD Pattern: Repository Implementation
* - Implements domain interface
* - Infrastructure concern
* - Can be replaced with real DB
*
* SOLID Principles:
* - DIP: implements abstraction from domain
* - SRP: manages User persistence
* - LSP: substitutable with other implementations
*
* Clean Architecture:
* - Infrastructure layer
* - Depends on domain
* - Can be swapped (in-memory, Postgres, MongoDB)
*
* Use cases:
* - Testing
* - Development
* - Prototyping
*/
export class InMemoryUserRepository implements IUserRepository {
private readonly users: Map<string, User> = new Map()
public async save(user: User): Promise<void> {
this.users.set(user.userId.value, user)
}
public async findById(id: UserId): Promise<User | null> {
return this.users.get(id.value) ?? null
}
public async findByEmail(email: Email): Promise<User | null> {
return Array.from(this.users.values()).find((user) => user.email.equals(email)) ?? null
}
public async findAll(): Promise<User[]> {
return Array.from(this.users.values())
}
public async findActive(): Promise<User[]> {
return Array.from(this.users.values()).filter((user) => user.isActive)
}
public async delete(id: UserId): Promise<void> {
this.users.delete(id.value)
}
public async exists(id: UserId): Promise<boolean> {
return this.users.has(id.value)
}
public clear(): void {
this.users.clear()
}
}