architecture-review

Architecture Review Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "architecture-review" with this command: npx skills add decebals/claude-code-java/decebals-claude-code-java-architecture-review

Architecture Review Skill

Analyze project structure at the macro level - packages, modules, layers, and boundaries.

When to Use

  • User asks "review the architecture" / "check project structure"

  • Evaluating package organization

  • Checking dependency direction between layers

  • Identifying architectural violations

  • Assessing clean/hexagonal architecture compliance

Quick Reference: Architecture Smells

Smell Symptom Impact

Package-by-layer bloat service/ with 50+ classes Hard to find related code

Domain → Infra dependency Entity imports @Repository

Core logic tied to framework

Circular dependencies A → B → C → A Untestable, fragile

God package util/ or common/ growing Dump for misplaced code

Leaky abstractions Controller knows SQL Layer boundaries violated

Package Organization Strategies

Package-by-Layer (Traditional)

com.example.app/ ├── controller/ │ ├── UserController.java │ ├── OrderController.java │ └── ProductController.java ├── service/ │ ├── UserService.java │ ├── OrderService.java │ └── ProductService.java ├── repository/ │ ├── UserRepository.java │ ├── OrderRepository.java │ └── ProductRepository.java └── model/ ├── User.java ├── Order.java └── Product.java

Pros: Familiar, simple for small projects Cons: Scatters related code, doesn't scale, hard to extract modules

Package-by-Feature (Recommended)

com.example.app/ ├── user/ │ ├── UserController.java │ ├── UserService.java │ ├── UserRepository.java │ └── User.java ├── order/ │ ├── OrderController.java │ ├── OrderService.java │ ├── OrderRepository.java │ └── Order.java └── product/ ├── ProductController.java ├── ProductService.java ├── ProductRepository.java └── Product.java

Pros: Related code together, easy to extract, clear boundaries Cons: May need shared kernel for cross-cutting concerns

Hexagonal/Clean Architecture

com.example.app/ ├── domain/ # Pure business logic (no framework imports) │ ├── model/ │ │ └── User.java │ ├── port/ │ │ ├── in/ # Use cases (driven) │ │ │ └── CreateUserUseCase.java │ │ └── out/ # Repositories (driving) │ │ └── UserRepository.java │ └── service/ │ └── UserDomainService.java ├── application/ # Use case implementations │ └── CreateUserService.java ├── adapter/ │ ├── in/ │ │ └── web/ │ │ └── UserController.java │ └── out/ │ └── persistence/ │ ├── UserJpaRepository.java │ └── UserEntity.java └── config/ └── BeanConfiguration.java

Key rule: Dependencies point inward (adapters → application → domain)

Dependency Direction Rules

The Golden Rule

┌─────────────────────────────────────────┐ │ Frameworks │ ← Outer (volatile) ├─────────────────────────────────────────┤ │ Adapters (Web, DB) │ ├─────────────────────────────────────────┤ │ Application Services │ ├─────────────────────────────────────────┤ │ Domain (Core Logic) │ ← Inner (stable) └─────────────────────────────────────────┘

Dependencies MUST point inward only. Inner layers MUST NOT know about outer layers.

Violations to Flag

// ❌ Domain depends on infrastructure package com.example.domain.model;

import org.springframework.data.jpa.repository.JpaRepository; // Framework leak! import javax.persistence.Entity; // JPA in domain!

@Entity public class User { // Domain polluted with persistence concerns }

// ❌ Domain depends on adapter package com.example.domain.service;

import com.example.adapter.out.persistence.UserJpaRepository; // Wrong direction!

// ✅ Domain defines port, adapter implements package com.example.domain.port.out;

public interface UserRepository { // Pure interface, no JPA User findById(UserId id); void save(User user); }

Architecture Review Checklist

  1. Package Structure
  • Clear organization strategy (by-layer, by-feature, or hexagonal)

  • Consistent naming across modules

  • No util/ or common/ packages growing unbounded

  • Feature packages are cohesive (related code together)

  1. Dependency Direction
  • Domain has ZERO framework imports (Spring, JPA, Jackson)

  • Adapters depend on domain, not vice versa

  • No circular dependencies between packages

  • Clear dependency hierarchy

  1. Layer Boundaries
  • Controllers don't contain business logic

  • Services don't know about HTTP (no HttpServletRequest)

  • Repositories don't leak into controllers

  • DTOs at boundaries, domain objects inside

  1. Module Boundaries
  • Each module has clear public API

  • Internal classes are package-private

  • Cross-module communication through interfaces

  • No "reaching across" modules for internals

  1. Scalability Indicators
  • Could extract a feature to separate service? (microservice-ready)

  • Are boundaries enforced or just conventional?

  • Does adding a feature require touching many packages?

Common Anti-Patterns

  1. The Big Ball of Mud

src/main/java/com/example/ └── app/ ├── User.java ├── UserController.java ├── UserService.java ├── UserRepository.java ├── Order.java ├── OrderController.java ├── ... (100+ files in one package)

Fix: Introduce package structure (start with by-feature)

  1. The Util Dumping Ground

util/ ├── StringUtils.java ├── DateUtils.java ├── ValidationUtils.java ├── SecurityUtils.java ├── EmailUtils.java # Should be in notification module ├── OrderCalculator.java # Should be in order domain └── UserHelper.java # Should be in user domain

Fix: Move domain logic to appropriate modules, keep only truly generic utils

  1. Anemic Domain Model

// Domain object is just data public class Order { private Long id; private List<OrderLine> lines; private BigDecimal total; // Only getters/setters, no behavior }

// All logic in "service" public class OrderService { public void addLine(Order order, Product product, int qty) { ... } public void calculateTotal(Order order) { ... } public void applyDiscount(Order order, Discount discount) { ... } }

Fix: Move behavior to domain objects (rich domain model)

  1. Framework Coupling in Domain

package com.example.domain;

@Entity // JPA @Data // Lombok @JsonIgnoreProperties(ignoreUnknown = true) // Jackson public class User { @Id @GeneratedValue private Long id;

@NotBlank  // Validation
private String email;

}

Fix: Separate domain model from persistence/API models

Analysis Commands

When reviewing architecture, examine:

Package structure overview

find src/main/java -type d | head -30

Largest packages (potential god packages)

find src/main/java -name "*.java" | xargs dirname | sort | uniq -c | sort -rn | head -10

Check for framework imports in domain

grep -r "import org.springframework" src/main/java//domain/ 2>/dev/null grep -r "import javax.persistence" src/main/java//domain/ 2>/dev/null

Find circular dependencies (look for bidirectional imports)

Check if package A imports from B and B imports from A

Recommendations Format

When reporting findings:

Architecture Review: [Project Name]

Structure Assessment

  • Organization: Package-by-layer / Package-by-feature / Hexagonal
  • Clarity: Clear / Mixed / Unclear

Findings

SeverityIssueLocationRecommendation
HighDomain imports Springdomain/model/User.javaExtract pure domain model
MediumGod packageutil/ (23 classes)Distribute to feature modules
LowInconsistent namingservice/ vs services/Standardize to service/

Dependency Analysis

[Describe dependency flow, violations found]

Recommendations

  1. [Highest priority fix]
  2. [Second priority]
  3. [Nice to have]

Token Optimization

For large codebases:

  • Start with find to understand structure

  • Check only domain package for framework imports

  • Sample 2-3 features for pattern analysis

  • Don't read every file - look for patterns

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

java-code-review

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

clean-code

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

spring-boot-patterns

No summary provided by upstream source.

Repository SourceNeeds Review