Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 61 additions & 24 deletions architectures/clean-architecture/implementation-guide.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
---
technology: Clean-architecture
domain: architecture
technology: Clean Architecture
domain: Architecture
level: Senior/Architect
version: Latest
tags: [architecture, best-practices]
tags: [architecture, clean-architecture, best-practices]
ai_role: System Architect
last_updated: 2026-03-22
description: AI agent blueprint constraint
topic: Clean-architecture
complexity: Architect
last_evolution: 2026-03-22
vibe_coding_ready: true
---

# 🛠️ Clean Architecture Implementation Guide

<div align="center">
**Executable blueprints and constraints for AI-agent code generation.**
</div>

---
description: Vibe coding guidelines and architectural constraints for Clean Architecture within the Architecture domain.
tags: [clean-architecture, architecture, best-practices, architecture]
topic: Clean Architecture
complexity: Architect
last_evolution: 2026-03-29
vibe_coding_ready: true
technology: Clean Architecture
domain: Architecture
level: Senior/Architect
version: Latest
ai_role: Senior Clean Architecture Expert
last_updated: 2026-03-29---# Clean Architecture - Implementation Guide
## Code patterns and Anti-patterns
## 💻 Code Patterns and Anti-patterns

### Entity Relationships
### 🧩 Entity Relationships

```mermaid
classDiagram
Expand All @@ -47,5 +36,53 @@ classDiagram
```

### Rules
- Dependency Inversion Principle must be strictly followed.
- Entities encapsulate the most general and high-level rules.
- **Dependency Inversion Principle** must be strictly followed. Dependencies must only point inward toward the core domain.
- **Entities** encapsulate the most general and high-level business rules. They must not depend on any outer layers.

---
## ⚡ The Vibe Coding Instructions (Constraints)

### ❌ Bad Practice
```typescript
import { S3Client } from 'aws-sdk';
import { UserEntity } from '../domain/UserEntity';

export class UploadUserAvatarUseCase {
constructor(private readonly s3Client: S3Client) {}

public async execute(user: UserEntity, fileBuffer: Buffer): Promise<string> {
const uploadResult = await this.s3Client.upload({
Bucket: 'user-avatars',
Key: `${user.id}-avatar.png`,
Body: fileBuffer
}).promise();

return uploadResult.Location;
}
}
```

### ⚠️ Problem
The Use Case (Application layer) depends directly on an external infrastructure dependency (`aws-sdk`). This violates the Dependency Rule. The Use Case cannot be tested without mocking AWS, and changing the storage provider (e.g., to Google Cloud Storage) requires modifying the core business logic.

### ✅ Best Practice
```typescript
import { UserEntity } from '../domain/UserEntity';
import { IFileStoragePort } from '../ports/IFileStoragePort';

export class UploadUserAvatarUseCase {
constructor(private readonly fileStorage: IFileStoragePort) {}

public async execute(user: UserEntity, fileBuffer: Buffer): Promise<string> {
const avatarUrl = await this.fileStorage.uploadFile(
`${user.id}-avatar.png`,
fileBuffer
);

return avatarUrl;
}
}
```

### 🚀 Solution
By using the **Dependency Inversion Principle**, the Application layer defines an abstract interface (`IFileStoragePort`) that dictates its needs. The Infrastructure layer implements this interface (e.g., `S3FileStorageAdapter`). The Use Case is fully decoupled from the external framework, making it easily testable and agnostic to the storage provider.
67 changes: 58 additions & 9 deletions architectures/cqrs/implementation-guide.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
---
description: Vibe coding guidelines and architectural constraints for CQRS within the Architecture domain.
tags: [cqrs, architecture, best-practices, architecture]
topic: CQRS
complexity: Architect
last_evolution: 2026-03-29
vibe_coding_ready: true
technology: CQRS
domain: Architecture
level: Senior/Architect
version: Latest
tags: [cqrs, architecture, best-practices]
ai_role: Senior CQRS Expert
last_updated: 2026-03-29---# CQRS - Implementation Guide
## Code patterns and Anti-patterns
last_updated: 2026-03-29
---

# 🛠️ CQRS Implementation Guide

<div align="center">
**Executable blueprints and constraints for AI-agent code generation.**
</div>

### Entity Relationships
---
## 💻 Code Patterns and Anti-patterns

