Thiago Morangos API — Documentação
Base URL fixa: https://api.thiagomorangos.com.br/
Esta documentação descreve o contrato público da API (rotas, autenticação, headers e formatos de resposta).
1) Visão geral
1.1 Base URL e versionamento
A API é acessada sempre pela base URL fixa: https://api.thiagomorangos.com.br/
As rotas públicas seguem o prefixo: /api/v1/… (versionamento por caminho).
1.2 Convenções HTTP
- JSON por padrão: endpoints aceitam/retornam JSON (exceto preflight
OPTIONSque responde sem body). - Content-Type esperado em requests com body:
application/json. - Status codes: 200/201, 400, 401, 403, 404, 429, 500 e 502.
- Headers: CORS habilitado (ver seção CORS).
1.3 Padrão de resposta JSON e erros
{
"ok": true,
"message": "…",
"data": {},
"timestamp": "2026-01-25T00:00:00.000Z"
}
{
"ok": false,
"error": true,
"message": "…",
"timestamp": "2026-01-25T00:00:00.000Z"
}
Observação: alguns endpoints retornam campos adicionais específicos (por exemplo, dados de token, paginação, etc.). Sempre trate campos extras como extensões do contrato para manter compatibilidade futura.
1.4 Quickstart (60s)
- GET
https://api.thiagomorangos.com.br/api/v1/health - Se estiver em browser, rode um
OPTIONSno mesmo endpoint (preflight). - Faça login do cliente:
/api/v1/auth/login-start→/api/v1/auth/login-confirm. - Use o Bearer token para chamar
/api/v1/me.
1.5 Resumo de endpoints
| Método | Path | Auth | Resumo |
|---|---|---|---|
| GET | /api/v1/health | Nenhuma | Saúde/monitoramento. |
| GET | /api/v1/cep/<cep> | Nenhuma | Lookup CEP (ViaCEP). |
| GET | /api/v1/unsplash/search | Nenhuma | Busca imagens (Unsplash). |
| POST | /api/v1/auth/login-start | Nenhuma | Inicia login por telefone. |
| POST | /api/v1/auth/login-confirm | Nenhuma | Confirma código e emite token. |
| POST | /api/v1/auth/logout | Bearer (cliente) | Logout do cliente. |
| GET | /api/v1/me | Bearer (cliente) | Perfil do cliente autenticado. |
| GET | /api/v1/produtos | Nenhuma | Lista produtos. |
| POST | /api/v1/produtos | Nenhuma (legado) | Cria produto. |
| POST | /api/v1/frete/calcular | Nenhuma | Calcula frete. |
| GET | /api/v1/pedidos | Bearer (cliente) | Lista pedidos do cliente. |
| POST | /api/v1/pedidos | Bearer (cliente) | Cria pedido. |
| POST | /api/v1/admin/auth/login | Nenhuma | Login admin. |
| POST | /__admin/init-db | X-Setup-Token | Cria/atualiza schema. |
| POST | /__admin/exec-sql | X-Setup-Token | Executa SQL bruto. |
2) Autenticação e autorização
A API usa:
Authorization: Bearer <token>para sessões (cliente e admin)X-Setup-Tokenpara rotas administrativas sensíveis de setup/manutenção em/__admin/*
2.1 Fluxo de login do cliente
- login-start: informe o telefone do cliente para iniciar o desafio de login (código). Em ambiente de desenvolvimento, a resposta pode incluir o
codigopara facilitar testes. - login-confirm: informe telefone +
codigopara confirmar o desafio e receber osession_token(use-o como Bearer nas rotas autenticadas).
2.2 Fluxo de login do admin
Login via usuário/senha → emissão de token Bearer com validade (expires_at).
Rotas admin exigem token e algumas exigem nível mínimo (controle legado).
2.3 Rotas de setup (X-Setup-Token)
Rotas /__admin/* exigem X-Setup-Token com o valor configurado em SETUP_TOKEN no ambiente do Worker.
3) CORS e preflight (OPTIONS)
Preflight global com:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET,POST,PUT,PATCH,DELETE,OPTIONS Access-Control-Allow-Headers: Content-Type,Authorization,X-Setup-Token Access-Control-Max-Age: 86400
4) Endpoints
As rotas abaixo estão agrupadas por domínio funcional. Quando campos exatos dependerem do schema do banco, esta documentação descreve o mínimo garantido e boas práticas de consumo.
4.1 Health
| Método | Path | Auth | Descrição |
|---|---|---|---|
| GET | /api/v1/health | Nenhuma | Endpoint de saúde. |
4.2 Consulta de CEP (ViaCEP)
| Método | Path | Auth | Descrição |
|---|---|---|---|
| GET | /api/v1/cep/<cep> | Nenhuma | Consulta dados por CEP. |
Parâmetro: cep (somente números, com ou sem máscara).
4.3 Busca de imagens (Unsplash)
| Método | Path | Auth | Descrição |
|---|---|---|---|
| GET | /api/v1/unsplash/search | Nenhuma | Busca imagens e retorna formato normalizado. |
Querystring: q/query (obrigatório), page, per_page.
4.4 Autenticação do cliente
Autenticação de cliente via desafio por código (2 etapas). Ao final, a API retorna um session_token
que deve ser usado como Authorization: Bearer <token>.
- Em DEV, o endpoint
login-startpode retornar ocodigono JSON para facilitar testes (conforme front-end). - Em produção, o código normalmente é entregue ao usuário pelo canal configurado (ex.: WhatsApp), e pode não aparecer na resposta.
- Alguns erros podem retornar 429 (rate limit) com
retry_after.
| Método | Path | Auth | Entrada | Saída | Status | Headers relevantes |
|---|---|---|---|---|---|---|
POST |
/api/v1/auth/login-start |
Nenhuma | { telefone } |
{ ok, data } |
200 / 400 / 429 | Content-Type, CORS |
POST |
/api/v1/auth/login-confirm |
Nenhuma | { telefone, codigo } |
{ ok, data.session_token } |
200 / 400 / 401 / 429 | Content-Type, CORS |
POST |
/api/v1/auth/logout |
Bearer | (vazio) | { ok } (ou vazio) |
200 / 401 | Authorization, CORS |
4.4.1 POST /api/v1/auth/login-start
Inicia o login: o usuário informa seu telefone e o servidor inicia um desafio (código de 6 caracteres).
O código expira; quando presente, use o campo expira_em retornado pela API para exibir o prazo.
Headers
Content-Type: application/json
Body (JSON)
telefone(string) — telefone do cliente. Pode ser enviado com máscara; o servidor pode normalizar (aceite recomendado: somente dígitos).
Resposta de sucesso (200)
{
"ok": true,
"data": {
"cliente_id": 123,
"telefone": "16999999999",
"expira_em": "2026-01-26T12:34:56.000Z",
"codigo": "ABC123"
}
}
Obs.: o campo codigo pode estar presente apenas em DEV (use-o como opcional).
Erros comuns
- 400: dados inválidos (ex.: telefone ausente/ inválido). Retorna
{ ok:false, message }. - 429: rate limit. Pode retornar
{ ok:false, message, retry_after }.
Exemplo (cURL)
BASE="https://api.thiagomorangos.com.br"
curl -s "$BASE/api/v1/auth/login-start" -H "Content-Type: application/json" -d '{"telefone":"16999999999"}'
4.4.2 POST /api/v1/auth/login-confirm
Confirma o código e retorna o token de sessão. O cliente deve persistir o token e enviá-lo como Bearer.
Headers
Content-Type: application/json
Body (JSON)
telefone(string) — mesmo telefone usado nologin-start.codigo(string) — código recebido (6 caracteres). Em DEV pode ser alfanumérico (ex.:ABC123).
Resposta de sucesso (200)
{
"ok": true,
"data": {
"session_token": "eyJ...",
"expires_at": "2026-01-26T22:34:56.000Z",
"cliente": {
"id": 123,
"nome": "João Silva",
"telefone": "16999999999",
"email": "joao@email.com",
"tipo_pessoa": "PF"
}
}
}
Erros comuns
- 400/401: código inválido, expirado, ou não correspondente ao telefone. Retorna
{ ok:false, message }. - 429: rate limit. Pode retornar
{ ok:false, message, retry_after }.
Exemplo (cURL)
BASE="https://api.thiagomorangos.com.br"
curl -s "$BASE/api/v1/auth/login-confirm" -H "Content-Type: application/json" -d '{"telefone":"16999999999","codigo":"ABC123"}'
4.4.3 POST /api/v1/auth/logout
Invalida a sessão atual (quando aplicável). Mesmo que o servidor responda com erro, o cliente deve remover o token local.
Headers
Authorization: Bearer <session_token>
Exemplo (cURL)
BASE="https://api.thiagomorangos.com.br" TOKEN="SEU_TOKEN_AQUI" curl -s -X POST "$BASE/api/v1/auth/logout" -H "Authorization: Bearer $TOKEN"
4.5 Meu perfil (cliente)
| Método | Path | Auth | Descrição |
|---|---|---|---|
| GET | /api/v1/me | Bearer (cliente) | Dados do cliente autenticado. |
4.6 Produtos
| Método | Path | Auth | Descrição |
|---|---|---|---|
| GET | /api/v1/produtos | Nenhuma | Lista produtos. |
| POST | /api/v1/produtos | Nenhuma (legado) | Cria produto. |
4.7 Clientes e endereços
Endpoints de cadastro e manutenção de clientes (PF/PJ) e seus endereços. No contrato atual, estas rotas são tratadas como legado e podem não exigir Bearer — mantenha a proteção por borda (WAF/rate limit) se publicar publicamente.
| Método | Path | Auth | Entrada | Saída | Status | Headers relevantes |
|---|---|---|---|---|---|---|
GET |
/api/v1/clientes |
Nenhuma (legado) | Query params | { ok, count, data[] } |
200 | CORS |
GET |
/api/v1/clientes/:id |
Nenhuma (legado) | Path param | { ok, data{... , enderecos[] } } |
200 / 404 | CORS |
POST |
/api/v1/clientes |
Nenhuma (legado) | JSON (PF/PJ) | { ok, message, data } |
201 / 400 | Content-Type, CORS |
PUT |
/api/v1/clientes/:id |
Nenhuma (legado) | JSON | { ok, message, data } |
200 / 400 / 404 | Content-Type, CORS |
POST |
/api/v1/clientes/:id/enderecos |
Nenhuma (legado) | JSON | { ok, message, data } |
201 / 400 / 404 | Content-Type, CORS |
PUT |
/api/v1/enderecos/:id |
Nenhuma (legado) | JSON | { ok, message, data } |
200 / 400 / 404 | Content-Type, CORS |
DELETE |
/api/v1/enderecos/:id |
Nenhuma (legado) | - | { ok, message } |
200 / 404 / 409 | CORS |
4.7.1 Modelos (Cliente/Endereço)
Cliente (campos comuns)
id(number) — identificador.nome(string) — nome do cliente (PF) ou contato principal (PJ).telefone(string) — telefone (recomendado: dígitos).email(string | null) — opcional.tipo_pessoa("PF" | "PJ")ativo(boolean)criado_em/atualizado_em(ISO datetime)
Cliente PJ (campos adicionais)
razao_social(string)cnpj(string)ie(string | null)isento_ie(boolean)
Endereço
id(number)cliente_id(number)apelido(string) — ex.: "Casa", "Trabalho".cep(string) — ex.: "14020-000".rua(string)numero(string)complemento(string | null)bairro(string)cidade(string)uf(string) — 2 letras (ex.: "SP").distancia_km(number) — usado para cálculo de frete.principal(boolean) — indica endereço principal do cliente.criado_em/atualizado_em(ISO datetime)
nome, telefone, tipo_pessoa em criação). Outros podem variar conforme validações do Worker.
Para evitar rejeição por validação, envie o payload completo nos cadastros e utilize atualização parcial apenas quando já souber quais campos foram aceitos.
4.7.2 GET /api/v1/clientes
Query params
incluirInativos(boolean, opcional, default: false) — inclui registros desativados.tipo("PF" | "PJ", opcional) — filtra por tipo.
Resposta (200)
{
"ok": true,
"count": 2,
"data": [
{
"id": 1,
"nome": "João Silva",
"telefone": "16999887766",
"email": "joao@email.com",
"tipo_pessoa": "PF",
"ativo": true,
"criado_em": "2026-01-26T10:30:00.000Z"
}
]
}
Exemplo (cURL)
BASE="https://api.thiagomorangos.com.br" curl -s "$BASE/api/v1/clientes?incluirInativos=false&tipo=PF"
4.7.3 GET /api/v1/clientes/:id
Retorna o cliente e uma lista enderecos associada.
Resposta (200)
{
"ok": true,
"data": {
"id": 1,
"nome": "João Silva",
"telefone": "16999887766",
"email": "joao@email.com",
"tipo_pessoa": "PF",
"ativo": true,
"criado_em": "2026-01-26T10:30:00.000Z",
"enderecos": [
{
"id": 1,
"apelido": "Casa",
"cep": "14020-000",
"rua": "Rua das Flores",
"numero": "123",
"complemento": "Apto 45",
"bairro": "Centro",
"cidade": "Ribeirão Preto",
"uf": "SP",
"distancia_km": 3.5,
"principal": true,
"criado_em": "2026-01-26T10:30:00.000Z"
}
]
}
}
Erro (404)
{
"ok": false,
"message": "Cliente não encontrado"
}
Exemplo (cURL)
BASE="https://api.thiagomorangos.com.br" ID=1 curl -s "$BASE/api/v1/clientes/$ID"
4.7.4 POST /api/v1/clientes
Cria um novo cliente. Use tipo_pessoa para indicar PF ou PJ.
Headers
Content-Type: application/json
Body (PF) — exemplo completo
{
"nome": "Maria Santos",
"telefone": "16988776655",
"email": "maria@email.com",
"tipo_pessoa": "PF"
}
Body (PJ) — exemplo completo
{
"nome": "Contato Principal",
"telefone": "1633334444",
"email": "contato@empresa.com",
"tipo_pessoa": "PJ",
"razao_social": "Empresa Exemplo LTDA",
"cnpj": "12.345.678/0001-99",
"ie": "123456789",
"isento_ie": false
}
Resposta (201)
{
"ok": true,
"message": "Cliente criado com sucesso",
"data": {
"id": 3,
"nome": "Maria Santos",
"telefone": "16988776655",
"email": "maria@email.com",
"tipo_pessoa": "PF",
"ativo": true,
"criado_em": "2026-01-26T15:30:00.000Z"
}
}
Erro (400) — exemplo
{
"ok": false,
"message": "Nome e telefone são obrigatórios"
}
Exemplo (cURL)
BASE="https://api.thiagomorangos.com.br"
curl -s -X POST "$BASE/api/v1/clientes" -H "Content-Type: application/json" -d '{"nome":"Maria Santos","telefone":"16988776655","email":"maria@email.com","tipo_pessoa":"PF"}'
4.7.5 PUT /api/v1/clientes/:id
Atualiza dados do cliente. O contrato permite atualização parcial; para evitar divergência, prefira enviar o conjunto completo de campos que você mantém no seu cadastro.
Headers
Content-Type: application/json
Body — exemplo (PF) com campos comuns
{
"nome": "João Silva Santos",
"telefone": "16999887766",
"email": "joao.novo@email.com",
"tipo_pessoa": "PF"
}
Body — exemplo (PJ) com campos adicionais
{
"nome": "Contato Principal",
"telefone": "1633334444",
"email": "contato@empresa.com",
"tipo_pessoa": "PJ",
"razao_social": "Empresa Exemplo LTDA",
"cnpj": "12.345.678/0001-99",
"ie": "123456789",
"isento_ie": false
}
Resposta (200)
{
"ok": true,
"message": "Cliente atualizado com sucesso",
"data": {
"id": 1,
"nome": "João Silva Santos",
"telefone": "16999887766",
"email": "joao.novo@email.com",
"tipo_pessoa": "PF",
"ativo": true,
"atualizado_em": "2026-01-26T16:00:00.000Z"
}
}
Exemplo (cURL)
BASE="https://api.thiagomorangos.com.br"
ID=1
curl -s -X PUT "$BASE/api/v1/clientes/$ID" -H "Content-Type: application/json" -d '{"nome":"João Silva Santos","telefone":"16999887766","email":"joao.novo@email.com"}'
4.7.6 POST /api/v1/clientes/:id/enderecos
Adiciona um endereço ao cliente. O campo distancia_km influencia o cálculo do frete.
Headers
Content-Type: application/json
Body — exemplo completo
{
"apelido": "Trabalho",
"cep": "14021-000",
"rua": "Av. Nove de Julho",
"numero": "500",
"complemento": "Sala 12",
"bairro": "Jardim América",
"cidade": "Ribeirão Preto",
"uf": "SP",
"distancia_km": 6.2,
"principal": false
}
Resposta (201)
{
"ok": true,
"message": "Endereço adicionado com sucesso",
"data": {
"id": 2,
"cliente_id": 1,
"apelido": "Trabalho",
"cep": "14021-000",
"rua": "Av. Nove de Julho",
"numero": "500",
"complemento": "Sala 12",
"bairro": "Jardim América",
"cidade": "Ribeirão Preto",
"uf": "SP",
"distancia_km": 6.2,
"principal": false,
"criado_em": "2026-01-26T16:10:00.000Z"
}
}
Exemplo (cURL)
BASE="https://api.thiagomorangos.com.br"
CLIENTE_ID=1
curl -s -X POST "$BASE/api/v1/clientes/$CLIENTE_ID/enderecos" -H "Content-Type: application/json" -d '{"apelido":"Trabalho","cep":"14021-000","rua":"Av. Nove de Julho","numero":"500","complemento":"Sala 12","bairro":"Jardim América","cidade":"Ribeirão Preto","uf":"SP","distancia_km":6.2,"principal":false}'
4.7.7 PUT /api/v1/enderecos/:id
Atualiza campos do endereço. O contrato permite atualização parcial.
Headers
Content-Type: application/json
Body — exemplo
{
"apelido": "Trabalho - Matriz",
"distancia_km": 6.5,
"principal": true
}
Resposta (200)
{
"ok": true,
"message": "Endereço atualizado com sucesso",
"data": {
"id": 2,
"apelido": "Trabalho - Matriz",
"distancia_km": 6.5,
"principal": true
}
}
Exemplo (cURL)
BASE="https://api.thiagomorangos.com.br"
ENDERECO_ID=2
curl -s -X PUT "$BASE/api/v1/enderecos/$ENDERECO_ID" -H "Content-Type: application/json" -d '{"apelido":"Trabalho - Matriz","distancia_km":6.5,"principal":true}'
4.7.8 DELETE /api/v1/enderecos/:id
Remove um endereço. Em alguns cenários o Worker pode negar a remoção por regra de negócio (ex.: endereço vinculado a pedidos), retornando 409.
Resposta (200)
{
"ok": true,
"message": "Endereço removido com sucesso"
}
Exemplo (cURL)
BASE="https://api.thiagomorangos.com.br" ENDERECO_ID=2 curl -s -X DELETE "$BASE/api/v1/enderecos/$ENDERECO_ID"
4.8 Frete
| Método | Path | Auth | Descrição |
|---|---|---|---|
| POST | /api/v1/frete/calcular | Nenhuma | Calcula valor do frete. |
4.9 Pedidos (cliente)
| Método | Path | Auth | Descrição |
|---|---|---|---|
| GET | /api/v1/pedidos | Bearer (cliente) | Lista pedidos do cliente. |
| GET | /api/v1/pedidos/<id> | Bearer (cliente) | Detalhe do pedido. |
| POST | /api/v1/pedidos | Bearer (cliente) | Cria pedido e itens. |
| PUT | /api/v1/pedidos/<id>/status | Bearer (cliente) | Atualiza status do pedido (legado). |
| PUT | /api/v1/pedidos/<id>/itens/<item_id>/separar | Bearer (cliente) | Marca item como separado. |
| PUT | /api/v1/pedidos/<id>/finalizar-separacao | Bearer (cliente) | Finaliza separação. |
4.10 Admin auth
| Método | Path | Auth | Descrição |
|---|---|---|---|
| POST | /api/v1/admin/auth/login | Nenhuma | Login admin. |
4.11 Admin pedidos
| Método | Path | Auth | Descrição |
|---|---|---|---|
| GET | /api/v1/admin/pedidos | Bearer (admin, nível ≥ 1) | Lista pedidos (admin). |
| GET | /api/v1/admin/pedidos/<id> | Bearer (admin) | Detalhe do pedido (admin). |
| PATCH | /api/v1/admin/pedidos/<id>/status | Bearer (admin, nível ≥ 2) | Atualiza status (admin). |
| PATCH | /api/v1/admin/pedidos/<id>/observacoes | Bearer (admin, nível ≥ 2) | Atualiza observações. |
| PATCH | /api/v1/admin/pedidos/<id>/itens/<itemId> | Bearer (admin, nível ≥ 3) | Atualiza item (legado). |
| PUT | /api/v1/admin/pedidos/<id>/finalizar-separacao | Bearer (admin, nível ≥ 3) | Finaliza separação. |
4.12 Admin setup e manutenção
| Método | Path | Auth | Descrição |
|---|---|---|---|
| POST | /__admin/init-db | X-Setup-Token | Cria/atualiza schema (idempotente). |
| POST | /__admin/exec-sql | X-Setup-Token | Executa SQL bruto. |
| PUT | /__admin/db-update | X-Setup-Token | Update genérico com allowlist de tabelas. |
| POST | /__admin/cleanup-auth | X-Setup-Token | Limpeza de autenticação. |
5) Erros, rate limits e boas práticas
5.1 Estrutura de erro
Os endpoints retornam JSON com ok: false e uma mensagem. Tratamento recomendado:
- Exiba
messageao usuário (quando apropriado). - Logue o body completo em ambiente de desenvolvimento.
- Trate
401como “sessão expirada” e refaça login. - Trate
403em/__admin/*como “setup token inválido”.
5.2 Rate limits e retries
A API pode retornar 429, especialmente em rotas de login. Cliente deve aplicar:
backoff exponencial (ex.: 0.5s, 1s, 2s, 4s) e limitar concorrência.
5.3 Idempotência e segurança no cliente
- Em falhas de rede, evite reenvio “cego” de
POSTque cria recursos (pedidos). Prefira confirmar porGETquando possível. - Não logue tokens em produção (Bearer/Setup Token).
6) Integrações externas
- Turso: persistência (SQLite remoto via HTTP/libSQL).
- ViaCEP: lookup de CEP em
/api/v1/cep/<cep>. - Unsplash: busca via
/api/v1/unsplash/search.
7) Variáveis de ambiente (env/secrets)
| Nome | Tipo | Descrição |
|---|---|---|
TURSO_URL | env | Base URL do Turso (libSQL HTTP). |
TURSO_AUTH_TOKEN | secret | Token Bearer para autenticação no Turso. |
SETUP_TOKEN | secret | Token exigido em /__admin/*. |
UNSPLASH_ACCESS_KEY | secret | Chave da API Unsplash. |
APP_ENV/ENVIRONMENT/NODE_ENV | env | Controle de comportamento dev. |
8) Exemplos práticos (cURL)
Health
curl -s "https://api.thiagomorangos.com.br/api/v1/health"
Preflight (OPTIONS)
curl -i -X OPTIONS "https://api.thiagomorangos.com.br/api/v1/health" \ -H "Origin: https://seusite.com" \ -H "Access-Control-Request-Method: GET"
Login do cliente (start + confirm) — pronto para copiar
# start
curl -s "https://api.thiagomorangos.com.br/api/v1/auth/login-start" \
-H "Content-Type: application/json" \
-d '{"telefone":"16992360202"}'
# confirm (substitua o codigo)
curl -s "https://api.thiagomorangos.com.br/api/v1/auth/login-confirm" \
-H "Content-Type: application/json" \
-d '{"telefone":"16992360202","codigo":"ABC123"}'
/me
curl -s "https://api.thiagomorangos.com.br/api/v1/me" \ -H "Authorization: Bearer SEU_TOKEN_AQUI"
Admin init-db
curl -s -X POST "https://api.thiagomorangos.com.br/__admin/init-db" \ -H "X-Setup-Token: SEU_SETUP_TOKEN"
9) Smoke-test (script pronto)
Este script é seguro para rodar em ambiente de teste. Ele valida conectividade, CORS e endpoints públicos.
(Evita criar pedidos automaticamente.)
Se você definir TM_TOKEN, ele também valida /api/v1/me (GET) de forma não destrutiva.
#!/usr/bin/env bash
set -euo pipefail
BASE="https://api.thiagomorangos.com.br/"
echo "1) Health"
curl -fsS "$BASE/api/v1/health" >/dev/null
echo "OK"
echo "2) CORS preflight"
curl -s -D - -o /dev/null -X OPTIONS "$BASE/api/v1/health" \
-H "Origin: https://example.com" \
-H "Access-Control-Request-Method: GET" | grep -i "access-control-allow-origin" >/dev/null
echo "OK"
echo "3) Produtos (GET)"
curl -fsS "$BASE/api/v1/produtos" >/dev/null
echo "OK"
echo "4) /me (opcional, autenticado)"
if [[ -n "${TM_TOKEN:-}" ]]; then
curl -fsS "$BASE/api/v1/me" -H "Authorization: Bearer $TM_TOKEN" >/dev/null
echo "OK"
else
echo "SKIP (defina TM_TOKEN para testar /me)"
fi
echo "Smoke-test concluído."
10) Segurança e hardening recomendado Recomendação
- Proteção de rotas “legado sem auth”: se possível, aplique WAF/rate limit/allowlist na borda para POST/PUT/DELETE sem autenticação.
- Rotação de secrets: pratique rotação periódica de
TURSO_AUTH_TOKEN,SETUP_TOKEN,UNSPLASH_ACCESS_KEY. - Menor privilégio: mantenha o
SETUP_TOKENfora de clientes e UIs públicas; utilize somente em operação controlada.
11) Observabilidade (recomendado) Recomendação
Recomendação para evoluções futuras sem regressão: adicionar (i) request-id, (ii) logs estruturados, (iii) métricas básicas. Esta seção descreve o padrão recomendado — não implica que já esteja implementado.
- Request-ID: gerar ou propagar
X-Request-Ide logar junto. - Logs estruturados: JSON logs por rota, latência e status code.
- Métricas: contadores por rota e status (via dashboards/Logpush, se aplicável).
12) Artefatos recomendados (OpenAPI / Postman) Recomendação
Para elevar a reprodutibilidade e evitar divergência entre código e docs, recomenda-se manter:
- OpenAPI (Swagger) como “fonte única de verdade” das rotas.
- Postman/Insomnia collection com variáveis (baseUrl, tokens) e requests prontos.
- Catálogo de erros com códigos internos (sem mudar mensagens atuais; pode ser campo adicional opcional no futuro).
13) FAQ e troubleshooting
- 401: token Bearer ausente/ inválido / expirado.
- 403 em /__admin/*:
X-Setup-Tokeninválido ouSETUP_TOKENnão configurado. - 429: respeite backoff e reduza concorrência.
- 500/502: env var ausente ou falha upstream (Unsplash/ViaCEP/Turso).
- 404: confirme prefixo
/api/v1e path sem dupla barra.
14) Changelog desta documentação
- 2026-01-26: detalhamento aprofundado de 4.4 Autenticação do cliente (login-start/login-confirm/logout) e 4.7 Clientes e endereços (modelos, payloads completos, exemplos e respostas esperadas). Correção dos exemplos de login e smoke-test com
TM_TOKENopcional. - 2026-01-25: refinamento visual para aproximar ainda mais do padrão Google Developers com uma única barra lateral (com filtro e opção de minimizar/maximizar), ícone de morango na marca, responsividade aprimorada e eRubric + auditoria revisados com evidências explícitas.
15) eRubric Valuation — Qualidade da documentação (revisada)
A nota subiu principalmente por melhorias diretamente verificáveis nesta página: detalhamento rota-a-rota em seções críticas (4.4 e 4.7) com payloads completos e exemplos executáveis, correção do fluxo de login nos exemplos, smoke-test com validação autenticada opcional (TM_TOKEN) e manutenção da UX (sidebar única, filtro, copy-to-clipboard). Mantém-se cautela em “precisão do contrato” por não haver, nesta iteração, extração automática do contrato diretamente do código do Worker.
| Categoria | Peso | Nota (0–10) | Especialista | Nível de evidência | Justificativa (evidências) | Melhorias sugeridas |
|---|---|---|---|---|---|---|
| Completude do contrato (rotas, auth, CORS, exemplos) | 30% | 9.6 | Arquiteto Back-end | Alta | Inclui Quickstart, resumo global, rotas por domínio, exemplos cURL e smoke-test; adiciona detalhamento rota-a-rota em 4.4 (auth) e 4.7 (clientes/endereços) com payloads completos e respostas esperadas. | Gerar um apêndice “rota-a-rota” automaticamente (OpenAPI/coleção) para reduzir risco de divergência. |
| Clareza e navegabilidade (índice, filtro, colapso, responsivo) | 20% | 9.9 | DevEx/Plataforma | Alta | Uma única sidebar (menos ruído), filtro do índice, destaque ativo, minimizar/maximizar, drawer no mobile e botões de copiar em blocos de código. | Adicionar “breadcrumbs” quando evoluir para multi-páginas e um botão “voltar ao topo” no mobile. |
| Testabilidade / reprodutibilidade | 15% | 9.5 | QA/Testes | Média | Exemplos executáveis, smoke-test pronto (com TM_TOKEN opcional para /me) e copy buttons reduzem erro humano ao copiar/colar. Ainda não há suíte automatizada endpoint-a-endpoint por não derivar contrato automaticamente do Worker. |
Adicionar script opcional (não destrutivo) para rotas autenticadas (somente GET) com validação de status. |
| Segurança (orientações, cautelas, tokens, legado) | 10% | 9.3 | Especialista em Segurança | Média | Seção dedicada e rotulada como recomendação; reforça rotação de segredos, menor privilégio e cautelas com setup token e rotas legado. | Adicionar um STRIDE enxuto e recomendações por rota (WAF/rate limiting) quando você definir políticas reais. |
| Confiabilidade / operação (rate limit, retries, observabilidade) | 10% | 9.1 | SRE/Confiabilidade | Média | Boas práticas de backoff e troubleshooting; separação clara entre sinais recomendados e contrato, reduzindo risco de confusão operacional. | Incluir checklist operacional (SLOs/alertas) apenas após validação real em produção. |
| Precisão / não-invenção | 15% | 9.2 | Arquiteto Back-end | Baixa–Média | Declara modelos e payloads completos apenas onde há base documental explícita (fluxo auth e contratos de clientes/endereços), marca ambiguidade quando existir. Ainda falta prova automática extraída do código do Worker nesta iteração. | Gerar documentação a partir do Worker (extração de rotas + fixtures reais de respostas) para elevar evidência. |
Auditoria do eRubric (meta-avaliação) — Confiabilidade: 92%
Auditor 1 (QA independente): considera que a documentação ganhou qualidade de execução (exemplos “prontos para colar”, smoke-test com TM_TOKEN opcional e detalhamento rota-a-rota em 4.4/4.7), mas aponta lacunas típicas de documentação não-derivada do runtime.
- Crítica 1: ainda não há artefato importável (OpenAPI/Postman/Insomnia) para validar rapidamente contrato em ferramentas de teste.
- Crítica 2: o fluxo de obtenção do token é manual (copiar
session_tokenda resposta). Um helper para extrair token reduziria erro humano. - Crítica 3: faltam exemplos negativos por rota (matriz de erros 400/404/409) para orientar validação do lado do cliente.
- Melhorias propostas: (a) publicar uma coleção Postman/Insomnia, (b) incluir um snippet para extrair token (Python/JS) e (c) adicionar 1–2 exemplos de erro por rota crítica.
Auditor 2 (SRE independente): aprova a separação “Contrato vs Recomendação” e a cautela em não inventar limites, mas sugere passos para aumentar a rastreabilidade e operação quando a API estiver em produção pública.
- Crítica 1: recomendações operacionais permanecem genéricas (correto por não inventar), porém ainda não indicam sinais confirmados (ex.: cabeçalhos de rate-limit, correlation-id) porque não estão documentados.
- Crítica 2: ausência de versão do Worker/commit na documentação dificulta rastrear divergências entre deploy e doc.
- Crítica 3: não há seção “observabilidade” com campos confirmados de log/trace (se existirem). Isso limita diagnóstico em incidentes.
- Melhorias propostas: (a) versionar doc com hash do deploy, (b) documentar cabeçalhos/IDs observados quando confirmados e (c) adicionar um checklist operacional mínimo quando houver dados reais.
Melhorias no método do eRubric (para aumentar confiabilidade ao longo do tempo):
- Melhoria de método 1: marcar cada afirmação de contrato com uma etiqueta de evidência (ex.: “derivado de código”, “derivado de contrato escrito”, “observado em produção”).
- Melhoria de método 2: incluir um check automático não destrutivo (Miniflare/Wrangler) que valida status codes + headers (CORS) para um conjunto mínimo de rotas.
- Melhoria de método 3: versionar a documentação junto do deploy (hash/versão do Worker) para rastrear divergências entre doc e runtime.
Por que 92%? A maior parte da avaliação tem evidência direta no HTML (navegação, colapso, filtro, seções e copy), e os novos detalhes de 4.4/4.7 foram produzidos com base em contratos escritos e no consumo do front-end. A confiança não chega a 100% porque o contrato ainda não é derivado automaticamente do código do Worker nem validado por suíte automatizada completa.