diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 0000000..483e196
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,50 @@
+name: Deploy
+on:
+ workflow_dispatch:
+env:
+ REGISTRY: container-registry.br-se1.magalu.cloud
+ IMAGE_NAME: cloud-application
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
+ with:
+ python-version: '3.11'
+ - name: Instalar dependências
+ run: |
+ pip install poetry
+ poetry install --no-root
+ - name: Executar testes
+ run: poetry run pytest
+ build-and-deploy:
+ needs: test
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Login no Container Registry
+ run: |
+ docker login https://${{ env.REGISTRY }} \
+ -u ${{ secrets.MGC_REGISTRY_USER }} \
+ -p ${{ secrets.MGC_REGISTRY_PASSWORD }}
+ - name: Build e push da imagem
+ run: |
+ IMAGE=${{ env.REGISTRY }}/${{ secrets.MGC_REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:latest
+ docker build -t $IMAGE .
+ docker push $IMAGE
+ - name: Configurar kubectl
+ run: |
+ echo "${{ secrets.MGC_KUBECONFIG }}" > kubeconfig.yaml
+ - name: Criar Secret do banco
+ run: |
+ export KUBECONFIG=kubeconfig.yaml
+ kubectl create secret generic db-secret \
+ --from-literal=url=${{ secrets.DATABASE_URL }} \
+ --dry-run=client -o yaml | kubectl apply -f -
+ - name: Deploy no Kubernetes
+ run: |
+ export KUBECONFIG=kubeconfig.yaml
+ export MGC_REGISTRY_NAME=${{ secrets.MGC_REGISTRY_NAME }}
+ envsubst < k8s/app.yaml | kubectl apply -f -
+ kubectl rollout status deployment/cloud-application
diff --git a/docs/data-model.md b/docs/data-model.md
new file mode 100644
index 0000000..f8fdb51
--- /dev/null
+++ b/docs/data-model.md
@@ -0,0 +1,26 @@
+# Modelagem de Dados
+
+## Entidades
+
+### Pedido (orders)
+
+| Coluna | Tipo | Descrição |
+|--------------|--------------------------------|----------------------------------------------------------------------------|
+| id | String (UUID) | Chave primária. Gerado automaticamente (`uuid4`) na criação do pedido |
+| customer | String | Nome do cliente que fez o pedido. Obrigatório |
+| status | String | Status do pedido. Padrão: `"open"` |
+| created_at | DateTime (com timezone, UTC) | Data/hora de criação do pedido. Preenchido automaticamente (`now(UTC)`) |
+
+### Item (items)
+
+| Coluna | Tipo | Descrição |
+|--------------|-----------|-----------------------------------------------------------------------------|
+| id | String (UUID) | Chave primária. Gerado automaticamente (`uuid4`) na criação do item |
+| order_id | String | Chave estrangeira para `orders.id`. Obrigatório |
+| sku | String | Código (SKU) do produto. Obrigatório |
+| description | String | Descrição do item. Obrigatório |
+| quantity | Integer | Quantidade do item no pedido. Obrigatório |
+
+## Relacionamento
+
+Relacionamento **1:N** entre `orders` e `items`: um pedido (`Order`) pode ter vários itens (`Item`), e cada item pertence a exatamente um pedido, via a chave estrangeira `items.order_id → orders.id`.
diff --git a/docs/docs/adr/001-kubernetes-deploy.md b/docs/docs/adr/001-kubernetes-deploy.md
new file mode 100644
index 0000000..5f2a90d
--- /dev/null
+++ b/docs/docs/adr/001-kubernetes-deploy.md
@@ -0,0 +1,35 @@
+# ADR 001 — Usar K3s para deploy da aplicação
+
+**Status:** Aceito
+**Data:** 2026-08-04
+
+## Contexto
+
+A aplicação precisa ser implantada na Magalu Cloud de forma acessível publicamente, resiliente a falhas e com capacidade de escalar.
+
+## Alternativas consideradas
+
+- **K3s em VM** — Kubernetes leve; cobra só a VM; provisionamento < 2 min; sem HA nativa.
+- **MKS (Kubernetes Gerenciado)** — control plane e HA gerenciados; custo maior; provisionamento 5-10 min.
+- **VM com Docker Compose** — mais simples de subir; sem orquestração, self-healing nem escala declarativa.
+
+## Decisão
+
+Usar K3s em uma VM BV2-2-40 (Ubuntu 24.04) com Klipper ServiceLB para expor a aplicação na porta 80 do IP público da VM.
+
+O script `k3s-mgc` automatiza todo o provisionamento. Critério: menor custo e provisionamento mais rápido, com manifests idênticos a qualquer Kubernetes.
+
+## Consequências
+
+**Positivas:**
+- Custo menor que o MKS (cobra apenas pela VM e não pelo control plane)
+- Provisionamento em menos de 2 minutos
+- Manifests YAML idênticos a qualquer Kubernetes padrão (sem lock-in)
+- Restart automático em caso de falha (liveness probe)
+- Escalabilidade horizontal simples (basta aumentar o número de réplicas)
+
+**Negativas:**
+- Single point of failure: sem alta disponibilidade nativa (tudo em uma VM)
+- Armazenamento efêmero: volumes locais desaparecem se a VM for recriada
+- Sem auto-scaling de nós: capacidade fixa (2 vCPU, 2 GB)
+- IP público muda se a VM for substituída
diff --git a/docs/docs/adr/002-dbaas-postgresql.md b/docs/docs/adr/002-dbaas-postgresql.md
new file mode 100644
index 0000000..4dde7db
--- /dev/null
+++ b/docs/docs/adr/002-dbaas-postgresql.md
@@ -0,0 +1,30 @@
+# ADR 002 — Usar DBaaS PostgreSQL da Magalu Cloud
+
+**Status:** Aceito
+**Data:** 2026-08-04
+
+## Contexto
+
+A aplicação precisa de persistência de dados. O banco precisa sobreviver a reinicializações de containers e estar disponível para múltiplas réplicas da API simultaneamente.
+
+## Alternativas consideradas
+
+- **DBaaS PostgreSQL gerenciado (externo)** — backup, patch e HA pelo provedor; custo maior; menos controle fino.
+- **PostgreSQL em pod com PVC** — custo baixo, tudo em um lugar; volume, backup e recuperação por nossa conta; o dado morre junto com o cluster.
+
+## Decisão
+
+Usar o serviço DBaaS PostgreSQL da Magalu Cloud — banco gerenciado, sem necessidade de operar o servidor de banco de dados. Critério: disponibilidade e custo de operação (estado é caro de operar manualmente).
+
+## Consequências
+
+**Positivas:**
+- Backup automático gerenciado pelo provedor
+- Sem custo operacional de administração do banco
+- Conexões simultâneas de múltiplos pods sem conflito
+- Alta disponibilidade incluída no serviço
+
+**Negativas:**
+- Custo por hora de uso, mesmo com pouco tráfego
+- Menor controle sobre configurações avançadas do PostgreSQL
+- Dependência do provedor para upgrades de versão
diff --git a/docs/docs/architecture.md b/docs/docs/architecture.md
new file mode 100644
index 0000000..3afb538
--- /dev/null
+++ b/docs/docs/architecture.md
@@ -0,0 +1,97 @@
+# Arquitetura da Solução
+
+## Diagrama de arquitetura (C4 — Nível de Container)
+
+```mermaid
+graph LR
+ User["Usuário / Cliente HTTP"]
+
+ subgraph GH["GitHub"]
+ GA["GitHub Actions
(CI/CD)"]
+ end
+
+ subgraph MGC["Magalu Cloud"]
+ CR[("Container Registry")]
+
+ subgraph VM["VM BV2-2-40 · K3s"]
+ LB["Klipper ServiceLB
IP público · porta 80"]
+ API1["Pod API
réplica 1 · :8000"]
+ API2["Pod API
réplica 2 · :8000"]
+ end
+
+ DB[("DBaaS PostgreSQL
IP privado · :5432")]
+ end
+
+ User -->|"HTTP :80"| LB
+ LB -->|"HTTP :8000"| API1
+ LB -->|"HTTP :8000"| API2
+ API1 -->|"SQL/TCP :5432 (rede privada)"| DB
+ API2 -->|"SQL/TCP :5432 (rede privada)"| DB
+ GA -->|"docker push (HTTPS)"| CR
+ GA -->|"kubectl apply (via kubeconfig)"| VM
+ VM -->|"docker pull (HTTPS)"| CR
+```
+
+## Componentes da arquitetura
+
+| Componente | Serviço MGC | Função |
+|---|---|---|
+| API | K3s (VM single node) — 2 réplicas | Processa as requisições HTTP |
+| Banco de dados | DBaaS PostgreSQL | Persiste pedidos e itens |
+| Imagens | Container Registry | Armazena versões da aplicação |
+| Tráfego externo | Klipper ServiceLB (IP da VM, porta 80) | Distribui entre as réplicas e fornece acesso externo |
+| CI/CD | GitHub Actions | Automatiza testes, build e deploy |
+
+## Requisitos não-funcionais
+
+| Requisito | Como medir | Alvo |
+|---|---|---|
+| Disponibilidade | Erros 5xx e uptime das probes no Grafana | 99,5% mensal |
+| Latência | `histogram_quantile(0.95, ...)` do `/metrics` | P95 < 500 ms |
+| Escalabilidade | Teste de carga (k6) + `rate(http_requests_total)` | 300 req/s sem degradar |
+| Custo | VM + DBaaS + IP na calculadora MGC | Teto definido em ADR |
+
+## Estilo arquitetural
+
+A solução segue um **monolito em camadas** (apresentação → serviço → dados), implantado como container único com duas réplicas atrás de um LoadBalancer. Não há separação de bounded contexts nem comunicação assíncrona entre serviços — toda a lógica de pedidos e itens vive num único processo FastAPI.
+
+Estilo-alvo, caso o domínio de notificações cresça: extrair um segundo serviço (ex.: um serviço de notificações desacoplado, comunicando-se via fila ou evento), evoluindo de monolito para um conjunto pequeno de serviços.
+
+## Trade-offs
+
+| Aspecto | Decisão tomada | Alternativa não escolhida | Motivo da escolha |
+|---|---|---|---|
+| Deploy | K3s em VM | MKS (Kubernetes Gerenciado) | Custo menor, provisionamento < 2 min, manifests idênticos |
+| Banco | DBaaS gerenciado | PostgreSQL em container | Backup automático, sem administração |
+| CI/CD | GitHub Actions | Deploy manual | Consistência e rastreabilidade |
+| Réplicas | 2 pods | 1 pod | Disponibilidade mínima sem custo excessivo |
+| API | FastAPI (Python) | Node.js, Go, Java | Curva de aprendizado baixa, alta produtividade |
+
+## Pontos de melhoria
+
+### Escalabilidade
+
+A aplicação é stateless, então escala na horizontal — mais réplicas atrás do balanceador. Hoje são 2 réplicas fixas; o próximo passo natural é o HPA (Horizontal Pod Autoscaler), que ajusta esse número automaticamente pela utilização de CPU (ex.: mínimo 2, máximo 6, alvo de 70%). Vale registrar também que mais réplicas não resolvem um gargalo de banco — o PostgreSQL escala na vertical e costuma saturar primeiro.
+
+### Próximos passos naturais
+
+| Melhoria | Por quê |
+|---|---|
+| HTTPS / TLS | Toda API em produção deve ser acessada por HTTPS |
+| Autoscaler (HPA) | Escala automaticamente conforme a carga |
+| Versionamento de API | `/v1/orders` permite evoluir sem quebrar clientes |
+| Rate limiting | Evita abuso e protege o banco de sobrecargas |
+| Cache (Redis) | Reduz consultas repetidas ao banco |
+| Migrações de schema (Alembic) | Controle de versão das mudanças no banco |
+| Testes de carga | Valida o comportamento sob alto tráfego |
+| Migrar para MKS | Quando precisar de HA real: basta trocar o kubeconfig — os manifests YAML são idênticos |
+
+### Custo estimado na Magalu Cloud
+
+| Recurso | Especificação | Observação |
+|---|---|---|
+| VM K3s | BV2-2-40 (2 vCPU, 2 GB) | Cobrada por hora de uso |
+| DBaaS PostgreSQL | Instância pequena | Cobrado por hora de uso |
+| Container Registry | Por armazenamento | Baixo para imagens < 500 MB |
+
+Consulte os preços atualizados em: https://magalu.cloud/precos/
diff --git a/k8s/app.yaml b/k8s/app.yaml
new file mode 100644
index 0000000..9001a99
--- /dev/null
+++ b/k8s/app.yaml
@@ -0,0 +1,54 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: cloud-application
+ labels:
+ app: cloud-application
+spec:
+ replicas: 2
+ selector:
+ matchLabels:
+ app: cloud-application
+ template:
+ metadata:
+ labels:
+ app: cloud-application
+ spec:
+ containers:
+ - name: cloud-application
+ image: container-registry.br-se1.magalu.cloud/${MGC_REGISTRY_NAME}/cloud-application:latest
+ ports:
+ - containerPort: 8000
+ env:
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: db-secret
+ key: url
+ livenessProbe:
+ httpGet:
+ path: /health
+ port: 8000
+ initialDelaySeconds: 10
+ periodSeconds: 30
+ readinessProbe:
+ httpGet:
+ path: /health
+ port: 8000
+ initialDelaySeconds: 5
+ periodSeconds: 10
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: cloud-application
+ labels:
+ app: cloud-application
+spec:
+ type: LoadBalancer
+ selector:
+ app: cloud-application
+ ports:
+ - name: http
+ port: 80
+ targetPort: 8000