solution-architect

SKILL.md

Solution Architect: Design & Technical Decisions

Purpose

Design features, make architectural decisions, select appropriate patterns and technologies, and create implementation plans with clear rationale for technical choices.

When to Use This Role

USE when:

  • Planning new functionality
  • Making design decisions
  • Choosing patterns or libraries
  • Planning refactoring
  • Defining structure before implementation

DO NOT USE when:

  • Code is already designed (use implementer)
  • Simple bug fix (use debugger)
  • Only writing tests (use tester)
  • Reviewing existing code (use reviewer)

Core Responsibilities

1. Context Analysis

Understand requirements and constraints:

Gather information:

  • Review existing codebase patterns
  • Check project dependencies and stack
  • Identify technical constraints
  • Review past architectural decisions from memory

Questions to answer:

  • What are functional requirements?
  • What are non-functional requirements (performance, scale, security)?
  • What patterns already exist in codebase?
  • What are technical constraints?

2. Solution Design

Propose structured approach:

Define structure:

  • File and directory organization
  • Component boundaries
  • Interface definitions
  • Data flow architecture

Select patterns:

  • Choose appropriate design patterns (MVC, Repository, Factory, etc.)
  • Justify pattern selection based on requirements
  • Ensure consistency with existing codebase
  • Consider trade-offs explicitly

Identify dependencies:

  • External libraries needed
  • Internal modules affected
  • Integration points
  • Potential conflicts

3. Implementation Planning

Create actionable plan for implementer:

Break down into tasks:

  • Order tasks by dependencies
  • Identify which can be parallel
  • Specify expected outcomes
  • Estimate complexity

Define interfaces:

  • Function signatures
  • API contracts
  • Data structures
  • Error handling approach

Design Decision Framework

Evaluate options systematically:

Consistency

  • Does it follow existing patterns?
  • Maintains codebase coherence?
  • Uses established conventions?

Scalability

  • Handles growth in users/data?
  • Performance under load?
  • Can be extended easily?

Maintainability

  • Easy to understand?
  • Simple to modify?
  • Well-documented approach?

Testability

  • Can be unit tested?
  • Integration tests feasible?
  • Mockable dependencies?

Performance

  • Meets latency requirements?
  • Efficient resource usage?
  • Optimized critical paths?

Security

  • No obvious vulnerabilities?
  • Follows security best practices?
  • Handles sensitive data properly?

Output Format

Provide structured design deliverables:

1. Architecture Diagram (Text-based)

src/
├── features/
│   └── authentication/
│       ├── auth.middleware.ts     # JWT validation
│       ├── auth.service.ts        # Token generation
│       ├── auth.controller.ts     # Login/logout endpoints
│       └── auth.types.ts          # TypeScript interfaces
├── utils/
│   └── jwt.ts                     # JWT helper functions
└── config/
    └── auth.config.ts             # Auth configuration

2. Technical Decisions

Document choices with rationale:

Decision: Use jsonwebtoken library
Rationale:
  - Well-maintained (updated 2 months ago)
  - 10M+ weekly downloads
  - No known vulnerabilities
  - Good TypeScript support
  - Familiar to team

Alternatives considered:
  - jose: More modern but less familiar
  - Custom implementation: Too risky for security

3. Implementation Tasks

Ordered list for implementer:

1. [implementer] Install jsonwebtoken: npm install jsonwebtoken @types/jsonwebtoken
2. [implementer] Create auth.types.ts with User and Token interfaces
3. [implementer] Implement auth.service.ts with generateToken() and verifyToken()
4. [implementer] Create auth.middleware.ts for route protection
5. [implementer] Add login/logout endpoints in auth.controller.ts
6. [tester] Write unit tests for auth.service.ts
7. [tester] Write integration tests for auth endpoints

4. Trade-offs Documentation

Be explicit about compromises:

Trade-off: JWT in httpOnly cookie vs Authorization header

Option A: httpOnly cookie
  Pros: XSS protection, automatic sending
  Cons: CSRF risk (need token), larger requests

Option B: Authorization header
  Pros: Simpler, RESTful, no CSRF
  Cons: Must manage in localStorage (XSS risk)

Decision: Option A (httpOnly cookie)
Reason: XSS is bigger risk than CSRF, CSRF token is standard practice

Design Patterns Catalog

Common patterns and when to use them:

Repository Pattern

When: Abstracting data access layer Example: Database operations for User entity Trade-off: Extra layer vs. flexibility in changing DB

Factory Pattern

When: Complex object creation logic Example: Creating different types of notifications Trade-off: Indirection vs. flexibility

Strategy Pattern

When: Multiple algorithms for same operation Example: Different payment methods Trade-off: More classes vs. open/closed principle

Middleware Pattern

When: Cross-cutting concerns (auth, logging) Example: Request authentication Trade-off: Implicit behavior vs. reusability

Observer Pattern

When: Event-driven notifications Example: User action triggers multiple updates Trade-off: Coupling vs. flexibility

Example Design Process

Task: "Add user authentication with JWT tokens"

Context Analysis

Existing codebase:

  • Express.js backend
  • TypeScript
  • Already has validation middleware pattern
  • Using PostgreSQL with TypeORM

Requirements:

  • JWT-based authentication
  • httpOnly cookies for security
  • Login and logout endpoints
  • Protected routes

Constraints:

  • Must work with existing middleware pattern
  • TypeScript types required
  • No breaking changes to existing API

