# BriefApp CLI — Provisionamento e Deploy de Clientes (Tenants)

> **Documentação Completa da Ferramenta de Linha de Comando do BriefApp**  
> **Versão:** 1.0 (Alinhada com Sprint 9 / .NET 10 / BriefApp.Sdk / BriefApp.Sidecar)  
> **Localização:** `c:\projetos\briefapp-modules\cli`

---

## 1. Visão Geral e Propósito

O **BriefApp CLI** é a ferramenta oficial da plataforma BriefApp (*Startup as a Service*) criada para automatizar o onboarding de novos clientes (tenants), emissão de credenciais de API criptograficamente assinadas, atribuição de planos/quotas de rate limit e empacotamento dos artefatos de deploy (`.env`, manifesto JSON e compose com sidecar).

```
                      ┌──────────────────────────────────────────────┐
                      │                 BriefApp CLI                 │
                      │           (cli/BriefApp.Cli.csproj)          │
                      └──────────────────────┬───────────────────────┘
                                             │
             ┌───────────────────────────────┼───────────────────────────────┐
             ▼                               ▼                               ▼
    [Comando provision]             [Comando validate]               [Comando keys]
  • Criação do Tenant              • Leitura do .env do cliente    • Emissão de novas chaves
  • Quotas por Plano               • Token Exchange OAuth2         • Rotação de chaves
  • Emissão de sk_ e pk_           • Diagnóstico de escopos e exp. • Gestão de escopos
  • Geração de .env e compose
             │
             ▼
┌─────────────────────────┐
│  Artefatos de Deploy    │
│  (deploy/{slug}/)       │
│  • .env                 │
│  • client-provisioning  │
│  • docker-compose.yml   │
└─────────────────────────┘
```

---

## 2. Estrutura do Projeto CLI

A solução do CLI está organizada dentro do repositório em:

```
c:\projetos\briefapp-modules\
├── cli\
│   ├── BriefApp.Cli.csproj           # Projeto console .NET 10
│   ├── Program.cs                     # Entry point e despachante de comandos
│   ├── ConsoleUi.cs                   # Interface de terminal com cores ANSI e prompts
│   ├── briefapp.ps1                   # Wrapper de execução para Windows PowerShell
│   ├── briefapp.sh                    # Wrapper de execução para Linux / macOS
│   ├── README.md                      # Guia rápido da pasta cli
│   ├── Commands\
│   │   ├── ICommand.cs                # Contrato padrão de comando
│   │   ├── ProvisionCommand.cs        # Implementação do comando 'provision'
│   │   ├── KeysCommand.cs             # Implementação do comando 'keys'
│   │   ├── ValidateCommand.cs         # Implementação do comando 'validate'
│   │   └── HelpCommand.cs             # Implementação do comando 'help'
│   ├── Models\
│   │   ├── PlanQuotas.cs              # Mapeamento de planos comerciais (Builder, Scale, Enterprise)
│   │   ├── ProvisionOptions.cs        # Parser e sanitização de argumentos/flags
│   │   └── ProvisionResult.cs         # Modelos de retorno e mascaramento de chaves
│   └── Services\
│       ├── ITenantProvisioningClient.cs     # Contrato de integração com Gateway
│       ├── HttpTenantProvisioningClient.cs # Cliente HTTP para endpoints administrativos
│       └── ArtifactGenerator.cs       # Gerador dos arquivos de deploy (.env, json, compose)
│
├── tests\
│   └── BriefApp.Cli.Tests\            # Suíte de testes automatizados com 27 testes
│       ├── BriefApp.Cli.Tests.csproj
│       ├── PlanQuotasTests.cs
│       ├── ProvisionOptionsParserTests.cs
│       ├── ArtifactGeneratorTests.cs
│       └── ProvisionCommandTests.cs
│
└── docs\
    └── cli-provisioning.md            # Documentação técnica resumida
```

---

## 3. Como Executar

O CLI pode ser invocado de três maneiras convenientes:

### 3.1 Via Script Wrapper no Windows (PowerShell)
```powershell
.\cli\briefapp.ps1 provision --name "Acme Logística" --slug acme --plan Standard --out-dir ./deploy/acme
```

### 3.2 Via Script Wrapper no Linux / macOS (Bash)
```bash
./cli/briefapp.sh provision --name "Acme Logística" --slug acme --plan Standard --out-dir ./deploy/acme
```

### 3.3 Diretamente via .NET CLI
```bash
dotnet run --project cli/BriefApp.Cli.csproj -- provision --name "Acme Logística" --slug acme
```

