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
Breaking a monolith into microservices doesn't solve architectural problems. Each service still needs internal architecture. Services are a deployment option, not an architecture.
Incorrect (microservices as architecture replacement):
"We use microservices architecture"
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ order-service │ │ user-service │ │ payment-service │
│ │ │ │ │ │
│ routes.js │ │ routes.js │ │ routes.js │
│ database.js │ │ database.js │ │ database.js │
│ helpers.js │ │ helpers.js │ │ helpers.js │
│ │ │ │ │ │
│ (No layers, │ │ (No layers, │ │ (No layers, │
│ no boundaries,│ │ no boundaries,│ │ no boundaries,│
│ just smaller │ │ just smaller │ │ just smaller │
│ messes) │ │ messes) │ │ messes) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
# Result: Distributed monolith
# All the downsides of microservices (network, deployment, consistency)
# None of the benefits (each service still a tangled mess)Correct (clean architecture within each service):
┌───────────────────────────────────────────────────────────┐
│ order-service │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ domain/ │ │
│ │ Order.ts OrderLine.ts OrderStatus.ts │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ application/ │ │
│ │ PlaceOrderUseCase.ts │ │
│ │ ports/ │ │
│ │ OrderRepository.ts │ │
│ │ PaymentGateway.ts ← calls payment-service │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ infrastructure/ │ │
│ │ PostgresOrderRepository.ts │ │
│ │ HttpPaymentGateway.ts → payment-service API │ │
│ │ KafkaEventPublisher.ts │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ interface/ │ │
│ │ OrderController.ts │ │
│ │ OrderEventHandler.ts │ │
│ └─────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────┘
# Each service has:
# - Domain layer with business rules
# - Application layer with use cases and ports
# - Infrastructure layer implementing ports
# - Clean dependency direction within serviceCross-service communication:
// application/ports/PaymentGateway.ts
interface PaymentGateway {
charge(amount: Money, method: PaymentMethod): Promise<PaymentResult>
}
// infrastructure/HttpPaymentGateway.ts
class HttpPaymentGateway implements PaymentGateway {
async charge(amount: Money, method: PaymentMethod): Promise<PaymentResult> {
// Calls payment-service over HTTP
// Service boundary is an infrastructure detail
const response = await fetch('http://payment-service/charge', { ... })
return this.mapResponse(response)
}
}Benefits:
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