### 🧩 Entity Relationships

```mermaid
classDiagram
Expand All @@ -36,3 +40,48 @@ classDiagram
### Rules
- Never return business data from a Command (only ack or id).
- Queries must never mutate state.

---
## ⚡ The Vibe Coding Instructions (Constraints)

### ❌ Bad Practice
```typescript
import { Database } from '../infrastructure/Database';

export class CreateUserCommandHandler {
constructor(private readonly db: Database) {}

async handle(command: CreateUserCommand): Promise<User> {
// Mutating State
const user = new User(command.name, command.email);
await this.db.users.save(user);

// BAD: Returning full business data from a command
return user;
}
}
```

### ⚠️ Problem
Returning the full entity or business data from a Command Handler breaks the fundamental rule of CQS/CQRS: **A method should either change state (Command) or return data (Query), but not both.** Returning data couples the mutation logic with read requirements, making it harder to optimize reads and writes independently, and breaking the single responsibility principle.

### ✅ Best Practice
```typescript
import { Database } from '../infrastructure/Database';

export class CreateUserCommandHandler {
constructor(private readonly db: Database) {}

async handle(command: CreateUserCommand): Promise<string> {
// Mutating State
const user = new User(command.name, command.email);
await this.db.users.save(user);

// GOOD: Returning only the ID (or an acknowledgment)
return user.id;
}
}
```

### 🚀 Solution
Strictly separate Commands and Queries. A Command Handler should only return a success acknowledgment or the unique identifier of the newly created resource. If the client needs the full entity data, it should subsequently issue a separate Query (e.g., `GetUserQuery`) using the returned ID. This ensures independent scaling and maintainability of the read and write models.
65 changes: 57 additions & 8 deletions architectures/hexagonal-architecture/implementation-guide.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
---
description: Hexagonal Architecture Implementation Guide rules. Defining the exact code constraints for Vibe Coding and AI.
technology: Hexagonal Architecture
domain: Architecture
level: Senior/Architect
version: Agnostic
tags: [best-practices, implementation-guide, hexagonal-architecture, ports-and-adapters]
ai_role: Senior Software Architect
last_updated: 2026-03-22
topic: Hexagonal Architecture
complexity: Architect
last_evolution: 2026-03-29
vibe_coding_ready: true---
---

# 🛠️ Hexagonal Architecture Implementation Guide

Expand Down Expand Up @@ -168,14 +164,67 @@ export class UserController {
}
```

---

### ❌ Bad Practice
[Need to fill in example of non-optimal code]
```typescript
// BAD: Core Domain entity directly coupled to a database ORM framework
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity('users')
export class User {
@PrimaryGeneratedColumn('uuid')
public id: string;

@Column()
public email: string;

@Column()
public status: 'ACTIVE' | 'INACTIVE';

public deactivate(): void {
this.status = 'INACTIVE';
}
}
```

### ⚠️ Problem
[Analysis of the risks]
The Core Domain entity (`User`) is polluted with database-specific decorators (`@Entity`, `@Column`) from an external library (`typeorm`). This tightly couples the business logic to a specific ORM and database technology. If you want to change the database or ORM later, you must rewrite the core business logic. Furthermore, the domain entity cannot be easily tested in isolation without setting up the ORM environment.

### ✅ Best Practice
```typescript
// GOOD: Core Domain is purely business logic, decoupled from infrastructure
export class User {
private _id: string;
private _email: string;
private _status: 'ACTIVE' | 'INACTIVE';

constructor(id: string, email: string) {
this._id = id;
this._email = email;
this._status = 'ACTIVE';
}

public deactivate(): void {
this._status = 'INACTIVE';
}
}

// Data Mapper handles translating to/from the external ORM
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity('users')
export class UserOrmEntity {
@PrimaryGeneratedColumn('uuid')
public id: string;

@Column()
public email: string;

@Column()
public status: 'ACTIVE' | 'INACTIVE';
}
```

### 🚀 Solution
[Architectural justification of the solution]
Keep the Core Domain completely pure and agnostic of any external frameworks, databases, or UI. Use mapping layers (`Adapters`) to translate the pure Domain Entities to and from database-specific representations (like ORM entities or raw SQL rows). This ensures the business logic remains portable, independently testable, and strictly focused on business rules.
Loading