mirror of
https://github.com/samiyev/puaros.git
synced 2025-12-28 07:16:53 +05:00
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:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user