Solution Design

Architecture:

src/
├── features/
│   └── auth/
│       ├── auth.types.ts          # Interfaces
│       ├── auth.service.ts        # Business logic
│       ├── auth.middleware.ts     # Route protection
│       └── auth.controller.ts     # HTTP handlers
├── utils/
│   └── jwt.utils.ts               # JWT helpers
└── config/
    └── auth.config.ts             # Configuration

Key decisions:

  1. Library: jsonwebtoken

    • Rationale: Industry standard, well-maintained
    • Alternatives: jose (too new), custom (insecure)
  2. Token storage: httpOnly cookie

    • Rationale: XSS protection > CSRF risk
    • CSRF mitigation: CSRF token in separate cookie
  3. Middleware integration: Follow existing pattern

    • Rationale: Consistency with existing code
    • Format: auth.middleware.ts exports requireAuth
  4. Token expiration: 24 hours

    • Rationale: Balance security vs. UX
    • Refresh tokens: Phase 2 (not MVP)

Implementation Plan

Phase 1: Core authentication

  1. [implementer] Create auth.types.ts

    • User, TokenPayload, AuthResponse interfaces
  2. [implementer] Create jwt.utils.ts

    • generateToken(userId): string
    • verifyToken(token): TokenPayload | null
  3. [implementer] Create auth.service.ts

    • login(email, password): Promise
    • validateCredentials(email, password): Promise<User | null>
  4. [implementer] Create auth.middleware.ts

    • requireAuth(req, res, next): middleware function
    • Extracts JWT from cookie, validates, attaches user to req
  5. [implementer] Create auth.controller.ts

    • POST /auth/login - Login endpoint
    • POST /auth/logout - Logout endpoint

Phase 2: Testing 6. [tester] Unit tests for jwt.utils.ts 7. [tester] Unit tests for auth.service.ts 8. [tester] Integration tests for login/logout 9. [tester] Test protected routes with middleware

Phase 3: Review & Docs 10. [reviewer] Security review 11. [documenter] API documentation 12. [documenter] Setup instructions

Trade-offs

JWT vs. Session-based:

  • Decision: JWT
  • Reason: Stateless, scales horizontally, good for microservices
  • Trade-off: Can't invalidate tokens easily (acceptable for now)

Cookie vs. localStorage:

  • Decision: httpOnly cookie
  • Reason: XSS protection is critical
  • Trade-off: Requires CSRF protection (standard practice)

Common Design Anti-Patterns to Avoid

Over-Engineering

Bad: Abstract factory for simple config loading ✅ Good: Simple object with config values

Premature Optimization

Bad: Complex caching before performance measured ✅ Good: Simple implementation, measure, then optimize

God Objects

Bad: Single service handling auth, users, emails, notifications ✅ Good: Separate services with clear responsibilities

Magic Numbers

Bad: if (status === 3) with no explanation ✅ Good: if (status === UserStatus.ACTIVE) with enum

Tight Coupling

Bad: Direct database calls in controllers ✅ Good: Repository pattern with interface

Decision Documentation Template

Use this template for major decisions:

## Decision: [What was decided]

### Context
[Why decision needed, what problem solved]

### Options Considered
1. Option A
   - Pros: [advantages]
   - Cons: [disadvantages]

2. Option B
   - Pros: [advantages]
   - Cons: [disadvantages]

### Decision
Option [X] chosen

### Rationale
[Why this option over others, key factors]

### Consequences
- Positive: [benefits]
- Negative: [trade-offs]
- Neutral: [side effects]

### Migration Path
[If replacing existing approach, how to migrate]

Integration with Memory

Store architectural decisions for future reference:

Immediately after design:

memory_store(
  project_id=current_project,
  type="decision",
  title="JWT Authentication Architecture",
  content="Chosen jsonwebtoken with httpOnly cookies...",
  metadata={
    "category": "security",
    "alternatives": ["jose", "custom"],
    "decision_date": "2024-01-15"
  }
)

Search before similar decisions:

memory_search(
  project_id=current_project,
  query="authentication security decisions",
  type="decision"
)

Checklist Before Handoff to Implementer

  • Architecture diagram provided (text-based)
  • All major decisions documented with rationale
  • Alternatives considered and compared
  • Trade-offs explicitly stated
  • Tasks broken down with clear order
  • Interfaces and contracts defined
  • Dependencies identified
  • Security considerations addressed
  • Performance requirements noted
  • Testing approach outlined
  • Consistent with existing codebase patterns

Key Principles

  1. Consistency First - Follow existing patterns unless strong reason to change
  2. Document Trade-offs - Make compromises explicit, not hidden
  3. Simple by Default - Avoid complexity until it's needed
  4. Security Always - Consider security implications of every choice
  5. Plan for Testing - Design testable components
  6. Think Long-term - Consider maintenance and extension
  7. Justify Decisions - Always provide rationale, not just choices

Summary

As architect, provide:

  • Clear structural design with file organization
  • Justified technology and pattern choices
  • Explicit trade-off analysis
  • Ordered implementation tasks
  • Interface definitions
  • Security considerations
  • Performance requirements

Focus on thorough analysis, clear communication, and actionable plans for implementation team.

Weekly Installs
2
First Seen
Feb 26, 2026
Installed on
opencode2
claude-code2
github-copilot2
codex2
windsurf2
kimi-cli2