npx claudepluginhub martinffx/atelier --plugin pythonThis skill uses the workspace's default tool permissions.
Modern Python application architecture following functional core / imperative shell pattern, Domain-Driven Design, and type-safe data modeling.
Implements Clean Architecture, Hexagonal Architecture (Ports & Adapters), and Domain-Driven Design patterns in Python FastAPI/Flask apps for layered backends, repository patterns, entities/value objects, and testable domain logic.
Implements Clean Architecture, Hexagonal Architecture, and Domain-Driven Design for backend systems. Use for architecting complex apps or refactoring monoliths for maintainability.
Designs features using DDD, hexagonal architecture, and functional core patterns. Guides domain modeling, task breakdown, and component responsibility assignment.
Share bugs, ideas, or general feedback.
Modern Python application architecture following functional core / imperative shell pattern, Domain-Driven Design, and type-safe data modeling.
Separate pure business logic from side effects:
See references/functional-core.md for detailed patterns and examples.
Follow bottom-up dependency flow:
Router/Handler → Service → Repository → Entity → Database
Each layer depends only on layers below.
Responsibilities:
from dataclasses import dataclass
from uuid import UUID
from decimal import Decimal
@dataclass
class Order:
"""Entity - has identity and encapsulated behavior"""
id: UUID
customer_id: UUID
total: Decimal
status: str
def apply_discount(self, rate: Decimal) -> None:
"""Business rule - encapsulated in entity"""
if self.status == "pending":
self.total = self.total * (1 - rate)
@classmethod
def from_request(cls, req, customer_id: UUID) -> "Order":
"""Transform API request → entity"""
return cls(id=uuid4(), customer_id=customer_id, total=Decimal("0"), status="pending")
def to_response(self):
"""Transform entity → API response"""
return {"id": self.id, "total": self.total, "status": self.status}
from dataclasses import dataclass
@dataclass(frozen=True)
class Money:
"""Value object - immutable, no identity"""
amount: Decimal
currency: str
def add(self, other: "Money") -> "Money":
if self.currency != other.currency:
raise ValueError("Cannot add different currencies")
return Money(self.amount + other.amount, self.currency)
See references/ddd.md for aggregates, bounded contexts, and domain services.
Abstract storage behind interface:
from abc import ABC, abstractmethod
from typing import Optional
class OrderRepository(ABC):
"""Abstract repository - interface only"""
@abstractmethod
def get(self, order_id: UUID) -> Optional[Order]:
pass
@abstractmethod
def save(self, order: Order) -> None:
pass
class PostgresOrderRepository(OrderRepository):
"""Concrete implementation"""
def get(self, order_id: UUID) -> Optional[Order]:
record = self.session.get(OrderRecord, order_id)
return Order.from_record(record) if record else None
def save(self, order: Order) -> None:
record = order.to_record()
self.session.merge(record)
self.session.commit()
from_request(), to_response(), from_record(), to_record()See references/data-modeling.md for validation patterns, Pydantic features, and transformation examples.
frozen=True❌ Anemic Domain Model - Entities with only getters/setters, all logic in services ❌ Transaction Script - All logic in service layer, entities just data ❌ Leaky Abstraction - Repository exposing database details ❌ God Object - Entity with too many responsibilities ❌ Mixed Concerns - Business logic calling IO directly
For detailed examples, patterns, and decision trees, see the reference materials: