Skip to content
NeuralSkills
Code Review

Architecture Review

Review code architecture decisions for coupling, cohesion, SOLID principles, and long-term maintainability.

Advanced Free Published: April 15, 2026
Compatible Tools claude-codechatgptgeminicopilotcursorwindsurfuniversal

The Problem

Architecture decisions compound over time. A tightly coupled module that seems fine at 500 lines becomes an unmaintainable monolith at 5,000. Teams ship features without stepping back to evaluate dependency direction, abstraction boundaries, or whether single-responsibility is actually enforced. By the time the architecture pain surfaces, refactoring costs have multiplied tenfold.

The Prompt

Review the architecture of the following codebase. Act as a principal engineer evaluating the system for long-term scalability and maintainability.

CODEBASE CONTEXT: [e.g., "E-commerce checkout service, 3 developers, Node.js/Express"]
FILE STRUCTURE:
[paste directory tree or key file paths]

CODE:
[paste key modules/files]

Evaluate across these architectural dimensions:

1. **SOLID Compliance**
   - Single Responsibility: Does each module/class have one reason to change?
   - Open/Closed: Can behavior be extended without modifying existing code?
   - Liskov Substitution: Are subtypes truly interchangeable?
   - Interface Segregation: Are interfaces lean or bloated?
   - Dependency Inversion: Do high-level modules depend on abstractions?

2. **Coupling Analysis**
   - Map dependencies between modules. Identify circular dependencies.
   - Rate coupling: tight (direct object refs) / loose (interfaces/events) / none.
   - Flag God objects that know too much about other modules.

3. **Cohesion Assessment**
   - Does each module group related functionality?
   - Identify shotgun surgery risks (one change touches 5+ files).
   - Flag utility dumping grounds with unrelated functions.

4. **Abstraction Boundaries**
   - Are layer boundaries clear (controller → service → repository)?
   - Is business logic leaking into transport or persistence layers?
   - Are cross-cutting concerns (auth, logging, validation) centralized?

5. **Evolution Readiness**
   - How painful would it be to swap the database? The framework? Add a new API consumer?
   - Identify vendor lock-in or framework coupling.

For each finding, provide:
- **Location**: Module/file affected
- **Severity**: structural-debt / design-smell / improvement
- **Impact**: What breaks or degrades as the codebase grows
- **Recommendation**: Specific refactoring with before/after sketch

Example Output

## Architecture Review: Checkout Service

### Structural Debt: God Service Pattern
Location: `src/services/OrderService.ts` (847 lines)
Impact: Handles payment, inventory, email, and analytics — any change risks side effects.
Recommendation: Extract into PaymentService, InventoryService, NotificationService.
Each owns its domain logic. OrderService becomes an orchestrator:

  // Before: OrderService.createOrder() does everything
  // After:  OrderService orchestrates
  async createOrder(dto: CreateOrderDTO) {
    const payment = await this.paymentService.charge(dto);
    await this.inventoryService.reserve(dto.items);
    await this.notificationService.sendConfirmation(payment);
  }

### Design Smell: Circular Dependency
Location: UserModule ↔ OrderModule (import each other)
Impact: Cannot test or deploy independently. Bundle splitting impossible.
Recommendation: Extract shared types into a `@shared/types` package.
Use an event bus for cross-module communication.

When to Use

Run this when starting a new project phase, onboarding to an inherited codebase, or before a major feature that will stress existing boundaries. Architecture reviews are most valuable before the codebase doubles in size — they surface the cracks that will become chasms.

Pro Tips

  • Include the file tree — architecture issues live in the relationships between files, not inside them. Always paste or describe the directory structure.
  • Review at the boundary — focus on how modules communicate, not internal implementation. The interface between services reveals more than the code within them.
  • Ask for a dependency graph — request “Draw an ASCII dependency graph showing module relationships” to visualize coupling at a glance.
  • Pair with evolution scenarios — add “How would this architecture handle adding GraphQL alongside REST?” to stress-test flexibility.