<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->

# Diretrizes para Agentes de IA — Newsletter Platform

Este repositório é uma plataforma de e-mail marketing full-stack desenvolvida com Next.js 15 (App Router), React 19, Prisma ORM 6, NextAuth v5, AWS SES/SMTP, TypeScript e Vitest.

---

## 1. Princípios Arquiteturais & Convenções

- **Modular por Funcionalidade (`src/modules/`)**: Não crie pastas genéricas por tipo de arquivo na raiz. Agrupe o domínio em `src/modules/<feature>/`.
- **Camadas com Dependências Apontando para Dentro**:
  - `domain / entities`: Tipos, regras puras, validações. Sem import de frameworks ou ORM.
  - `use-cases`: Casos de uso da aplicação (regra de negócio). Dependem de abstrações (interfaces de repositórios/providers).
  - `repositories`: Interfaces (`*Repository`) + implementações concretas (`Prisma*Repository` e `InMemory*Repository`).
  - `actions`: Server Actions React 19 (`'use server'`) para mutações chamadas pela interface.
- **Server Actions para Mutações**: Mutações originadas do front-end usam Server Actions em `src/modules/<feature>/actions/`. **Não crie API routes REST para o front-end**.
- **Server Components para Leitura**: Páginas em `src/app/(dashboard)/` são Server Components que chamam use-cases diretamente para buscar dados no servidor.
- **API Routes Restritas**: Rotas HTTP em `src/app/api/` são exclusivas para callbacks/webhooks externos, NextAuth, pixel de rastreamento e descadastro RFC 8058.
- **Criptografia de Credenciais**: Senhas SMTP devem ser mantidas criptografadas no banco via `encrypt()` / `decrypt()` de `src/shared/infra/crypto/crypto.ts`.

---

## 2. Estrutura do Projeto

```
src/
├── app/                       # Apresentação e roteamento Next.js (App Router)
│   ├── (auth)/                # Route Group: Páginas de Login e Registro
│   ├── (dashboard)/           # Route Group: Páginas autenticadas do painel
│   ├── api/                   # API Routes restritas a webhooks/callbacks externos
│   └── unsubscribe/           # Página pública de descadastro
├── config/                    # Configuração global (NextAuth.js v5, env vars)
├── modules/                   # Módulos de domínio (Feature-Based)
│   ├── auth/
│   ├── campaigns/
│   ├── contacts/
│   ├── domains/
│   ├── senders/
│   ├── ses-webhooks/
│   └── suppression/
└── shared/                    # UI Design System, utilitários e infraestrutura comum
    ├── components/            # UI Primitives (buttons, modals, inputs, sonner)
    ├── infra/                 # Crypto, Prisma client singleton, ResponseHelper
    └── utils/                 # Helpers puros
```

---

## 3. Padrões de Nomenclatura

- **Arquivos e Pastas**: Sempre em `kebab-case` (ex.: `create-campaign-use-case.ts`, `prisma-contacts-repository.ts`).
- **Classes e Interfaces**: Em `PascalCase` (ex.: `CreateCampaignUseCase`, `ContactsRepository`).
- **Server Actions**: Nomeadas no formato `<acao>-<entidade>-action.ts` e exportando uma função em `camelCase` terminada em `Action` (ex.: `createCampaignAction`).
- **Use-Cases**: Nomeados no formato `<acao>-<entidade>-use-case.ts` e exportando uma classe terminada em `UseCase` (ex.: `CreateCampaignUseCase`).
- **Repositórios**:
  - Interface: `<entidade>-repository.ts` (ex.: `ContactsRepository`).
  - Prisma: `prisma-<entidade>-repository.ts` (ex.: `PrismaContactsRepository`).
  - In-Memory: `in-memory-<entidade>-repository.ts` (ex.: `InMemoryContactsRepository`).

---

## 4. Guia Passo a Passo

### Como criar um novo Módulo (`src/modules/<novo-modulo>`)

1. Crie a pasta em `src/modules/<novo-modulo>/`.
2. Adicione as subpastas necessárias sem aninhamento profundo: `actions/`, `use-cases/`, `repositories/`, `dtos/`, `components/`.
3. Se houver tabela no banco, adicione o model em `prisma/schema.prisma` e rode `npx prisma migrate dev --name add_<novo_modulo>`.

### Como criar um novo Use-Case

1. Crie o DTO/Schema de entrada com Zod se necessário.
2. Defina a interface do Use-Case com o método `execute(request: RequestType): Promise<ResponseType>`.
3. Receba os repositórios abstratos via injeção no construtor.
4. Crie o teste unitário equivalente `.spec.ts` usando `InMemoryRepository`.

Exemplo:
```typescript
// src/modules/example/use-cases/do-something-use-case.ts
import { ExampleRepository } from "../repositories/example-repository";

interface DoSomethingRequest {
  title: string;
}

export class DoSomethingUseCase {
  constructor(private exampleRepository: ExampleRepository) {}

  async execute({ title }: DoSomethingRequest) {
    const item = await this.exampleRepository.create({ title });
    return { item };
  }
}
```

### Como criar uma nova Server Action

1. Crie o arquivo em `src/modules/<modulo>/actions/<nome>-action.ts`.
2. Adicione `'use server'` no topo do arquivo.
3. Valide a sessão do usuário com `auth()`.
4. Instancie o Use-Case passando a implementação `PrismaRepository`.
5. Execute o Use-Case e revalide o caminho visual com `revalidatePath()`.

Exemplo:
```typescript
// src/modules/example/actions/do-something-action.ts
'use server';

import { revalidatePath } from "next/cache";
import { auth } from "@/config/auth";
import { PrismaExampleRepository } from "../repositories/prisma-example-repository";
import { DoSomethingUseCase } from "../use-cases/do-something-use-case";

export async function doSomethingAction(data: { title: string }) {
  const session = await auth();
  if (!session?.user?.id) {
    throw new Error("Não autorizado");
  }

  const useCase = new DoSomethingUseCase(new PrismaExampleRepository());
  const result = await useCase.execute(data);

  revalidatePath("/dashboard");
  return result;
}
```

### Como criar um Repositório (Interface + Prisma + In-Memory)

1. **Interface**: `src/modules/<modulo>/repositories/<modulo>-repository.ts`
2. **Prisma**: `src/modules/<modulo>/repositories/prisma-<modulo>-repository.ts`
3. **In-Memory**: `src/modules/<modulo>/repositories/in-memory-<modulo>-repository.ts` (para testes unitários)

---

## 5. Testes

- **Executar Testes**: `npm run test`
- Os testes usam **Vitest** e não conectam ao PostgreSQL real. Eles utilizam as implementações `InMemory*Repository`.
- Nomes dos arquivos de teste devem seguir o padrão `<nome>.spec.ts` ao lado do arquivo testado.
