diff --git a/.agents/tools/architecture/clean-ddd-hexagonal-skill/hexagonal.md b/.agents/tools/architecture/clean-ddd-hexagonal-skill/hexagonal.md index 83555a2f70..0cf36c2647 100644 --- a/.agents/tools/architecture/clean-ddd-hexagonal-skill/hexagonal.md +++ b/.agents/tools/architecture/clean-ddd-hexagonal-skill/hexagonal.md @@ -8,32 +8,19 @@ ```mermaid flowchart TB - subgraph DriverSide["DRIVER SIDE (Primary / Inbound / Left)"] - REST["REST API Adapter"] - CLI["CLI Adapter"] - DriverPorts["DRIVER PORTS\n(Use Case Interfaces)"] - REST --> DriverPorts - CLI --> DriverPorts + subgraph DriverSide["DRIVER SIDE (Primary / Inbound)"] + REST["REST API"] --> DriverPorts["DRIVER PORTS\n(Use Case Interfaces)"] + CLI["CLI"] --> DriverPorts end - subgraph Hexagon["THE HEXAGON"] - subgraph AppCore["APPLICATION CORE"] - subgraph Domain["DOMAIN\n(Business Logic)"] - end - end + Domain["DOMAIN\n(Business Logic)"] end - - subgraph DrivenSide["DRIVEN SIDE (Secondary / Outbound / Right)"] - DrivenPorts["DRIVEN PORTS\n(Repository Interfaces)"] - Postgres["Postgres Adapter"] - RabbitMQ["RabbitMQ Adapter"] - DrivenPorts --> Postgres - DrivenPorts --> RabbitMQ + subgraph DrivenSide["DRIVEN SIDE (Secondary / Outbound)"] + DrivenPorts["DRIVEN PORTS\n(Repository Interfaces)"] --> Postgres["Postgres"] + DrivenPorts --> RabbitMQ["RabbitMQ"] end - - DriverPorts --> AppCore - AppCore --> DrivenPorts - + DriverPorts --> Domain + Domain --> DrivenPorts style DriverSide fill:#3b82f6,stroke:#2563eb,color:white style Hexagon fill:#10b981,stroke:#059669,color:white style DrivenSide fill:#f59e0b,stroke:#d97706,color:white @@ -59,14 +46,12 @@ export interface IOrderRepositoryPort { save(order: Order): Promise; delete(order: Order): Promise; } -// application/ports/driven/event_publisher_port.ts export interface IEventPublisherPort { publish(event: DomainEvent): Promise; publishAll(events: DomainEvent[]): Promise; } -// application/ports/driven/payment_gateway_port.ts export interface IPaymentGatewayPort { - charge(amount: Money, paymentMethod: PaymentMethod): Promise; + charge(amount: Money, method: PaymentMethod): Promise; refund(paymentId: PaymentId, amount: Money): Promise; } ``` @@ -78,17 +63,11 @@ export interface IPaymentGatewayPort { ```typescript // infrastructure/adapters/driver/rest/order_controller.ts export class OrderController { - constructor( - private readonly placeOrder: IPlaceOrderPort, - private readonly getOrder: IGetOrderPort, - ) {} - + constructor(private readonly placeOrder: IPlaceOrderPort, private readonly getOrder: IGetOrderPort) {} async create(req: Request, res: Response): Promise { const orderId = await this.placeOrder.execute({ customerId: req.user.id, - items: req.body.items.map((item: any) => ({ - productId: item.product_id, quantity: item.quantity, - })), + items: req.body.items.map((i: any) => ({ productId: i.product_id, quantity: i.quantity })), }); res.status(201).json({ id: orderId.value }); } @@ -112,7 +91,7 @@ class InMemoryOrderRepository implements IOrderRepositoryPort: # for tests delete(order): orders.delete(order.id.value) class StripePaymentGateway implements IPaymentGatewayPort: - charge(amount, paymentMethod) -> PaymentResult: + charge(amount, method) -> PaymentResult: intent = stripe.paymentIntents.create({amount: amount.cents, ...}) return PaymentResult.success(PaymentId.from(intent.id)) refund(paymentId, amount): stripe.refunds.create({paymentIntent: paymentId.value, ...})