From ftitos-claude-code
Design, implement, and refactor Ports & Adapters systems with clear domain boundaries, dependency inversion, and testable use-case orchestration.
npx claudepluginhub nassimbf/ftitos-claude-codeThis skill uses the workspace's default tool permissions.
Hexagonal architecture (Ports and Adapters) keeps business logic independent from frameworks, transport, and persistence details. The core app depends on abstract ports, and adapters implement those ports at the edges.
Expert guidance for Next.js Cache Components and Partial Prerendering (PPR). **PROACTIVE ACTIVATION**: Use this skill automatically when working in Next.js projects that have `cacheComponents: true` in their next.config.ts/next.config.js. When this config is detected, proactively apply Cache Components patterns and best practices to all React Server Component implementations. **DETECTION**: At the start of a session in a Next.js project, check for `cacheComponents: true` in next.config. If enabled, this skill's patterns should guide all component authoring, data fetching, and caching decisions. **USE CASES**: Implementing 'use cache' directive, configuring cache lifetimes with cacheLife(), tagging cached data with cacheTag(), invalidating caches with updateTag()/revalidateTag(), optimizing static vs dynamic content boundaries, debugging cache issues, and reviewing Cache Component implementations.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Share bugs, ideas, or general feedback.
Hexagonal architecture (Ports and Adapters) keeps business logic independent from frameworks, transport, and persistence details. The core app depends on abstract ports, and adapters implement those ports at the edges.
Dependency direction is always inward: Adapters -> Application -> Domain.
src/
features/
orders/
domain/
Order.ts
application/
ports/
inbound/CreateOrder.ts
outbound/OrderRepositoryPort.ts
use-cases/CreateOrderUseCase.ts
adapters/
inbound/http/createOrderRoute.ts
outbound/postgres/PostgresOrderRepository.ts
composition/ordersContainer.ts
export interface OrderRepositoryPort {
save(order: Order): Promise<void>;
findById(orderId: string): Promise<Order | null>;
}
export interface PaymentGatewayPort {
authorize(input: { orderId: string; amountCents: number }): Promise<{ authorizationId: string }>;
}
export class CreateOrderUseCase {
constructor(
private readonly orderRepository: OrderRepositoryPort,
private readonly paymentGateway: PaymentGatewayPort
) {}
async execute(input: CreateOrderInput): Promise<CreateOrderOutput> {
const order = Order.create({ id: input.orderId, amountCents: input.amountCents });
const auth = await this.paymentGateway.authorize({
orderId: order.id, amountCents: order.amountCents,
});
const authorizedOrder = order.markAuthorized(auth.authorizationId);
await this.orderRepository.save(authorizedOrder);
return { orderId: order.id, authorizationId: auth.authorizationId };
}
}
export const buildCreateOrderUseCase = (deps: { db: SqlClient; stripe: StripeClient }) => {
const orderRepository = new PostgresOrderRepository(deps.db);
const paymentGateway = new StripePaymentGateway(deps.stripe);
return new CreateOrderUseCase(orderRepository, paymentGateway);
};
req, res, or queue metadata