mit einem Klick
architecture-design
// Use when designing new systems or significant features, evaluating architectural trade-offs, choosing between structural approaches, or when a task requires understanding system-wide design before writing code
// Use when designing new systems or significant features, evaluating architectural trade-offs, choosing between structural approaches, or when a task requires understanding system-wide design before writing code
Use when adding new dependencies, deciding whether to update packages, running security audits on dependencies, evaluating library alternatives, or encountering outdated or vulnerable packages
Use when starting any conversation — establishes how to find and use skills, requiring skill check before ANY response including clarifying questions
You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.
Use when you have a written implementation plan to execute in a separate session with review checkpoints
Use when you have a spec or requirements for a multi-step task, before touching code
Use when a task requires interacting with a web browser — testing UI flows, verifying web app behavior, clicking through screens, reading live web content, or automating browser workflows in Google Antigravity
| name | architecture-design |
| description | Use when designing new systems or significant features, evaluating architectural trade-offs, choosing between structural approaches, or when a task requires understanding system-wide design before writing code |
Design before you build. Architecture decisions are expensive to change. Understand constraints, explore options, validate trade-offs, then decide.
Complete this checklist before presenting any architectural options. Do not propose options without knowing the constraints — options that ignore constraints are not options, they are guesses.
Termination criterion: Proceed when 4 out of 5 items are checked, OR when the user explicitly says "don't know" or "doesn't matter" for the remaining unchecked items.
If fewer than 4 items are known and the user has not dismissed the unknowns, ask before proceeding. Unknown constraints produce designs that must be redesigned later.
1. Understand constraints Before proposing anything, gather the checklist above. Record what is known and what is assumed.
2. Identify core trade-offs Every architecture has trade-offs. Name them explicitly:
3. Propose 2-3 options Never present only one option. For each:
4. Recommend with reasoning State your recommendation clearly. Explain WHY given the specific constraints. Don't hedge everything — make a call.
5. Document the decision Record: what was decided, what was rejected, and why. This is the most important thing to write down.
After completing the output, list any open questions that remain. For each open question, assign it to exactly one of:
If a user-assigned question is blocking, state it clearly: "I need your answer on [question] before I can finalize this design."
When constraints are unavailable, do not refuse to proceed — proceed transparently:
Assumptions are acceptable. Hidden assumptions are not.
When combining patterns, follow these composition rules:
REST + event-driven: Use REST for synchronous CRUD operations (user requests a resource, expects an immediate response). Use events for async side effects (notifications, audit logs, cache invalidation, search index updates). Do not use events for operations where the caller needs an immediate, consistent result.
CQRS + event-driven: Commands (writes) emit events. Query models are rebuilt from events. Acceptable eventual consistency window must be defined before adopting this — if users expect to see their own writes immediately, event lag will cause visible bugs.
Repository pattern + any persistence layer: The repository interface is defined by the domain, not the database. Changing the underlying storage should not require changing the domain logic.
YAGNI — Don't build for hypothetical future needs. Simple first — The simplest thing that could work is usually right. Explicit over implicit — Clear dependencies beat magic. Stateless where possible — Stateful systems are harder to scale and reason about. Fail fast — Validate inputs at boundaries, not deep in the call stack.
| Pattern | Use When |
|---|---|
| REST API | CRUD over resources, external-facing APIs |
| Event-driven | Decoupling producers/consumers, async workflows |
| CQRS | Read/write loads differ significantly |
| Repository pattern | Abstracting data access from business logic |
| Circuit breaker | Calling unreliable external services |
| Saga pattern | Distributed transactions across services |
| BFF (Backend for Frontend) | Multiple clients with different data needs |
Present as:
The following is a complete design session demonstrating correct application of this skill.
Scenario: "Design a notification service for a SaaS app"
Constraint gathering
Checklist filled:
4/5 checked, user dismissed remaining item. Termination criterion met. Proceeding.
Trade-offs identified
Primary tension: sync vs. async delivery
Secondary tension: reliability vs. simplicity
Option A: Direct DB polling
The application writes notification records to a PostgreSQL notifications table when events
occur. A background worker process polls the table every 2 seconds for undelivered notifications
and dispatches them via email/in-app channels. Marks records as delivered after successful send.
Pros:
Cons:
notifications table)Constraints satisfied: scale (5k users, 50k/day), consistency (eventual), team (no new infra), cost (zero marginal cost). Constraints not satisfied: would need redesign above ~100k notifications/day.
Complexity estimate: Low. 1 database table, 1 background worker process, 1-2 days to implement.
Option B: Message queue + workers
Introduce a message queue (AWS SQS or RabbitMQ). Application services publish notification events to the queue. A pool of worker processes consumes the queue and dispatches notifications. Queue provides durability, retry, and dead-letter handling.
Pros:
Cons:
Constraints satisfied: scale (headroom to 1M+/day), consistency (eventual). Constraints not satisfied: team (adds infra burden); cost (SQS has per-message cost at volume).
Complexity estimate: High. New infrastructure dependency, operational runbook required.
Option C: Webhooks / Server-Sent Events (client-pull)
Instead of pushing notifications, serve a /notifications SSE endpoint. The frontend
subscribes on load and receives events in real time. Email notifications sent synchronously
within the triggering request.
Pros:
Cons:
Constraints satisfied: latency (real-time when connected). Constraints not satisfied: consistency (offline users miss notifications), reliability (no guaranteed delivery).
Complexity estimate: Medium. SSE implementation is straightforward; offline delivery gap is a product-level deficiency.
Recommendation: Option A
Given the constraints — 5k users, 50k notifications/day, 2-engineer team, no compliance requirement for guaranteed delivery, no message queue infrastructure — Option A (DB polling) is the correct choice.
Rationale:
Decision record
Decided: Option A — DB polling with PostgreSQL notifications table and background worker.
Rejected: Option B (message queue) — premature complexity. No current requirement justifies the operational burden for a 2-engineer team at this scale.
Rejected: Option C (SSE/webhooks) — does not provide guaranteed delivery for offline users. Acceptable only if the product accepts "notifications are best-effort and only visible when logged in," which was not stated.
Open questions
(delivered_at IS NULL)?
Assign to: (implementation discovery) — measure query time after table has 100k rows,
add index if needed.