---

## 4. Comandos e Parâmetros

### 4.1 Comando `provision`
Cria o tenant no Gateway central, emite o par de chaves de API (`sk_` e `pk_`), calcula as quotas de rate limit conforme o plano e gera os artefatos de deploy.

```bash
briefapp provision [opções]
```

#### Tabela de Opções e Flags:

| Parâmetro | Alias | Padrão | Descrição |
|---|---|---|---|
| `--name` | `-n` | *(Obrigatório em batch)* | Nome Fantasia ou Razão Social do cliente. |
| `--slug` | `-s` | Kebab-case do nome | Identificador único alfanumérico do tenant (ex: `acme-corp`). |
| `--plan` | `-p` | `Scale` | Plano contratado (`Builder`/`Starter`, `Scale`/`Standard`, `Enterprise`). |
| `--email` | `-e` | `dev@{slug}.com` | E-mail técnico de contato para alertas e auditoria. |
| `--document` | `-d` | *(Opcional)* | CNPJ ou CPF do integrador. |
| `--out-dir` | `-o` | `./deploy` | Pasta de destino para gravação dos arquivos de deploy. |
| `--gateway-url` | `-g` | `http://localhost:5000` | URL do Gateway central do BriefApp. |
| `--sidecar-url` | | `http://localhost:5005` | URL base do Sidecar dedicado do cliente. |
| `--admin-token` | | *(Opcional)* | Bearer JWT com papel `Admin` para invocar a Admin API do Gateway. |
| `--admin-key` | | *(Opcional)* | Master API Key com escopo `admin`. |
| `--webhook-url` | | *(Opcional)* | Endpoint HTTP para onde o BriefApp despacha webhooks em tempo real. |
| `--allowed-origins` | | *(Opcional)* | Domínios CORS permitidos separados por vírgula. |
| `--allowed-bundles` | | *(Opcional)* | Bundle IDs mobile autorizados (ex: `br.com.acme.app`). |
| `--dry-run` | | `false` | Simula o provisionamento gerando os arquivos sem persistir no Gateway. |
| `--non-interactive` | | `false` | Falha imediatamente se faltar opção obrigatória (ideal para CI/CD). |
| `--up` / `--start` | | `false` | **Sobe os containers Docker do cliente automaticamente** (`docker compose up -d`). |
| `--port` | | `5005` | Porta local mapeada para o container do `BriefApp.Sidecar`. |
| `--build` | | `false` | Força a recompilação da imagem Docker do Sidecar antes de subir. |
| `--db-mode` | | `shared` | Modo do banco de dados: `shared` (multitenant compartilhado), `dedicated` (banco PostgreSQL existente do cliente) ou `container` (PostgreSQL dedicado em container). |
| `--db-cs` / `--db-connection-string` | | *(Opcional)* | Connection string do PostgreSQL existente quando `--db-mode dedicated`. |
| `--db-host` | | `localhost` | Host do PostgreSQL quando montando a string por parâmetros. |
| `--db-port` | | `5432` / `5433` | Porta do PostgreSQL (default 5433 para container para evitar conflito). |
| `--db-name` | | `briefapp_{slug}` | Nome da base de dados do cliente. |
| `--db-user` | | `postgres` | Usuário do PostgreSQL. |
| `--db-password` / `--db-pwd` | | *(Opcional)* | Senha de conexão do PostgreSQL. |
| `--db-ssl` | | `Prefer` | Modo SSL (`Disable`, `Prefer`, `Require`). |
| `--migrate` | | `false` | Executa migrações DDL idempotentes no banco alvo garantindo as tabelas do BriefApp. |
| `--test-db` | | `false` | Valida conectividade TCP e handshake com o PostgreSQL antes de provisionar. |
| `--create-db` / `--auto-create-db` | | `false` | Cria a base de dados via banco de manutenção `postgres` caso ainda não exista. |

#### Modos de Operação:
1. **Modo Interativo (Prompt):**
   Ao rodar `briefapp provision` sem argumentos, o CLI solicita interativamente:
   - Nome da Empresa / Cliente
   - Slug do Tenant (com sugestão automática baseada no nome)
   - E-mail de Contato
   - Modo de Banco de Dados (`[1] Shared`, `[2] Dedicated`, `[3] Container Postgres`)
   - Connection String ou parâmetros do PostgreSQL existente
2. **Modo Automatizado / CI-CD:**
   Ao passar `--name "Nome"` e `--non-interactive`, executa silenciosamente sem bloqueios de terminal.
