Skip to content
Development
Command

/suggest-refactor

Actionable refactoring suggestions for improving clean architecture compliance in Rust projects

From plugin
claude-command-suite
1.3k199 skills89 agents199 commands
Install
$ npx -y skills add qdhenry/Claude-Command-Suite --agent claude-code

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/suggest-refactor

Context preview

What this command does when you run it.

Actionable refactoring suggestions for improving clean architecture compliance in Rust projects

Command definition

suggest-refactor.md
name: rust:suggest-refactor
description: Actionable refactoring suggestions for improving clean architecture compliance in Rust projects
allowed-tools: Read, Grep, Glob, Bash, Edit
author: Quintin Henry (https://github.com/qdhenry/)

Suggest Clean Architecture Refactoring

Analyze a Rust codebase and provide actionable refactoring suggestions to improve clean architecture compliance, with prioritized recommendations and code examples.

Instructions

Suggest refactoring improvements for: **$ARGUMENTS**

> **Note:** `$ARGUMENTS` can specify focus areas or severity. > Examples: > - `/rust:suggest-refactor` - All suggestions > - `/rust:suggest-refactor --critical` - Only critical issues > - `/rust:suggest-refactor src/application/` - Focus on specific path

---

Refactoring Priority Framework

| Priority | Description | When to Fix | |----------|-------------|-------------| | **P0 - Critical** | Architecture violations blocking testability/maintainability | Immediately | | **P1 - High** | Dependency rule violations | This sprint | | **P2 - Medium** | Missing abstractions, unclear boundaries | Next sprint | | **P3 - Low** | Style, organization improvements | When touching code |

---

Phase 1: Identify Current Issues

1.1 Run Quick Audit

# Domain violations
DOMAIN_VIOLATIONS=$(grep -rn "use crate::adapters\|use crate::infrastructure\|use axum\|use sqlx" src/domain/ 2>/dev/null | wc -l)

# Application violations
APP_VIOLATIONS=$(grep -rn "use crate::adapters\|use crate::infrastructure\|use axum\|use sqlx" src/application/ 2>/dev/null | wc -l)

# Missing ports (concrete types in use cases)
CONCRETE_DEPS=$(grep -rn "Postgres\|Mysql\|Redis\|Pool" src/application/ 2>/dev/null | wc -l)

echo "Domain violations: $DOMAIN_VIOLATIONS"
echo "Application violations: $APP_VIOLATIONS"
echo "Concrete dependencies: $CONCRETE_DEPS"

1.2 Categorize Findings

Group issues by type for prioritized remediation.

---

Phase 2: P0 - Critical Refactorings

2.1 Domain Layer Depends on Outer Layers

**Problem:** Domain imports adapters/infrastructure

**Detection:**

grep -rn "use crate::adapters\|use crate::infrastructure" src/domain/ 2>/dev/null

**Before:**

// src/domain/user.rs
use crate::adapters::db::UserRow;  // VIOLATION

pub struct User {
    // ...
}

impl From<UserRow> for User {
    fn from(row: UserRow) -> Self {
        // Conversion logic
    }
}

**After:**

// src/domain/user.rs
pub struct User {
    // Pure domain entity
}

// Move conversion to adapter
// src/adapters/persistence/user_mapper.rs
use crate::domain::User;

pub fn row_to_user(row: UserRow) -> User {
    User { /* ... */ }
}

**Refactoring Steps:** 1. Remove adapter imports from domain 2. Move conversion logic to adapter layer 3. Ensure domain only has inward dependencies

---

2.2 Application Layer Depends on Concrete Adapters

**Problem:** Use cases depend on concrete implementations instead of traits

**Detection:**

grep -rn "PostgresUserRepository\|Argon2Hasher\|RedisCache" src/application/ 2>/dev/null

**Before:**

// src/application/use_cases/register_user.rs
use crate::adapters::persistence::PostgresUserRepository;
use crate::adapters::crypto::Argon2Hasher;

pub struct RegisterUser {
    repo: PostgresUserRepository,  // Concrete!
    hasher: Argon2Hasher,          // Concrete!
}

**After:**

// src/application/ports/mod.rs
#[async_trait]
pub trait UserRepository: Send + Sync {
    async fn save(&self, user: &User) -> Result<(), RepositoryError>;
    async fn find_by_username(&self, username: &str) -> Result<Option<User>, RepositoryError>;
}

pub trait PasswordHasher: Send + Sync {
    fn hash(&self, password: &str) -> Result<String, HashError>;
}

// src/application/use_cases/register_user.rs
use crate::application::ports::{UserRepository, PasswordHasher};

pub struct RegisterUser {
    repo: Arc<dyn UserRepository>,    // Trait object!
    hasher: Arc<dyn PasswordHasher>,  // Trait object!
}

**Refactoring Steps:** 1. Define port traits in `application/ports/` 2. Update use case to depend on `Arc<dyn Trait>` 3. Update adapter to `impl Trait for ConcreteType` 4. Wire dependencies in infrastructure

---

2.3 Framework Types in Application Layer

**Problem:** HTTP/DB types leaked into use cases

**Detection:**

grep -rn "Json<\|HttpResponse\|StatusCode\|Query<\|Path<\|PgPool" src/application/ 2>/dev/null

**Before:**

// src/application/use_cases/register_user.rs
use axum::Json;
use sqlx::PgPool;

pub async fn execute(pool: &PgPool, input: Json<RegisterInput>) -> Result<Json<UserResponse>, Error> {
    // ...
}

**After:**

// src/application/use_cases/register_user.rs
use crate::domain::User;
use crate::application::{AppError, ports::UserRepository};

impl RegisterUser {
    pub async fn execute(&self, username: String, password: String) -> Result<User, AppError> {
        // Pure application logic
    }
}

// Move HTTP concerns to adapter
// src/adapters/http/handlers.rs
pub async fn register_handler(
    State(state): State<AppState>,
    Json(dto): Json<RegisterDto>,
) -> impl IntoResponse {
    match state.register_user.execute(dto.username, dto.password).await {
        Ok(user) => (StatusCode::CREATED, Json(UserResponse::from(user))),
        Err(e) => e.into_response(),
    }
}

**Refactoring Steps:** 1. Remove framework imports from application layer 2. Use primitive/domain types in use case signatures 3. Create DTOs in adapter layer 4. Handle conversion in HTTP handlers

---

Phase 3: P1 - High Priority Refactorings

3.1 Missing Port Abstraction

**Problem:** Direct external service calls without trait abstraction

**Detection:**

grep -rn "reqwest::\|lettre::\|aws_sdk" src/application/ 2>/dev/null

**Before:**

// src/application/use_cases/send_notification.rs
use reqwest::Client;

pub struct SendNotification {
    client: Client,
}

impl SendN
Read more
Ships withclaude-command-suite

A comprehensive development toolkit designed following Anthropic's Claude Code Best Practices for AI-assisted software development.

Get the whole plugin