mirror of
https://github.com/samiyev/puaros.git
synced 2025-12-27 23:06:54 +05:00
feat: add anemic model detection and refactor hardcoded values (v0.9.0)
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* GOOD EXAMPLE: Rich Domain Model
|
||||
*
|
||||
* This Order class contains business logic and enforces business rules.
|
||||
* State changes are made through business methods, not setters.
|
||||
*
|
||||
* This follows Domain-Driven Design principles.
|
||||
*/
|
||||
|
||||
type OrderStatus = "pending" | "approved" | "rejected" | "shipped"
|
||||
|
||||
interface OrderItem {
|
||||
productId: string
|
||||
quantity: number
|
||||
price: number
|
||||
}
|
||||
|
||||
interface DomainEvent {
|
||||
type: string
|
||||
data: any
|
||||
}
|
||||
|
||||
class Order {
|
||||
private readonly id: string
|
||||
private status: OrderStatus
|
||||
private items: OrderItem[]
|
||||
private readonly events: DomainEvent[] = []
|
||||
|
||||
constructor(id: string, items: OrderItem[]) {
|
||||
this.id = id
|
||||
this.status = "pending"
|
||||
this.items = items
|
||||
}
|
||||
|
||||
public approve(): void {
|
||||
if (!this.canBeApproved()) {
|
||||
throw new Error("Cannot approve order in current state")
|
||||
}
|
||||
this.status = "approved"
|
||||
this.events.push({
|
||||
type: "OrderApproved",
|
||||
data: { orderId: this.id },
|
||||
})
|
||||
}
|
||||
|
||||
public reject(reason: string): void {
|
||||
if (!this.canBeRejected()) {
|
||||
throw new Error("Cannot reject order in current state")
|
||||
}
|
||||
this.status = "rejected"
|
||||
this.events.push({
|
||||
type: "OrderRejected",
|
||||
data: { orderId: this.id, reason },
|
||||
})
|
||||
}
|
||||
|
||||
public ship(): void {
|
||||
if (!this.canBeShipped()) {
|
||||
throw new Error("Order must be approved before shipping")
|
||||
}
|
||||
this.status = "shipped"
|
||||
this.events.push({
|
||||
type: "OrderShipped",
|
||||
data: { orderId: this.id },
|
||||
})
|
||||
}
|
||||
|
||||
public addItem(item: OrderItem): void {
|
||||
if (this.status !== "pending") {
|
||||
throw new Error("Cannot modify approved or shipped order")
|
||||
}
|
||||
this.items.push(item)
|
||||
}
|
||||
|
||||
public calculateTotal(): number {
|
||||
return this.items.reduce((sum, item) => sum + item.price * item.quantity, 0)
|
||||
}
|
||||
|
||||
public getStatus(): OrderStatus {
|
||||
return this.status
|
||||
}
|
||||
|
||||
public getItems(): OrderItem[] {
|
||||
return [...this.items]
|
||||
}
|
||||
|
||||
public getEvents(): DomainEvent[] {
|
||||
return [...this.events]
|
||||
}
|
||||
|
||||
private canBeApproved(): boolean {
|
||||
return this.status === "pending" && this.items.length > 0
|
||||
}
|
||||
|
||||
private canBeRejected(): boolean {
|
||||
return this.status === "pending"
|
||||
}
|
||||
|
||||
private canBeShipped(): boolean {
|
||||
return this.status === "approved"
|
||||
}
|
||||
}
|
||||
|
||||
export { Order }
|
||||
Reference in New Issue
Block a user