3. **Modo Simulação (`--dry-run`):**
   Gera chaves e artefatos de teste instantaneamente sem depender de conexão de rede ou Gateway ligado.

---

### 4.2 Comando `db`
Gerencia a infraestrutura de banco de dados PostgreSQL do cliente (testes de conectividade, inspeção de tabelas e execução de migrações):

```bash
briefapp db <ação> [opções]
```

#### Ações Disponíveis:
- **`test`** (ou `ping`): Testa a conexão TCP e o handshake com o PostgreSQL, reportando a versão do servidor e a latência de rede.
- **`status`**: Inspeciona o catálogo `information_schema.tables` e lista as tabelas existentes no schema público.
- **`migrate`** (ou `update`): Cria a base de dados se ela não existir, inicializa a tabela `__EFMigrationsHistory` e aplica os scripts DDL idempotentes do BriefApp (`Tenants`, `TenantApiKeys`, `Users`, `AuditLogs`).

#### Exemplos de Uso:
```bash
# 1. Testar conexão com um banco existente:
briefapp db test --connection-string "Host=db.acme.com;Port=5432;Database=briefapp_acme;Username=pguser;Password=secret"

# 2. Testar conexão usando a string gravada no .env do cliente:
briefapp db test --env ./deploy/acme/.env

# 3. Inspecionar tabelas já criadas no banco do cliente:
briefapp db status --env ./deploy/acme/.env

# 4. Executar migrações de schema no banco do cliente:
briefapp db migrate --env ./deploy/acme/.env
```

---

### 4.2 Comando `deploy`
Controla a execução e o ciclo de vida dos containers Docker da stack de deploy do cliente (`docker-compose.client.yml`):

```bash
# Iniciar os containers em background (-d):
briefapp deploy up --dir ./deploy/acme

# Iniciar forçando rebuild da imagem do Sidecar:
briefapp deploy up --dir ./deploy/acme --build

# Inspecionar status e healthcheck dos containers:
briefapp deploy status --dir ./deploy/acme

# Encerrar e remover containers da stack:
briefapp deploy down --dir ./deploy/acme
```

---

### 4.3 Comando `validate`
Verifica a integridade de credenciais de um cliente, testando a autenticação real e o OAuth2 Token Exchange (`POST /api/tenants/token`):

```bash
# Validar arquivo .env de um cliente já provisionado:
briefapp validate --env ./deploy/acme/.env

# Validar chave individual diretamente:
briefapp validate --key sk_live_acme_8f1b93a0d5c4e721... --gateway-url http://localhost:5000
```

#### O que o comando valida:
- Existência e sintaxe do arquivo `.env`
- Extração de `BRIEFAPP_SECRET_KEY` e `BRIEFAPP_GATEWAY_URL`
- Requisição com `grant_type=client_credentials` contra `/api/tenants/token`
- Validade do token JWT retornado, tempo de expiração (`expires_in`) e escopos ativos

---

### 4.4 Comando `keys`
Permite administrar chaves de API avulsas para clientes que já foram cadastrados:

```bash
# Emitir nova Publishable Key para aplicativo Android:
briefapp keys generate \
  --tenant-id e30e1675-d146-4ba2-8ef9-c793ff826e7a \
  --name "App Android Producao" \
  --type Publishable \
  --scopes "public,catalog:read,scheduling:read"

# Emitir nova Secret Key para microsserviço de faturamento:
briefapp keys generate \
  --tenant-id e30e1675-d146-4ba2-8ef9-c793ff826e7a \
  --name "Servico Faturamento Backend" \
  --type Secret \
  --scopes "payments,billing,financial"
```

---

## 5. Chaves de API e Matriz de Escopos

Cada cliente provisionado recebe dois tipos de credenciais com isolamento estrito:

| Tipo | Prefixo | Destino de Uso | Escopos Padrão Concedidos |
|---|---|---|---|
| **Secret Key** | `sk_live_{slug}_...` | Servidores backend, APIs parceiras e container dedicado `BriefApp.Sidecar` | `*` (qualquer escopo: `identity`, `financial`, `payments`, `billing`, `mobility`, `storage`, `kyc`, `kanban`, `openfinance`) |
| **Publishable Key** | `pk_live_{slug}_...` | Aplicativos móveis (Flutter/React Native) e front-ends SPA (Vue/React) | `public`, `identity:login`, `identity:refresh`, `identity:2fa`, `identity:firebase`, `catalog:read`, `catalog:availability`, `scheduling:read` |

