Apply software design principles across architecture and implementation using deterministic decision workflows, SOLID checks, structural patterns, and anti-pattern detection; use when reviewing designs, refactoring modules, or resolving maintainability and coupling risks.
Does it follow best practices?
Evaluation — 99%
↑ 1.01xAgent success when using this tile
Validation for skill structure
Database gateways, API gateways, and service gateways are polymorphic interfaces that hide external system details. The use case layer talks to abstractions; infrastructure implements them.
Incorrect (use case knows external system details):
func (uc *ProcessRefundUseCase) Execute(orderId string) error {
order := uc.db.QueryRow("SELECT * FROM orders WHERE id = $1", orderId)
// Direct Stripe API knowledge in use case
stripe.Key = os.Getenv("STRIPE_KEY")
params := &stripe.RefundParams{
PaymentIntent: stripe.String(order.PaymentIntentId),
Amount: stripe.Int64(order.Total),
}
_, err := refund.New(params)
if err != nil {
// Stripe-specific error handling
if stripeErr, ok := err.(*stripe.Error); ok {
if stripeErr.Code == stripe.ErrorCodeChargeAlreadyRefunded {
return ErrAlreadyRefunded
}
}
return err
}
uc.db.Exec("UPDATE orders SET status = 'refunded' WHERE id = $1", orderId)
return nil
}Correct (gateway abstracts external system):
// application/ports/PaymentGateway.go
type PaymentGateway interface {
Refund(paymentId string, amount Money) (RefundResult, error)
}
type RefundResult struct {
RefundId string
Status RefundStatus
}
// application/ports/OrderRepository.go
type OrderRepository interface {
FindById(id OrderId) (*Order, error)
Save(order *Order) error
}
// application/usecases/ProcessRefundUseCase.go
type ProcessRefundUseCase struct {
orders OrderRepository
payments PaymentGateway
}
func (uc *ProcessRefundUseCase) Execute(orderId string) error {
order, err := uc.orders.FindById(OrderId(orderId))
if err != nil {
return err
}
result, err := uc.payments.Refund(order.PaymentId, order.Total)
if err != nil {
return err // Gateway translates Stripe errors to domain errors
}
order.MarkRefunded(result.RefundId)
return uc.orders.Save(order)
}
// infrastructure/StripePaymentGateway.go
type StripePaymentGateway struct {
client *stripe.Client
}
func (g *StripePaymentGateway) Refund(paymentId string, amount Money) (RefundResult, error) {
params := &stripe.RefundParams{
PaymentIntent: stripe.String(paymentId),
Amount: stripe.Int64(amount.Cents()),
}
refund, err := g.client.Refunds.New(params)
if err != nil {
return RefundResult{}, g.translateError(err)
}
return RefundResult{
RefundId: refund.ID,
Status: g.translateStatus(refund.Status),
}, nil
}
func (g *StripePaymentGateway) translateError(err error) error {
// Convert Stripe-specific errors to domain errors
if stripeErr, ok := err.(*stripe.Error); ok {
switch stripeErr.Code {
case stripe.ErrorCodeChargeAlreadyRefunded:
return ErrAlreadyRefunded
}
}
return ErrPaymentFailed
}Benefits:
Reference: Clean Architecture - Database Gateways
Install with Tessl CLI
npx tessl i pantheon-ai/software-design-principlesevals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
references