Application Patterns
Authoritative reference for selecting and applying the application_patterns manifest block during blueprint generation. Covers architecture pattern selection, folder structures, coding conventions, error handling, testing strategies, and platform-specific patterns.
For security architecture (auth, OWASP, API security), see operational-patterns. For infrastructure and tooling decisions (cloud, database, hosting), see prescriptive-decision-framework.
Architecture Pattern Selection
Decision Inputs
| Input |
How to Determine |
| Team size |
Gating question 5 or tech constraints section |
| Domain complexity |
Simple CRUD (< 10 entities) vs complex business rules vs event-heavy workflows |
| Deployment model |
Single deployable vs multiple services (from scale/team gating) |
| Platform |
Backend API, frontend web app, mobile app, or full-stack |
Architecture Pattern Decision Tree
IF simple CRUD app with < 10 entities AND team <= 3:
-> RECOMMEND: layered
-> REASONING: "Simplest to build and hire for. Controllers -> services -> data access. No abstraction overhead."
-> ALTERNATIVE: "mvc if server-rendered pages are needed (admin panels, forms)"
-> DON'T USE: "clean-architecture or hexagonal — overkill for simple CRUD"
ELSE IF server-rendered pages with forms (admin panels, CRM, dashboards):
-> RECOMMEND: mvc
-> REASONING: "Natural fit for request/response with views. Well-understood by most developers."
-> ALTERNATIVE: "layered if API-only with separate frontend"
-> DON'T USE: "cqrs, event-driven — wrong paradigm for form-based apps"
ELSE IF mobile or reactive UI with data-binding (React Native, Flutter):
-> RECOMMEND: mvvm
-> REASONING: "ViewModel decouples business logic from UI. Natural fit for reactive/declarative frameworks."
-> ALTERNATIVE: "clean-architecture if domain logic is complex beyond UI state"
-> DON'T USE: "mvc — poor fit for reactive/declarative UI frameworks"
ELSE IF complex business logic with many domain rules AND high testability needed:
-> RECOMMEND: clean-architecture
-> REASONING: "Domain at center, dependencies point inward. Business logic testable without framework/DB. Best for long-lived codebases."
-> ALTERNATIVE: "hexagonal if swappable external integrations matter more than layered use-case organization"
-> DON'T USE: "For MVPs or simple CRUD — the abstraction overhead slows early development"
ELSE IF many external integrations that may change (payment providers, notification services, AI providers):
-> RECOMMEND: hexagonal
-> REASONING: "Ports and adapters. Swap Stripe for Adyen, swap OpenAI for Anthropic — without touching business logic."
-> ALTERNATIVE: "clean-architecture if the domain rules are more complex than the integration surface"
ELSE IF single deployable AND team 3-10 AND multiple bounded contexts:
-> RECOMMEND: modular-monolith
-> REASONING: "Module isolation without deployment complexity. Each module owns its data/logic. Can extract to microservices later."
-> ALTERNATIVE: "clean-architecture if there's one dominant domain, not multiple contexts"
-> DON'T USE: "microservices — same organizational benefit, 5x more operational complexity at this team size"
ELSE IF team > 10 backend engineers AND services need independent deployment and scaling:
-> RECOMMEND: microservices
-> REASONING: "Independent deploys, independent scaling, independent tech choices per service. Required at this team size for velocity."
-> DON'T USE: "At MVP stage or with < 5 engineers — operational overhead destroys velocity"
ELSE IF low-traffic bursty workloads AND no persistent connections:
-> RECOMMEND: serverless
-> REASONING: "Pay per invocation. Auto-scales to zero. Ideal for webhooks, cron jobs, event processors."
-> ALTERNATIVE: "layered on Railway/Render if you need persistent connections (WebSockets)"
-> DON'T USE: "For real-time features, long-running jobs, or latency-sensitive APIs (cold starts)"
ELSE IF components react to events asynchronously (order placed -> email + inventory + analytics):
-> RECOMMEND: event-driven
-> REASONING: "Decouples producers from consumers. New consumers don't require changes to producers. Natural for async workflows."
-> ALTERNATIVE: "cqrs if read/write asymmetry is the primary concern rather than event flow"
-> DON'T USE: "Simple request/response CRUD — adds unnecessary complexity"
ELSE IF read and write patterns are fundamentally different (high-read dashboards + low-write mutations):
-> RECOMMEND: cqrs
-> REASONING: "Separate read models (optimized for queries) from write models (optimized for business rules). Scale reads independently."
-> ALTERNATIVE: "event-driven if the asymmetry is about workflow rather than read/write patterns"
-> DON'T USE: "Simple CRUD where reads and writes use the same model"
ELSE (default):
-> RECOMMEND: layered
-> REASONING: "Safe default. Easiest to hire for. Can evolve to modular-monolith or clean-architecture when complexity justifies it."
Pattern Compatibility Matrix
| Primary Pattern |
Combines Well With |
Avoid Combining With |
| clean-architecture |
domain-driven folders, cqrs |
flat folders |
| hexagonal |
domain-driven folders, event-driven |
layer-based folders |
| mvc |
layer-based folders |
cqrs, event-driven |
| mvvm |
feature-based folders |
microservices |
| modular-monolith |
module-based folders, event-driven |
flat folders |
| microservices |
event-driven, cqrs |
mvc, flat folders |
| serverless |
flat or feature-based folders |
modular-monolith |
| event-driven |
cqrs, microservices, feature-based |
mvc |
| cqrs |
event-driven, clean-architecture |
flat folders, mvc |
| layered |
layer-based or feature-based folders |
cqrs (overkill) |
Folder Structure Examples
Backend: feature-based
src/
features/
auth/
auth.controller.ts
auth.service.ts
auth.repository.ts
auth.routes.ts
auth.types.ts
__tests__/
auth.service.test.ts
orders/
orders.controller.ts
orders.service.ts
orders.repository.ts
orders.routes.ts
orders.types.ts
__tests__/
orders.service.test.ts
shared/
middleware/
auth.middleware.ts
error.middleware.ts
utils/
types/
config/
env.ts
index.ts
Backend: layer-based
src/
controllers/
auth.controller.ts
orders.controller.ts
services/
auth.service.ts
orders.service.ts
repositories/
auth.repository.ts
orders.repository.ts
models/
user.model.ts
order.model.ts
routes/
auth.routes.ts
orders.routes.ts
middleware/
auth.middleware.ts
error.middleware.ts
config/
env.ts
index.ts
Backend: domain-driven (clean-architecture / hexagonal)
src/
domain/
entities/
user.ts
order.ts
value-objects/
email.ts
money.ts
repositories/
user.repository.ts # Interface only
order.repository.ts # Interface only
errors/
not-found.error.ts
validation.error.ts
application/
use-cases/
create-order.use-case.ts
get-user.use-case.ts
dto/
create-order.dto.ts
infrastructure/
persistence/
prisma-user.repository.ts # Implements domain interface
prisma-order.repository.ts
external/
stripe.adapter.ts
email.adapter.ts
presentation/
controllers/
orders.controller.ts
middleware/
auth.middleware.ts
error.middleware.ts
routes/
orders.routes.ts
config/
env.ts
index.ts
Backend: module-based (modular-monolith)
src/
modules/
auth/
index.ts # Public API (barrel export)
auth.service.ts
auth.repository.ts
auth.routes.ts
__tests__/
billing/
index.ts
billing.service.ts
billing.repository.ts
billing.routes.ts
__tests__/
orders/
index.ts
orders.service.ts
orders.repository.ts
orders.routes.ts
__tests__/
shared/
middleware/
utils/
config/
index.ts
Cross-module imports go through index.ts only. Direct imports of internal files across modules are a violation.
Backend: flat
src/
auth.ts
orders.ts
billing.ts
db.ts
middleware.ts
types.ts
index.ts
Suitable only for serverless functions, small CLIs, or prototypes with < 5 files.
Frontend: Next.js App Router (feature-based)
src/
app/
(auth)/
login/page.tsx
register/page.tsx
(dashboard)/
layout.tsx
page.tsx
orders/page.tsx
features/
auth/
hooks/use-auth.ts
components/login-form.tsx
api/auth.api.ts
orders/
hooks/use-orders.ts
components/order-list.tsx
api/orders.api.ts
components/
ui/
button.tsx
input.tsx
lib/
api-client.ts
utils.ts
store/
auth.store.ts
Frontend: React SPA (Vite, feature-based)
src/
features/
auth/
pages/login.tsx
hooks/use-auth.ts
components/login-form.tsx
api/auth.api.ts
orders/
pages/order-list.tsx
hooks/use-orders.ts
components/order-card.tsx
api/orders.api.ts
components/
ui/
layout/
lib/
api-client.ts
router.tsx
store/
App.tsx
main.tsx
Mobile: React Native / Expo (feature-based)
src/
features/
auth/
screens/login-screen.tsx
hooks/use-auth.ts
components/login-form.tsx
api/auth.api.ts
orders/
screens/order-list-screen.tsx
hooks/use-orders.ts
components/order-card.tsx
api/orders.api.ts
components/
ui/
navigation/
root-navigator.tsx
auth-navigator.tsx
services/
storage.ts
notifications.ts
biometrics.ts
lib/
api-client.ts
store/
auth.store.ts
App.tsx
Coding Conventions
Naming Conventions by Folder Convention
| Convention |
File Naming |
Class / Function |
Exports |
| feature-based |
{feature}.{layer}.ts (e.g., orders.service.ts) |
OrdersService, createOrder |
Named exports per file |
| layer-based |
{entity}.{layer}.ts (e.g., order.controller.ts) |
OrderController, OrderService |
Named exports per file |
| domain-driven |
{concept}.ts in layer directory |
Order (entity), CreateOrderUseCase |
Named exports per file |
| module-based |
{module}/{layer}.ts |
AuthService, BillingService |
Barrel exports via index.ts |
| flat |
{feature}.ts |
createOrder, authenticateUser |
Named exports per file |
Dependency Rules by Architecture Pattern
| Pattern |
Allowed Import Direction |
Violation Example |
| clean-architecture |
presentation -> application -> domain (never reverse) |
Domain importing Express types |
| hexagonal |
adapters -> ports -> domain (never reverse) |
Domain importing Prisma client |
| layered |
controllers -> services -> repositories (never reverse) |
Repository importing controller |
| modular-monolith |
Within module: any direction. Cross-module: public API (index.ts) only |
Module A importing Module B's internal service |
| mvc |
views -> controllers -> models (never reverse) |
Model importing view logic |
| mvvm |
view -> viewmodel -> model (never reverse) |
Model importing view state |
Error Handling Patterns
Application-level error handling for structuring, propagating, and responding to errors. For security error mitigations (OWASP, rate limiting, input sanitization), see operational-patterns.
Standard Error Response Shape
interface AppError {
code: string; // Machine-readable: "ORDER_NOT_FOUND", "VALIDATION_FAILED"
message: string; // Human-readable: "Order not found"
details?: unknown; // Validation errors array, debug context
requestId: string; // For support correlation
}
Error Handling Strategy by Pattern
| Pattern |
Strategy |
Implementation |
| layered / mvc |
Try-catch in controllers, centralized error middleware |
Express app.use((err, req, res, next) => ...) catches all |
| clean-architecture |
Domain errors as typed classes, use-case catches and maps to application errors |
OrderNotFoundError extends DomainError, use-case returns Result<T, E> |
| hexagonal |
Port defines error types, adapter catches infrastructure errors and maps to port errors |
Database timeout -> RepositoryUnavailableError |
| event-driven |
Dead letter queue for unprocessable events, structured error events |
Failed event -> DLQ, log for replay. See architecture-methodology invariant on at-least-once processing. |
| serverless |
Return structured error response, let platform handle retries |
{ statusCode: 500, body: JSON.stringify(appError) } |
| microservices |
Each service returns domain error codes, API gateway maps to HTTP |
gRPC status codes -> HTTP status codes at gateway |
Domain Error to HTTP Status Mapping
| Domain Error Type |
HTTP Status |
When |
ValidationError |
400 |
Input fails schema or business rule validation |
AuthenticationError |
401 |
Missing, expired, or invalid credentials |
ForbiddenError |
403 |
Valid auth but insufficient permissions |
NotFoundError |
404 |
Entity does not exist or is not accessible |
ConflictError |
409 |
Duplicate resource, idempotency key collision |
RateLimitError |
429 |
Too many requests |
ExternalServiceError |
502 |
Upstream dependency failed |
UnexpectedError |
500 |
Unhandled exception (log full stack, return generic message) |
Error Propagation Rules
- Never expose stack traces or internal error details in production responses
- Log the full error server-side (with
requestId), return sanitized AppError to the client
- Distinguish client errors (4xx — don't retry) from server errors (5xx — may retry with backoff)
- Use
requestId for cross-service correlation. See operational-patterns structured logging for format.
- For async errors, route to dead letter queue. See
architecture-methodology invariant on at-least-once processing with DLQ.
- Frontend: use error boundaries (React) or global error handlers to catch rendering errors without crashing the app
Testing Strategy Patterns
Testing Pyramid by Architecture Pattern
| Pattern |
Unit Tests |
Integration Tests |
E2E Tests |
Contract Tests |
Ratio |
| layered / mvc |
Service logic, validators |
API endpoints (supertest) |
Critical user flows |
N/A |
70 / 20 / 10 |
| clean-architecture |
Use cases, domain entities |
Adapters against real DB |
Critical user flows |
N/A |
60 / 30 / 10 |
| modular-monolith |
Per-module service logic |
Per-module API + cross-module |
Critical cross-module flows |
Between modules |
50 / 25 / 10 / 15 |
| microservices |
Per-service logic |
Intra-service with test DB |
Cross-service critical paths |
Between services (Pact) |
50 / 20 / 10 / 20 |
| event-driven |
Event handlers, validators |
Event processing pipeline |
End-to-end event flows |
Event schema validation |
50 / 20 / 10 / 20 |
| serverless |
Function logic |
With local emulator (SAM) |
Deployed endpoint smoke tests |
N/A |
60 / 30 / 10 |
What to Test Where
| Layer |
What to Test |
What NOT to Test |
Tooling |
| Domain / business logic |
Rules, calculations, state transitions, edge cases |
Framework code, database queries |
Jest, Vitest, pytest |
| API endpoints |
Request/response contracts, auth, validation, status codes |
Internal service implementation |
Supertest, httpx, Playwright API |
| Database |
Migrations, complex queries, indexes, constraints |
Simple CRUD operations |
Testcontainers, in-memory SQLite |
| External integrations |
Contract compliance, error handling for failures |
Third-party uptime or correctness |
MSW (mocks), Pact (contracts) |
| Frontend components |
User interactions, conditional rendering, form validation |
Styling, pixel-level layout |
Testing Library, Storybook |
| E2E flows |
Critical user journeys (signup, checkout, payment) |
Every possible path |
Playwright, Cypress |
Testing Strategy Templates
Use these templates when populating the testing_strategy manifest field:
MVP / simple app:
Unit tests for business logic (Jest/Vitest). Integration tests for API endpoints (supertest). No E2E yet. Coverage target: 60%. Run in CI on every PR.
Multi-service production:
Unit tests for domain logic per service. Integration tests per service with test database. Contract tests between services (Pact). E2E for critical user flows (Playwright). Coverage target: 80%. Run in CI, E2E on staging deploy.
Event-driven / async:
Unit tests for event handlers and validators. Integration tests for event processing pipeline. Schema validation tests for event contracts. DLQ monitoring as implicit regression detection. Coverage target: 70%.
Frontend-Specific Patterns
State Management Selection
IF app has < 5 pages AND minimal shared state:
-> RECOMMEND: React useState + Context
-> REASONING: "No extra dependencies. Sufficient for simple apps. Upgrade when state gets complex."
-> DON'T USE: "Redux, Zustand — overkill at this scale"
ELSE IF primary state is server data (CRUD app, dashboard, admin panel):
-> RECOMMEND: React Query / TanStack Query (server state) + Zustand (client state)
-> REASONING: "Server cache is not client state. React Query handles caching, revalidation, loading states. Zustand for UI-only state (modals, sidebar)."
ELSE IF complex client-side state (collaborative editor, form builder, drag-and-drop):
-> RECOMMEND: Zustand or Redux Toolkit
-> REASONING: "Need predictable state updates, middleware, devtools, undo/redo support."
ELSE IF Next.js App Router with server components:
-> RECOMMEND: Server components for data fetching + Zustand for client state
-> REASONING: "Server components eliminate client state for read data. Zustand handles remaining interactive state."
ELSE IF Vue / Nuxt:
-> RECOMMEND: Pinia
-> REASONING: "Official Vue state management. Composable, typed, devtools integrated."
Component Architecture
| Pattern |
When to Use |
Structure |
| Feature components |
Feature-scoped, self-contained units |
Feature folder with components/, hooks/, api/ |
| Presentational + Container |
Clear data/UI separation needed |
Container fetches data, presentational renders props |
| Compound components |
Complex UI with shared state (Accordion, Tabs, Menu) |
Parent provides context, children consume via hooks |
| Headless hooks |
Reusable logic across different UIs |
Logic in custom hooks, no rendered UI (e.g., useAuth, usePagination) |
Data Fetching Patterns
| Pattern |
When to Use |
Implementation |
| Server Components (RSC) |
Next.js App Router, data needed on initial render |
async function Page() with direct fetch or DB query |
| Client-side fetching |
Interactive data, user-triggered queries |
React Query useQuery / useMutation |
| SSR + hydration |
SEO-critical pages with interactivity |
Next.js getServerSideProps or loader functions |
| Optimistic updates |
Instant UI feedback (likes, toggles, status changes) |
React Query onMutate — update cache before server confirms |
| Infinite scroll / pagination |
Long lists, feeds, search results |
React Query useInfiniteQuery with cursor-based pagination |
Mobile-Specific Patterns
Offline-First Architecture
| Requirement |
Strategy |
Implementation |
| Read-only offline (view cached data) |
Cache-first with background sync |
MMKV / AsyncStorage + stale-while-revalidate fetch pattern |
| Write-while-offline (create/edit offline) |
Local-first writes + sync queue |
MMKV writes + background sync queue + server reconciliation on reconnect |
| Full offline capability |
Local database + sync engine |
WatermelonDB or Expo SQLite + custom sync protocol with conflict resolution |
Default recommendation: start with read-only offline caching. Add write-offline only when user research confirms the need.
Navigation Pattern Selection
| App Type |
Pattern |
Implementation |
| Tab-based (social, marketplace, dashboard) |
Bottom tabs + stack per tab |
Expo Router tabs or React Navigation bottom tabs |
| Flow-based (onboarding, checkout, multi-step forms) |
Stack navigation with progress indicator |
Stack navigator with step-aware header |
| Drawer-based (admin panels, settings-heavy apps) |
Drawer + nested stacks |
Drawer navigator with stack navigators per section |
| Deep-link driven (content apps, shared URLs) |
URL-based file routing |
Expo Router (file-based routing with deep link support) |
Platform Abstraction Layer
Create a services/ directory with platform-agnostic interfaces for capabilities that differ across platforms:
| Service |
What It Abstracts |
Example Implementations |
storage.ts |
Secure key-value storage |
Expo SecureStore, MMKV, AsyncStorage |
notifications.ts |
Push notification registration and handling |
Expo Notifications, Firebase Cloud Messaging |
biometrics.ts |
Biometric authentication |
Expo LocalAuthentication |
camera.ts |
Camera and image capture |
Expo Camera, react-native-image-picker |
Same principle as hexagonal architecture ports/adapters: feature code depends on the interface, not the platform implementation. Swap implementations without changing feature code.
Choosing Patterns for a Blueprint
Quick-reference table for selecting the full application_patterns block based on project profile:
| Project Profile |
Architecture |
Folder Convention |
Error Handling |
Testing Strategy |
| Simple CRUD API |
layered |
layer-based |
Centralized error middleware + status code mapping |
Unit + integration (70/30) |
| SaaS with complex domain |
clean-architecture |
domain-driven |
Typed domain errors + use-case mapping + error middleware |
Unit + integration + contract (60/30/10) |
| Modular product (pre-microservices) |
modular-monolith |
module-based |
Per-module error codes + shared error middleware |
Unit + integration per module + cross-module contract |
| Event-driven system |
event-driven |
feature-based |
DLQ + structured error events + retry with backoff |
Handler unit + schema validation + pipeline integration |
| Serverless API |
serverless |
flat |
Structured error responses per function |
Function unit + emulator integration (60/40) |
| Mobile app |
mvvm |
feature-based |
Error boundaries + retry on network failure |
Component unit + integration + E2E critical flows |
| Full-stack Next.js |
layered |
feature-based |
Server action errors + error.tsx boundaries + API error middleware |
RSC + API + Playwright E2E |
For security architecture decisions, see operational-patterns. For infrastructure and tooling decisions (cloud, database, auth, hosting), see prescriptive-decision-framework. For domain-specific depth (multi-tenant isolation, payment flows, AI orchestration), see product-type-detector templates. To evaluate your chosen patterns against quality standards, see well-architected.
1---2name: application-patterns3description: Architecture pattern selection, folder structures, coding conventions, error handling, testing strategies, and platform-specific patterns for structuring application code4---56# Application Patterns78Authoritative reference for selecting and applying the `application_patterns` manifest block during blueprint generation. Covers architecture pattern selection, folder structures, coding conventions, error handling, testing strategies, and platform-specific patterns.910For security architecture (auth, OWASP, API security), see `operational-patterns`. For infrastructure and tooling decisions (cloud, database, hosting), see `prescriptive-decision-framework`.1112---1314## Architecture Pattern Selection1516### Decision Inputs1718| Input | How to Determine |19|-------|-----------------|20| **Team size** | Gating question 5 or tech constraints section |21| **Domain complexity** | Simple CRUD (< 10 entities) vs complex business rules vs event-heavy workflows |22| **Deployment model** | Single deployable vs multiple services (from scale/team gating) |23| **Platform** | Backend API, frontend web app, mobile app, or full-stack |2425### Architecture Pattern Decision Tree2627```28IF simple CRUD app with < 10 entities AND team <= 3:29 -> RECOMMEND: layered30 -> REASONING: "Simplest to build and hire for. Controllers -> services -> data access. No abstraction overhead."31 -> ALTERNATIVE: "mvc if server-rendered pages are needed (admin panels, forms)"32 -> DON'T USE: "clean-architecture or hexagonal — overkill for simple CRUD"3334ELSE IF server-rendered pages with forms (admin panels, CRM, dashboards):35 -> RECOMMEND: mvc36 -> REASONING: "Natural fit for request/response with views. Well-understood by most developers."37 -> ALTERNATIVE: "layered if API-only with separate frontend"38 -> DON'T USE: "cqrs, event-driven — wrong paradigm for form-based apps"3940ELSE IF mobile or reactive UI with data-binding (React Native, Flutter):41 -> RECOMMEND: mvvm42 -> REASONING: "ViewModel decouples business logic from UI. Natural fit for reactive/declarative frameworks."43 -> ALTERNATIVE: "clean-architecture if domain logic is complex beyond UI state"44 -> DON'T USE: "mvc — poor fit for reactive/declarative UI frameworks"4546ELSE IF complex business logic with many domain rules AND high testability needed:47 -> RECOMMEND: clean-architecture48 -> REASONING: "Domain at center, dependencies point inward. Business logic testable without framework/DB. Best for long-lived codebases."49 -> ALTERNATIVE: "hexagonal if swappable external integrations matter more than layered use-case organization"50 -> DON'T USE: "For MVPs or simple CRUD — the abstraction overhead slows early development"5152ELSE IF many external integrations that may change (payment providers, notification services, AI providers):53 -> RECOMMEND: hexagonal54 -> REASONING: "Ports and adapters. Swap Stripe for Adyen, swap OpenAI for Anthropic — without touching business logic."55 -> ALTERNATIVE: "clean-architecture if the domain rules are more complex than the integration surface"5657ELSE IF single deployable AND team 3-10 AND multiple bounded contexts:58 -> RECOMMEND: modular-monolith59 -> REASONING: "Module isolation without deployment complexity. Each module owns its data/logic. Can extract to microservices later."60 -> ALTERNATIVE: "clean-architecture if there's one dominant domain, not multiple contexts"61 -> DON'T USE: "microservices — same organizational benefit, 5x more operational complexity at this team size"6263ELSE IF team > 10 backend engineers AND services need independent deployment and scaling:64 -> RECOMMEND: microservices65 -> REASONING: "Independent deploys, independent scaling, independent tech choices per service. Required at this team size for velocity."66 -> DON'T USE: "At MVP stage or with < 5 engineers — operational overhead destroys velocity"6768ELSE IF low-traffic bursty workloads AND no persistent connections:69 -> RECOMMEND: serverless70 -> REASONING: "Pay per invocation. Auto-scales to zero. Ideal for webhooks, cron jobs, event processors."71 -> ALTERNATIVE: "layered on Railway/Render if you need persistent connections (WebSockets)"72 -> DON'T USE: "For real-time features, long-running jobs, or latency-sensitive APIs (cold starts)"7374ELSE IF components react to events asynchronously (order placed -> email + inventory + analytics):75 -> RECOMMEND: event-driven76 -> REASONING: "Decouples producers from consumers. New consumers don't require changes to producers. Natural for async workflows."77 -> ALTERNATIVE: "cqrs if read/write asymmetry is the primary concern rather than event flow"78 -> DON'T USE: "Simple request/response CRUD — adds unnecessary complexity"7980ELSE IF read and write patterns are fundamentally different (high-read dashboards + low-write mutations):81 -> RECOMMEND: cqrs82 -> REASONING: "Separate read models (optimized for queries) from write models (optimized for business rules). Scale reads independently."83 -> ALTERNATIVE: "event-driven if the asymmetry is about workflow rather than read/write patterns"84 -> DON'T USE: "Simple CRUD where reads and writes use the same model"8586ELSE (default):87 -> RECOMMEND: layered88 -> REASONING: "Safe default. Easiest to hire for. Can evolve to modular-monolith or clean-architecture when complexity justifies it."89```9091### Pattern Compatibility Matrix9293| Primary Pattern | Combines Well With | Avoid Combining With |94|----------------|-------------------|---------------------|95| clean-architecture | domain-driven folders, cqrs | flat folders |96| hexagonal | domain-driven folders, event-driven | layer-based folders |97| mvc | layer-based folders | cqrs, event-driven |98| mvvm | feature-based folders | microservices |99| modular-monolith | module-based folders, event-driven | flat folders |100| microservices | event-driven, cqrs | mvc, flat folders |101| serverless | flat or feature-based folders | modular-monolith |102| event-driven | cqrs, microservices, feature-based | mvc |103| cqrs | event-driven, clean-architecture | flat folders, mvc |104| layered | layer-based or feature-based folders | cqrs (overkill) |105106---107108## Folder Structure Examples109110### Backend: feature-based111112```113src/114 features/115 auth/116 auth.controller.ts117 auth.service.ts118 auth.repository.ts119 auth.routes.ts120 auth.types.ts121 __tests__/122 auth.service.test.ts123 orders/124 orders.controller.ts125 orders.service.ts126 orders.repository.ts127 orders.routes.ts128 orders.types.ts129 __tests__/130 orders.service.test.ts131 shared/132 middleware/133 auth.middleware.ts134 error.middleware.ts135 utils/136 types/137 config/138 env.ts139 index.ts140```141142### Backend: layer-based143144```145src/146 controllers/147 auth.controller.ts148 orders.controller.ts149 services/150 auth.service.ts151 orders.service.ts152 repositories/153 auth.repository.ts154 orders.repository.ts155 models/156 user.model.ts157 order.model.ts158 routes/159 auth.routes.ts160 orders.routes.ts161 middleware/162 auth.middleware.ts163 error.middleware.ts164 config/165 env.ts166 index.ts167```168169### Backend: domain-driven (clean-architecture / hexagonal)170171```172src/173 domain/174 entities/175 user.ts176 order.ts177 value-objects/178 email.ts179 money.ts180 repositories/181 user.repository.ts # Interface only182 order.repository.ts # Interface only183 errors/184 not-found.error.ts185 validation.error.ts186 application/187 use-cases/188 create-order.use-case.ts189 get-user.use-case.ts190 dto/191 create-order.dto.ts192 infrastructure/193 persistence/194 prisma-user.repository.ts # Implements domain interface195 prisma-order.repository.ts196 external/197 stripe.adapter.ts198 email.adapter.ts199 presentation/200 controllers/201 orders.controller.ts202 middleware/203 auth.middleware.ts204 error.middleware.ts205 routes/206 orders.routes.ts207 config/208 env.ts209 index.ts210```211212### Backend: module-based (modular-monolith)213214```215src/216 modules/217 auth/218 index.ts # Public API (barrel export)219 auth.service.ts220 auth.repository.ts221 auth.routes.ts222 __tests__/223 billing/224 index.ts225 billing.service.ts226 billing.repository.ts227 billing.routes.ts228 __tests__/229 orders/230 index.ts231 orders.service.ts232 orders.repository.ts233 orders.routes.ts234 __tests__/235 shared/236 middleware/237 utils/238 config/239 index.ts240```241242Cross-module imports go through `index.ts` only. Direct imports of internal files across modules are a violation.243244### Backend: flat245246```247src/248 auth.ts249 orders.ts250 billing.ts251 db.ts252 middleware.ts253 types.ts254 index.ts255```256257Suitable only for serverless functions, small CLIs, or prototypes with < 5 files.258259### Frontend: Next.js App Router (feature-based)260261```262src/263 app/264 (auth)/265 login/page.tsx266 register/page.tsx267 (dashboard)/268 layout.tsx269 page.tsx270 orders/page.tsx271 features/272 auth/273 hooks/use-auth.ts274 components/login-form.tsx275 api/auth.api.ts276 orders/277 hooks/use-orders.ts278 components/order-list.tsx279 api/orders.api.ts280 components/281 ui/282 button.tsx283 input.tsx284 lib/285 api-client.ts286 utils.ts287 store/288 auth.store.ts289```290291### Frontend: React SPA (Vite, feature-based)292293```294src/295 features/296 auth/297 pages/login.tsx298 hooks/use-auth.ts299 components/login-form.tsx300 api/auth.api.ts301 orders/302 pages/order-list.tsx303 hooks/use-orders.ts304 components/order-card.tsx305 api/orders.api.ts306 components/307 ui/308 layout/309 lib/310 api-client.ts311 router.tsx312 store/313 App.tsx314 main.tsx315```316317### Mobile: React Native / Expo (feature-based)318319```320src/321 features/322 auth/323 screens/login-screen.tsx324 hooks/use-auth.ts325 components/login-form.tsx326 api/auth.api.ts327 orders/328 screens/order-list-screen.tsx329 hooks/use-orders.ts330 components/order-card.tsx331 api/orders.api.ts332 components/333 ui/334 navigation/335 root-navigator.tsx336 auth-navigator.tsx337 services/338 storage.ts339 notifications.ts340 biometrics.ts341 lib/342 api-client.ts343 store/344 auth.store.ts345 App.tsx346```347348---349350## Coding Conventions351352### Naming Conventions by Folder Convention353354| Convention | File Naming | Class / Function | Exports |355|-----------|-------------|-----------------|---------|356| feature-based | `{feature}.{layer}.ts` (e.g., `orders.service.ts`) | `OrdersService`, `createOrder` | Named exports per file |357| layer-based | `{entity}.{layer}.ts` (e.g., `order.controller.ts`) | `OrderController`, `OrderService` | Named exports per file |358| domain-driven | `{concept}.ts` in layer directory | `Order` (entity), `CreateOrderUseCase` | Named exports per file |359| module-based | `{module}/{layer}.ts` | `AuthService`, `BillingService` | Barrel exports via `index.ts` |360| flat | `{feature}.ts` | `createOrder`, `authenticateUser` | Named exports per file |361362### Dependency Rules by Architecture Pattern363364| Pattern | Allowed Import Direction | Violation Example |365|---------|------------------------|-------------------|366| **clean-architecture** | presentation -> application -> domain (never reverse) | Domain importing Express types |367| **hexagonal** | adapters -> ports -> domain (never reverse) | Domain importing Prisma client |368| **layered** | controllers -> services -> repositories (never reverse) | Repository importing controller |369| **modular-monolith** | Within module: any direction. Cross-module: public API (`index.ts`) only | Module A importing Module B's internal service |370| **mvc** | views -> controllers -> models (never reverse) | Model importing view logic |371| **mvvm** | view -> viewmodel -> model (never reverse) | Model importing view state |372373---374375## Error Handling Patterns376377Application-level error handling for structuring, propagating, and responding to errors. For security error mitigations (OWASP, rate limiting, input sanitization), see `operational-patterns`.378379### Standard Error Response Shape380381```typescript382interface AppError {383 code: string; // Machine-readable: "ORDER_NOT_FOUND", "VALIDATION_FAILED"384 message: string; // Human-readable: "Order not found"385 details?: unknown; // Validation errors array, debug context386 requestId: string; // For support correlation387}388```389390### Error Handling Strategy by Pattern391392| Pattern | Strategy | Implementation |393|---------|----------|---------------|394| **layered / mvc** | Try-catch in controllers, centralized error middleware | Express `app.use((err, req, res, next) => ...)` catches all |395| **clean-architecture** | Domain errors as typed classes, use-case catches and maps to application errors | `OrderNotFoundError extends DomainError`, use-case returns `Result<T, E>` |396| **hexagonal** | Port defines error types, adapter catches infrastructure errors and maps to port errors | Database timeout -> `RepositoryUnavailableError` |397| **event-driven** | Dead letter queue for unprocessable events, structured error events | Failed event -> DLQ, log for replay. See `architecture-methodology` invariant on at-least-once processing. |398| **serverless** | Return structured error response, let platform handle retries | `{ statusCode: 500, body: JSON.stringify(appError) }` |399| **microservices** | Each service returns domain error codes, API gateway maps to HTTP | gRPC status codes -> HTTP status codes at gateway |400401### Domain Error to HTTP Status Mapping402403| Domain Error Type | HTTP Status | When |404|------------------|-------------|------|405| `ValidationError` | 400 | Input fails schema or business rule validation |406| `AuthenticationError` | 401 | Missing, expired, or invalid credentials |407| `ForbiddenError` | 403 | Valid auth but insufficient permissions |408| `NotFoundError` | 404 | Entity does not exist or is not accessible |409| `ConflictError` | 409 | Duplicate resource, idempotency key collision |410| `RateLimitError` | 429 | Too many requests |411| `ExternalServiceError` | 502 | Upstream dependency failed |412| `UnexpectedError` | 500 | Unhandled exception (log full stack, return generic message) |413414### Error Propagation Rules415416- Never expose stack traces or internal error details in production responses417- Log the full error server-side (with `requestId`), return sanitized `AppError` to the client418- Distinguish client errors (4xx — don't retry) from server errors (5xx — may retry with backoff)419- Use `requestId` for cross-service correlation. See `operational-patterns` structured logging for format.420- For async errors, route to dead letter queue. See `architecture-methodology` invariant on at-least-once processing with DLQ.421- Frontend: use error boundaries (React) or global error handlers to catch rendering errors without crashing the app422423---424425## Testing Strategy Patterns426427### Testing Pyramid by Architecture Pattern428429| Pattern | Unit Tests | Integration Tests | E2E Tests | Contract Tests | Ratio |430|---------|-----------|------------------|----------|---------------|-------|431| **layered / mvc** | Service logic, validators | API endpoints (supertest) | Critical user flows | N/A | 70 / 20 / 10 |432| **clean-architecture** | Use cases, domain entities | Adapters against real DB | Critical user flows | N/A | 60 / 30 / 10 |433| **modular-monolith** | Per-module service logic | Per-module API + cross-module | Critical cross-module flows | Between modules | 50 / 25 / 10 / 15 |434| **microservices** | Per-service logic | Intra-service with test DB | Cross-service critical paths | Between services (Pact) | 50 / 20 / 10 / 20 |435| **event-driven** | Event handlers, validators | Event processing pipeline | End-to-end event flows | Event schema validation | 50 / 20 / 10 / 20 |436| **serverless** | Function logic | With local emulator (SAM) | Deployed endpoint smoke tests | N/A | 60 / 30 / 10 |437438### What to Test Where439440| Layer | What to Test | What NOT to Test | Tooling |441|-------|-------------|-----------------|---------|442| **Domain / business logic** | Rules, calculations, state transitions, edge cases | Framework code, database queries | Jest, Vitest, pytest |443| **API endpoints** | Request/response contracts, auth, validation, status codes | Internal service implementation | Supertest, httpx, Playwright API |444| **Database** | Migrations, complex queries, indexes, constraints | Simple CRUD operations | Testcontainers, in-memory SQLite |445| **External integrations** | Contract compliance, error handling for failures | Third-party uptime or correctness | MSW (mocks), Pact (contracts) |446| **Frontend components** | User interactions, conditional rendering, form validation | Styling, pixel-level layout | Testing Library, Storybook |447| **E2E flows** | Critical user journeys (signup, checkout, payment) | Every possible path | Playwright, Cypress |448449### Testing Strategy Templates450451Use these templates when populating the `testing_strategy` manifest field:452453**MVP / simple app:**454> Unit tests for business logic (Jest/Vitest). Integration tests for API endpoints (supertest). No E2E yet. Coverage target: 60%. Run in CI on every PR.455456**Multi-service production:**457> Unit tests for domain logic per service. Integration tests per service with test database. Contract tests between services (Pact). E2E for critical user flows (Playwright). Coverage target: 80%. Run in CI, E2E on staging deploy.458459**Event-driven / async:**460> Unit tests for event handlers and validators. Integration tests for event processing pipeline. Schema validation tests for event contracts. DLQ monitoring as implicit regression detection. Coverage target: 70%.461462---463464## Frontend-Specific Patterns465466### State Management Selection467468```469IF app has < 5 pages AND minimal shared state:470 -> RECOMMEND: React useState + Context471 -> REASONING: "No extra dependencies. Sufficient for simple apps. Upgrade when state gets complex."472 -> DON'T USE: "Redux, Zustand — overkill at this scale"473474ELSE IF primary state is server data (CRUD app, dashboard, admin panel):475 -> RECOMMEND: React Query / TanStack Query (server state) + Zustand (client state)476 -> REASONING: "Server cache is not client state. React Query handles caching, revalidation, loading states. Zustand for UI-only state (modals, sidebar)."477478ELSE IF complex client-side state (collaborative editor, form builder, drag-and-drop):479 -> RECOMMEND: Zustand or Redux Toolkit480 -> REASONING: "Need predictable state updates, middleware, devtools, undo/redo support."481482ELSE IF Next.js App Router with server components:483 -> RECOMMEND: Server components for data fetching + Zustand for client state484 -> REASONING: "Server components eliminate client state for read data. Zustand handles remaining interactive state."485486ELSE IF Vue / Nuxt:487 -> RECOMMEND: Pinia488 -> REASONING: "Official Vue state management. Composable, typed, devtools integrated."489```490491### Component Architecture492493| Pattern | When to Use | Structure |494|---------|------------|-----------|495| **Feature components** | Feature-scoped, self-contained units | Feature folder with `components/`, `hooks/`, `api/` |496| **Presentational + Container** | Clear data/UI separation needed | Container fetches data, presentational renders props |497| **Compound components** | Complex UI with shared state (Accordion, Tabs, Menu) | Parent provides context, children consume via hooks |498| **Headless hooks** | Reusable logic across different UIs | Logic in custom hooks, no rendered UI (e.g., `useAuth`, `usePagination`) |499500### Data Fetching Patterns501502| Pattern | When to Use | Implementation |503|---------|------------|---------------|504| **Server Components (RSC)** | Next.js App Router, data needed on initial render | `async function Page()` with direct `fetch` or DB query |505| **Client-side fetching** | Interactive data, user-triggered queries | React Query `useQuery` / `useMutation` |506| **SSR + hydration** | SEO-critical pages with interactivity | Next.js `getServerSideProps` or loader functions |507| **Optimistic updates** | Instant UI feedback (likes, toggles, status changes) | React Query `onMutate` — update cache before server confirms |508| **Infinite scroll / pagination** | Long lists, feeds, search results | React Query `useInfiniteQuery` with cursor-based pagination |509510---511512## Mobile-Specific Patterns513514### Offline-First Architecture515516| Requirement | Strategy | Implementation |517|-------------|----------|---------------|518| **Read-only offline** (view cached data) | Cache-first with background sync | MMKV / AsyncStorage + stale-while-revalidate fetch pattern |519| **Write-while-offline** (create/edit offline) | Local-first writes + sync queue | MMKV writes + background sync queue + server reconciliation on reconnect |520| **Full offline capability** | Local database + sync engine | WatermelonDB or Expo SQLite + custom sync protocol with conflict resolution |521522Default recommendation: start with read-only offline caching. Add write-offline only when user research confirms the need.523524### Navigation Pattern Selection525526| App Type | Pattern | Implementation |527|----------|---------|---------------|528| **Tab-based** (social, marketplace, dashboard) | Bottom tabs + stack per tab | Expo Router tabs or React Navigation bottom tabs |529| **Flow-based** (onboarding, checkout, multi-step forms) | Stack navigation with progress indicator | Stack navigator with step-aware header |530| **Drawer-based** (admin panels, settings-heavy apps) | Drawer + nested stacks | Drawer navigator with stack navigators per section |531| **Deep-link driven** (content apps, shared URLs) | URL-based file routing | Expo Router (file-based routing with deep link support) |532533### Platform Abstraction Layer534535Create a `services/` directory with platform-agnostic interfaces for capabilities that differ across platforms:536537| Service | What It Abstracts | Example Implementations |538|---------|------------------|------------------------|539| `storage.ts` | Secure key-value storage | Expo SecureStore, MMKV, AsyncStorage |540| `notifications.ts` | Push notification registration and handling | Expo Notifications, Firebase Cloud Messaging |541| `biometrics.ts` | Biometric authentication | Expo LocalAuthentication |542| `camera.ts` | Camera and image capture | Expo Camera, react-native-image-picker |543544Same principle as hexagonal architecture ports/adapters: feature code depends on the interface, not the platform implementation. Swap implementations without changing feature code.545546---547548## Choosing Patterns for a Blueprint549550Quick-reference table for selecting the full `application_patterns` block based on project profile:551552| Project Profile | Architecture | Folder Convention | Error Handling | Testing Strategy |553|----------------|-------------|-------------------|---------------|-----------------|554| **Simple CRUD API** | layered | layer-based | Centralized error middleware + status code mapping | Unit + integration (70/30) |555| **SaaS with complex domain** | clean-architecture | domain-driven | Typed domain errors + use-case mapping + error middleware | Unit + integration + contract (60/30/10) |556| **Modular product (pre-microservices)** | modular-monolith | module-based | Per-module error codes + shared error middleware | Unit + integration per module + cross-module contract |557| **Event-driven system** | event-driven | feature-based | DLQ + structured error events + retry with backoff | Handler unit + schema validation + pipeline integration |558| **Serverless API** | serverless | flat | Structured error responses per function | Function unit + emulator integration (60/40) |559| **Mobile app** | mvvm | feature-based | Error boundaries + retry on network failure | Component unit + integration + E2E critical flows |560| **Full-stack Next.js** | layered | feature-based | Server action errors + error.tsx boundaries + API error middleware | RSC + API + Playwright E2E |561562For security architecture decisions, see `operational-patterns`. For infrastructure and tooling decisions (cloud, database, auth, hosting), see `prescriptive-decision-framework`. For domain-specific depth (multi-tenant isolation, payment flows, AI orchestration), see `product-type-detector` templates. To evaluate your chosen patterns against quality standards, see `well-architected`.