mirror of
https://github.com/samiyev/puaros.git
synced 2025-12-27 23:06:54 +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,107 @@
|
||||
import { ValueObject } from "../../../../src/domain/value-objects/ValueObject"
|
||||
|
||||
interface MoneyProps {
|
||||
readonly amount: number
|
||||
readonly currency: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Money Value Object
|
||||
*
|
||||
* DDD Pattern: Value Object
|
||||
* - Encapsulates amount + currency
|
||||
* - Immutable
|
||||
* - Rich behavior (add, subtract, compare)
|
||||
*
|
||||
* Prevents common bugs:
|
||||
* - Adding different currencies
|
||||
* - Negative amounts (when not allowed)
|
||||
* - Floating point precision issues
|
||||
*/
|
||||
export class Money extends ValueObject<MoneyProps> {
|
||||
private static readonly SUPPORTED_CURRENCIES = ["USD", "EUR", "GBP", "RUB"]
|
||||
private static readonly DECIMAL_PLACES = 2
|
||||
|
||||
private constructor(props: MoneyProps) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
public static create(amount: number, currency: string): Money {
|
||||
const upperCurrency = currency.toUpperCase()
|
||||
|
||||
if (!Money.SUPPORTED_CURRENCIES.includes(upperCurrency)) {
|
||||
throw new Error(
|
||||
`Unsupported currency: ${currency}. Supported: ${Money.SUPPORTED_CURRENCIES.join(", ")}`,
|
||||
)
|
||||
}
|
||||
|
||||
if (amount < 0) {
|
||||
throw new Error("Money amount cannot be negative")
|
||||
}
|
||||
|
||||
const rounded = Math.round(amount * 100) / 100
|
||||
|
||||
return new Money({ amount: rounded, currency: upperCurrency })
|
||||
}
|
||||
|
||||
public static zero(currency: string): Money {
|
||||
return Money.create(0, currency)
|
||||
}
|
||||
|
||||
public get amount(): number {
|
||||
return this.props.amount
|
||||
}
|
||||
|
||||
public get currency(): string {
|
||||
return this.props.currency
|
||||
}
|
||||
|
||||
public add(other: Money): Money {
|
||||
this.ensureSameCurrency(other)
|
||||
return Money.create(this.amount + other.amount, this.currency)
|
||||
}
|
||||
|
||||
public subtract(other: Money): Money {
|
||||
this.ensureSameCurrency(other)
|
||||
const result = this.amount - other.amount
|
||||
|
||||
if (result < 0) {
|
||||
throw new Error("Cannot subtract: result would be negative")
|
||||
}
|
||||
|
||||
return Money.create(result, this.currency)
|
||||
}
|
||||
|
||||
public multiply(multiplier: number): Money {
|
||||
if (multiplier < 0) {
|
||||
throw new Error("Multiplier cannot be negative")
|
||||
}
|
||||
return Money.create(this.amount * multiplier, this.currency)
|
||||
}
|
||||
|
||||
public isGreaterThan(other: Money): boolean {
|
||||
this.ensureSameCurrency(other)
|
||||
return this.amount > other.amount
|
||||
}
|
||||
|
||||
public isLessThan(other: Money): boolean {
|
||||
this.ensureSameCurrency(other)
|
||||
return this.amount < other.amount
|
||||
}
|
||||
|
||||
public isZero(): boolean {
|
||||
return this.amount === 0
|
||||
}
|
||||
|
||||
private ensureSameCurrency(other: Money): void {
|
||||
if (this.currency !== other.currency) {
|
||||
throw new Error(
|
||||
`Cannot operate on different currencies: ${this.currency} vs ${other.currency}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
return `${this.amount.toFixed(Money.DECIMAL_PLACES)} ${this.currency}`
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user