### Princípios de Segurança Implementados:
- **Mascaramento no Terminal:** A chave secreta nunca é exposta por completo no console durante o provisionamento. O terminal exibe apenas o formato mascarado: `sk_live_acme****...e835`.
- **Texto Claro Seguro:** O valor completo em texto claro é gravado exclusivamente dentro do arquivo `.env` no diretório de saída do cliente.
- **Isolamento no Git:** A pasta `deploy/` está registrada no [.gitignore](file:///c:/projetos/briefapp-modules/.gitignore), impedindo commits acidentais de credenciais de clientes.

---

## 6. Planos e Quotas de Rate Limiting

As quotas de requisições por minuto e limites de consumo mensal são calculadas e configuradas automaticamente durante o provisionamento de acordo com o plano comercial ativo:

| Plano | Preço Mensal | Volume Mensal | Rate Limit Geral | Limites Específicos por Grupo | Perfil Típico |
|---|---|---|---|---|---|
| **Builder** (alias `starter`, `free`) | R$ 290 a 490/mês | Até 5 mil req/mês | 100 rpm (burst 10) | Login/Auth: 5 rpm · Pagamentos: 10 rpm · Token: 60 rpm | MVPs, validação, integrações com Lovable/Bolt |
| **Scale** (alias `standard`) | R$ 1.200 a 2.500/mês | Até 100 mil req/mês | 300 rpm (burst 50) | Login/Auth: 5 rpm · Pagamentos: 10 rpm · Token: 60 rpm | Startups em produção, múltiplos prestadores |
| **Enterprise** (alias `ent`) | A partir de R$ 8.000/mês | Customizado | A partir de 1200 rpm | Quotas e burst dedicados negociados em SLA | Grandes operações, frotas, alto volume |

> **Take-Rate e Cobranças Transacionais:** Para pagamentos, split, corridas e entregas, incide o take-rate da plataforma de R$ 0,50 fixo + 0,5% a 1,5% sobre o valor transacionado.

---

## 7. Artefatos de Deploy Gerados

Ao provisionar um cliente (ex: `--slug acme --out-dir ./deploy/acme`), os três arquivos a seguir são gerados automaticamente:

### 7.1 `.env` (Ambiente Pronto para Produção)
```env
# =================================================================
# BriefApp Client Deployment Configuration
# Auto-generated by BriefApp CLI on 2026-10-12 03:27:55 UTC
# Tenant: Acme Transportes (Slug: acme) | Plan: Standard
# =================================================================

# Tenant Identification
TENANT_ID=6920e9d7-2651-4275-9dad-d1dff2a083cf
TENANT_SLUG=acme
TENANT_NAME="Acme Transportes"
TENANT_PLAN=Standard
TENANT_CONTACT_EMAIL=admin@acme.com

# BriefApp Platform URLs
BRIEFAPP_GATEWAY_URL=http://localhost:5000
BRIEFAPP_SIDECAR_URL=http://localhost:5005

# Machine-to-Machine Server API Key (Secret Key)
# CAUTION: Never expose this key in client-side code or public repos.
BRIEFAPP_SECRET_KEY=sk_live_acme_72e8780ab66846fc8965cc61a0f4c92e69917b56fb404374a2369a2acce5e835

# Web / Mobile Client Publishable Key
BRIEFAPP_PUBLISHABLE_KEY=pk_live_acme_aca19a51b0e04842acce2244e207f763

# Rate Limit Allocation
RATE_LIMIT_RPM=300
RATE_LIMIT_BURST=50
```

### 7.2 `client-provisioning.json` (Manifesto e Auditoria)
```json
{
  "schemaVersion": "2.0",
  "provisionedAt": "2026-10-12T03:27:55.3981332Z",
  "tenant": {
    "id": "6920e9d7-2651-4275-9dad-d1dff2a083cf",
    "slug": "acme",
    "name": "Acme Transportes",
    "plan": "Standard",
    "contactEmail": "admin@acme.com",
    "status": "Active",
    "rateLimits": {
      "requestsPerMinute": 300,
      "burstRequests": 50
    }
  },
  "credentials": {
    "secretKey": {
      "keyId": "94edafb4-2b20-4848-8ec7-3eb967eb9ad5",
      "prefix": "sk_live_acme_",
      "masked": "sk_live_acme****...e835",
      "type": "Secret",
      "scopes": ["identity", "financial", "payments", "billing", "mobility", "storage", "kyc", "kanban", "openfinance"]
    },
    "publishableKey": {
      "keyId": "535b9ead-c4b2-4de1-b5ca-4321d89ac8f7",
      "prefix": "pk_live_acme_",
      "plaintext": "pk_live_acme_aca19a51b0e04842acce2244e207f763",
      "type": "Publishable",
      "scopes": ["public", "identity:login", "identity:refresh", "identity:2fa", "identity:firebase", "catalog:read", "catalog:availability", "scheduling:read"]
    }
  },
  "endpoints": {
    "gateway": "http://localhost:5000",
    "sidecar": "http://localhost:5005",
    "tokenExchange": "http://localhost:5000/api/tenants/token",
    "scalarDocumentation": "http://localhost:5005/scalar/v1",
    "openApiSpecification": "http://localhost:5000/openapi/v1.json"
  }
}
```

### 7.3 `docker-compose.client.yml` (Stack de Deploy do Cliente)
```yaml
# =================================================================
# BriefApp Client Sidecar & App Stack
# Tenant: acme (Acme Transportes)
# =================================================================
services:
  briefapp-sidecar:
    image: briefapp/sidecar:latest
    container_name: briefapp-sidecar-acme
    restart: unless-stopped
    ports:
      - "5005:5005"
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - BriefApp__GatewayBaseUrl=${BRIEFAPP_GATEWAY_URL}
      - BriefApp__TenantApiKey=${BRIEFAPP_SECRET_KEY}
      - BriefApp__PublishableKey=${BRIEFAPP_PUBLISHABLE_KEY}
    env_file:
      - .env
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5005/health"]
      interval: 15s
      timeout: 5s
      retries: 3

  client-app:
    # Imagem da aplicação do cliente
    image: alpine:latest
    container_name: client-app-acme
    restart: unless-stopped
    command: ["sh", "-c", "echo 'Tenant acme pronto' && sleep infinity"]
    env_file:
      - .env
    depends_on:
      briefapp-sidecar:
        condition: service_healthy
```

---

## 8. Testes Automatizados e Validação

O projeto possui cobertura completa de testes unitários e de integração em [tests/BriefApp.Cli.Tests](file:///c:/projetos/briefapp-modules/tests/BriefApp.Cli.Tests):

```bash
dotnet test tests/BriefApp.Cli.Tests/BriefApp.Cli.Tests.csproj
```

### Casos de Teste Cobertos (100% Aprovados):
- **`PlanQuotasTests`**: Validação de todas as variações de plano (Builder, Starter, Free, Standard, Scale, Enterprise, numéricos 1, 2, 3) e lançamento de exceção amigável para planos inválidos.
- **`ProvisionOptionsParserTests`**: Parsing rigoroso de todas as opções de linha de comando, sanitização de slugs em formato kebab-case e remoção de caracteres proibidos.
- **`ArtifactGeneratorTests`**: Validação estrutural do arquivo `.env`, integridade e mascaramento do `client-provisioning.json`, e sintaxe do Docker Compose.
- **`ProvisionCommandTests`**: Fluxo ponta a ponta com simulação do Gateway via NSubstitute, checagem de criação de tenant, emissão de ambas as chaves (`sk_` e `pk_`), tratamento de erros de conflito de slug e validação do modo `--dry-run`.

---

## 9. Rastreabilidade Atomic Flow (Sprint 9)

O desenvolvimento deste CLI foi governado pela metodologia **Atomic Flow**:
- **Tier:** M (Medium Complexity)
- **Backlog ID:** `c1ca66bd-c45e-49f3-a949-3339793accbd` (Status: `Done`)
- **Sprint ID:** `6ea292c6-9b36-43ad-af16-cb661a0c04cf` (`Sprint 9 - CLI de Provisionamento e Deploy de Clientes`)
- **Work Items / Subtasks Concluídas:**
  - `18bed4c3-a93e-4b68-849a-92c22211c8dc`: Estrutura do Projeto BriefApp.Cli e Comandos Base (`Done`)
  - `8f753aaf-4f27-4917-920e-ecd458edaa0d`: Integração com Gateway Admin API e Emissão de Chaves (`Done`)
  - `03505cd4-87b1-4312-a72d-20bbd8714b54`: Geração de Artefatos de Deploy e Scripts Multiplataforma (`Done`)
  - `70f0ef29-6c61-4a89-91c8-a676e49ee0b6`: Testes Automatizados e Validação Ponta a Ponta do CLI (`Done`)
  - `d4057035-5b74-49f3-a960-11c3586ae1ff`: Parent Work Item (`Done`)
- **Git Branching:** Desenvolvido em branch de tarefa efêmera, integrado em `develop` e sincronizado com `main`.
