From imersao
Enforce clean architecture principles, SOLID patterns, and scalable code organization. Use when building backends, APIs, microservices, or any application requiring maintainable, testable structure.
How this skill is triggered — by the user, by Claude, or both
Slash command
/imersao:clean-architectureThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Organize by feature/domain, NOT by type:
Organize by feature/domain, NOT by type:
src/
├── modules/
│ ├── users/
│ │ ├── domain/ # Entities, value objects
│ │ ├── application/ # Use cases, DTOs
│ │ ├── infrastructure/ # Repositories, adapters
│ │ └── presentation/ # Controllers
│ └── orders/
├── shared/
│ ├── domain/
│ ├── infrastructure/
│ └── utils/
└── main.ts
S - Single Responsibility: One class = one purpose O - Open/Closed: Extend via interfaces, not modification L - Liskov Substitution: Subtypes replaceable for base types I - Interface Segregation: Many small interfaces > one large D - Dependency Inversion: Depend on abstractions
export class User {
static create(props: CreateUserProps): User {
return new User(generateId(), new Email(props.email), UserStatus.PENDING);
}
activate(): void {
if (this._status !== UserStatus.PENDING) {
throw new DomainError('Cannot activate');
}
this._status = UserStatus.ACTIVE;
}
}
export class CreateUserUseCase {
constructor(
private readonly userRepository: IUserRepository,
private readonly emailService: IEmailService
) {}
async execute(input: CreateUserInput): Promise<CreateUserOutput> {
const existing = await this.userRepository.findByEmail(input.email);
if (existing) throw new UserAlreadyExistsError(input.email);
const user = User.create(input);
await this.userRepository.save(user);
return { id: user.id };
}
}
export class PrismaUserRepository implements IUserRepository {
constructor(private readonly prisma: PrismaClient) {}
async findByEmail(email: string): Promise<User | null> {
const data = await this.prisma.user.findUnique({ where: { email } });
return data ? UserMapper.toDomain(data) : null;
}
}
@Controller('users')
export class UserController {
constructor(private readonly createUser: CreateUserUseCase) {}
@Post()
async create(@Body() dto: CreateUserDto) {
return this.createUser.execute(dto);
}
}
| Type | Pattern | Example |
|---|---|---|
| Entity | PascalCase | User, Order |
| Value Object | Descriptive | Email, Money |
| Use Case | VerbNounUseCase | CreateUserUseCase |
| Repository | INounRepository | IUserRepository |
| Controller | NounController | UserController |
| DTO | NounActionDto | CreateUserDto |
| Error | NounError | UserNotFoundError |
export abstract class DomainError extends Error {
abstract readonly code: string;
}
export class UserNotFoundError extends DomainError {
readonly code = 'USER_NOT_FOUND';
constructor(id: string) {
super(`User ${id} not found`);
}
}
npx claudepluginhub parisgroup-ai/imersao-ia-setup --plugin imersaoProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.