AI Skill Report Card
Architecting Enterprise Systems
Quick Start14 / 15
When given a system requirement (e.g., "design an order management system"), immediately produce these outputs together — never partially:
- Architecture layers
- Module relations
- Event flow
- API flow
- Deployment flow
- Folder structure
Example trigger: "Design architecture for a payment processing service." Response: Full architecture package below (see Example 1).
Recommendation▾
Add a second example (e.g., a different domain like inventory or notification system) to demonstrate variability and reduce reliance on a single template output.
Workflow15 / 15
Progress:
- Step 1: Clarify domain boundaries (what business capability does this system own?)
- Step 2: Define architecture layers (presentation, application, domain, infrastructure)
- Step 3: Define modules/services and their relations (dependency direction, shared kernel vs. isolated)
- Step 4: Design event-driven flow (producers, consumers, event topics/queues, retry/DLQ strategy)
- Step 5: Design API flow (endpoints, request/response contracts, sync vs async, gateway routing)
- Step 6: Design deployment flow (CI/CD stages, containers, scaling strategy, environments)
- Step 7: Produce folder structure (mirrors architecture layers and module boundaries)
- Step 8: Validate scalability (identify bottlenecks, stateless services, horizontal scaling points)
Step Details
Architecture Layers — Always structure as:
- Presentation Layer (API Gateway / Controllers)
- Application Layer (Use cases / Orchestration / CQRS handlers)
- Domain Layer (Entities, Value Objects, Domain Events, Business Rules)
- Infrastructure Layer (DB, Message Broker, External Integrations)
Module Relation — Define per module:
- Owns which domain entities
- Depends on which modules (one-directional where possible)
- Exposes which contracts (API/event)
- Shared kernel items (if any) kept minimal
Event Flow — Always specify:
- Event name (past-tense, domain-driven:
OrderPlaced,PaymentConfirmed) - Producer module
- Broker/topic (Kafka topic / RabbitMQ exchange)
- Consumer module(s)
- Failure handling (retry policy, dead-letter queue)
API Flow — Always specify:
- Client → API Gateway → Service → Domain → Infra
- Sync (REST/gRPC) vs Async (event) decision per endpoint
- Versioning strategy (
/v1/) - Auth/authorization checkpoint
Deployment Flow — Always specify:
- Build → Test → Containerize → Push Registry → Deploy (per env: dev/staging/prod)
- Orchestration (Kubernetes namespace/service/deployment)
- Scaling policy (HPA, resource limits)
- Observability hooks (logging, tracing, metrics)
Folder Structure — Always mirror layers per module (modular monolith or microservice), e.g.:
src/
modules/
order/
api/
application/
domain/
infrastructure/
payment/
api/
application/
domain/
infrastructure/
shared/
kernel/
events/
gateway/
Recommendation▾
Include a 'bad output' contrast example (e.g., tightly coupled monolith design) to sharpen the good-vs-bad distinction expected in top-tier skills.
Examples15 / 20
Example 1: Input: "Design architecture for a payment processing service."
Output:
Architecture Layer
- Presentation: REST API Gateway (
/v1/payments) - Application:
ProcessPaymentUseCase,RefundPaymentUseCase - Domain:
Paymententity,PaymentStatusVO,PaymentConfirmeddomain event - Infrastructure: Postgres (payment records), Kafka (event bus), Stripe adapter
Module Relation
payment-serviceownsPaymententity- Depends on
order-service(read-only, via eventOrderPlaced) - Exposes
PaymentConfirmed,PaymentFailedevents - No direct DB access from other modules (contract-first)
Event Flow
OrderPlaced(from order-service) → consumed by payment-service → triggersProcessPaymentUseCase- On success: publish
PaymentConfirmed→ consumed by order-service & notification-service - On failure: publish
PaymentFailed→ retry 3x with exponential backoff → DLQ after exhaustion
API Flow
- Client → API Gateway (
/v1/payments) → Auth middleware →PaymentController→ProcessPaymentUseCase→ Domain validation → Stripe adapter → DB persist → Event publish
Deployment Flow
- Build (Docker) → Unit/Integration Test → Push to registry → Deploy to
payment-svcnamespace in K8s → HPA min 2/max 10 pods → Prometheus + Grafana + Jaeger tracing
Folder Structure
payment-service/
api/
controllers/
dto/
application/
use-cases/
domain/
entities/
events/
value-objects/
infrastructure/
db/
kafka/
stripe-adapter/
Recommendation▾
Add brief guidance on choosing between microservices vs modular monolith with concrete criteria (team size, deploy cadence thresholds) rather than just 'unless scale/team-autonomy justifies'.
Best Practices
- Always design for loose coupling, high cohesion — modules communicate via contracts (API/events), never shared database tables.
- Prefer async event-driven communication for cross-module workflows; reserve sync API calls for real-time user-facing reads.
- Always define idempotency for event consumers (duplicate delivery is expected).
- Always include versioning in APIs and schema evolution strategy for events (backward compatible).
- Always design stateless services to support horizontal scaling.
- Include observability (logs, metrics, traces) as a first-class architecture concern, not an afterthought.
- Default to modular monolith structure unless scale/team-autonomy explicitly justifies microservices.
Common Pitfalls
- Do NOT skip any of the 6 mandatory outputs (layer, module relation, event flow, API flow, deployment flow, folder structure) — always deliver the full set.
- Do NOT allow modules to share a database schema directly — this breaks service boundaries.
- Do NOT design synchronous chains across more than 2-3 services — leads to cascading failures; use events instead.
- Do NOT ignore failure/retry semantics in event flows — always specify DLQ and backoff.
- Do NOT propose toy/prototype-grade design — always assume production-grade: security, scalability, observability included.