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,102 @@
import { Order } from "../aggregates/Order"
import { OrderId } from "../value-objects/OrderId"
import { UserId } from "../value-objects/UserId"
import { OrderStatus } from "../value-objects/OrderStatus"
import { OrderItem } from "../entities/OrderItem"
import { Money } from "../value-objects/Money"
/**
* Factory: OrderFactory
*
* DDD Pattern: Factory
* - Handles complex Order creation
* - Different creation scenarios
* - Validation and defaults
*
* Clean Code:
* - Each method has clear purpose
* - No magic values
* - Meaningful names
*/
export class OrderFactory {
/**
* Create empty order for user
*/
public static createEmptyOrder(userId: UserId): Order {
return Order.create(userId)
}
/**
* Create order with initial items
*/
public static createWithItems(
userId: UserId,
items: Array<{ productId: string; productName: string; price: Money; quantity: number }>,
): Order {
const order = Order.create(userId)
for (const item of items) {
order.addItem(item.productId, item.productName, item.price, item.quantity)
}
return order
}
/**
* Reconstitute order from persistence
*/
public static reconstitute(data: {
orderId: string
userId: string
items: Array<{
id: string
productId: string
productName: string
price: number
currency: string
quantity: number
}>
status: string
createdAt: Date
confirmedAt?: Date
deliveredAt?: Date
}): Order {
const orderId = OrderId.create(data.orderId)
const userId = UserId.create(data.userId)
const status = OrderStatus.create(data.status)
const items = data.items.map((item) =>
OrderItem.reconstitute(
item.productId,
item.productName,
Money.create(item.price, item.currency),
item.quantity,
item.id,
),
)
return Order.reconstitute(
orderId,
userId,
items,
status,
data.createdAt,
data.confirmedAt,
data.deliveredAt,
)
}
/**
* Create test order
*/
public static createTestOrder(userId?: UserId): Order {
const testUserId = userId ?? UserId.create()
const order = Order.create(testUserId)
order.addItem("test-product-1", "Test Product 1", Money.create(10, "USD"), 2)
order.addItem("test-product-2", "Test Product 2", Money.create(20, "USD"), 1)
return order
}
}

View File

@@ -0,0 +1,77 @@
import { User } from "../aggregates/User"
import { Email } from "../value-objects/Email"
import { UserId } from "../value-objects/UserId"
/**
* Factory: UserFactory
*
* DDD Pattern: Factory
* - Encapsulates complex object creation
* - Hides construction details
* - Can create from different sources
*
* SOLID Principles:
* - SRP: responsible only for creating Users
* - OCP: can add new creation methods
* - DIP: returns domain object, not DTO
*
* Use cases:
* - Create from external auth provider (OAuth, SAML)
* - Create from legacy data
* - Create with default values
* - Create test users
*/
export class UserFactory {
/**
* Create user from OAuth provider data
*/
public static createFromOAuth(
oauthEmail: string,
oauthFirstName: string,
oauthLastName: string,
): User {
const email = Email.create(oauthEmail)
const firstName = oauthFirstName.trim() || "Unknown"
const lastName = oauthLastName.trim() || "User"
return User.create(email, firstName, lastName)
}
/**
* Create user from legacy database format
*/
public static createFromLegacy(legacyData: {
id: string
email: string
full_name: string
active: number
created_timestamp: number
}): User {
const [firstName = "Unknown", lastName = "User"] = legacyData.full_name.split(" ")
const userId = UserId.create(legacyData.id)
const email = Email.create(legacyData.email)
const isActive = legacyData.active === 1
const registeredAt = new Date(legacyData.created_timestamp * 1000)
return User.reconstitute(userId, email, firstName, lastName, isActive, false, registeredAt)
}
/**
* Create test user with defaults
*/
public static createTestUser(emailSuffix: string = "test"): User {
const email = Email.create(`test-${Date.now()}@${emailSuffix}.com`)
return User.create(email, "Test", "User")
}
/**
* Create admin user
*/
public static createAdmin(email: Email, firstName: string, lastName: string): User {
const user = User.create(email, firstName, lastName)
user.activate()
return user
}
}