Skip to main content
Glama
gsbenevides2

my-mcp-app

by gsbenevides2
README.md
# Unhide

> Em um e-commerce, muita receita não está perdida — ela só está escondida.

**Unhide** é um agente de inteligência e ação para operações de e-commerce, entregue como um
**MCP App**: um servidor MCP (Model Context Protocol) que expõe ferramentas sobre uma loja
Shopify **e** um dashboard interativo que roda dentro do host MCP (deco, Claude, etc.).

---

## Índice

- [Contexto do projeto](#contexto-do-projeto)
- [O que o Unhide entrega](#o-que-o-unhide-entrega)
- [Como funciona (arquitetura)](#como-funciona-arquitetura)
- [Instruções de execução](#instruções-de-execução)
- [Configuração de ambiente (envs)](#configuração-de-ambiente-envs)
- [Ferramentas MCP disponíveis](#ferramentas-mcp-disponíveis)
- [Estrutura de pastas](#estrutura-de-pastas)
- [Tecnologias usadas](#tecnologias-usadas)
- [Qualidade, testes e CI](#qualidade-testes-e-ci)
- [Deploy](#deploy)

---

## Contexto do projeto

Quem opera um e-commerce de alto volume sabe que a loja perde dinheiro em dezenas de pontos
todos os dias:

- um produto recebe **muita intenção de compra, mas não converte**;
- outro está **há semanas parado no estoque**, com capital imobilizado;
- uma **mudança de demanda** começa a acontecer e a operação só percebe depois;
- centenas ou milhares de produtos **poderiam ser melhor encontrados** — por pessoas e, agora,
  também por agentes de IA.

O problema não é falta de dado. Os dados já existem na plataforma — só estão **espalhados** entre
catálogo, tráfego, estoque, pedidos, busca interna e comportamento do consumidor. Encontrar essas
oportunidades, decidir o que fazer e executar manualmente é trabalho de uma equipe inteira em
tempo integral.

O Unhide observa os sinais da operação, encontra as oportunidades escondidas e **transforma
oportunidade em ação**:

- cruza **intenção × conversão × margem/markup** para achar o **menor incentivo necessário** para
  vender mais sem sacrificar rentabilidade — a pergunta deixa de ser "quanto desconto eu dou?";
- na frente de estoque, procura a **interseção entre capital parado e demanda real** — não apenas
  a lista de produtos com mais estoque;
- audita e transforma a loja para **descoberta em SEO e GEO**, deixando catálogo e produtos
  estruturados para os consumidores de hoje e para os agentes que vão descobrir, recomendar e
  comprar amanhã;
- e centraliza tudo em uma **visão 360** que serve de **camada de contexto para o próprio agente**
  — é dali que ele entende o que está acontecendo, quais sinais merecem atenção e onde existe uma
  oportunidade que vira ação.

A diferença: de um lado, visão profunda do negócio; do outro, um agente capaz de conversar com
esses dados, cruzá-los e agir sobre eles. Não é mais um dashboard dizendo o que aconteceu.

---

## O que o Unhide entrega

O dashboard é organizado em quatro abas — as mesmas quatro frentes do produto.

### 🩺 Diagnóstico

Visão geral da operação em um só lugar: sessões, visitantes, tráfego por origem, comportamento e
funil (bounce, adição ao carrinho, checkout iniciado × concluído), busca interna (incluindo buscas
**sem resultado**, o sinal mais claro de lacuna de catálogo), intenção de compra por fonte e a
quebra de conversão por produto, tipo, coleção, canal ou cliente novo × recorrente.

Inclui ainda o painel de **descontos gerados por IA**: a receita atribuída às promoções que o
próprio agente criou — ou seja, dá para **metrificar claramente o ganho do agente**, não só o que
ele fez.

### 🔎 SEO

Relatório com **nota 0–100 por produto**, calculada a partir de título de página, meta description,
handle da URL, descrição e imagem — com os pontos concretos de melhoria de cada um. Dá para editar
o SEO manualmente ou pedir para a **IA preencher automaticamente**, usando o contexto da loja e do
catálogo, e publicar direto na Shopify.

### 🤖 GEO (Generative Engine Optimization)

A aba que prepara a loja para o futuro da descoberta. Avalia o quanto cada produto está pronto
para ser **citado e recomendado pelas IAs de busca**, com base no metafield `geo_data` (descrição
longa, marca, MPN, material, cor, público-alvo, tabela de especificações, FAQ e destaques). Também
tem geração assistida por IA, com **publicação automática na loja** — deixando o catálogo pronto
para indexação por robôs, LLMs e protocolos de agente.

### 📦 Estoque parado

Cruza estoque com vendas para encontrar produtos **sem giro** na janela escolhida e, para cada um,
monta o público que vale abordar: quem **abandonou um checkout** com aquele produto e quem
**comprou o mesmo tipo de produto** no período. O resultado é um **segmento revisável e exportável
em CSV** para o time de CRM — o Unhide monta a lista, não dispara e-mail.

---

## Como funciona (arquitetura)

**App de visão única.** Exatamente **uma** ferramenta carrega UI (`unhide_dashboard`); todas as
outras são chamadas por dentro dela ou diretamente por um agente. O Vite gera **um único HTML**
(`dist/client/index.html`, com CSS e JS inlined) servido como o único recurso MCP.

**Os painéis buscam os próprios dados.** `unhide_dashboard` só resolve as configurações (domínio
da loja, período, limites). Cada painel então chama sua própria ferramenta via `useServerTool` →
`app.callServerTool`. Consequência prática: os painéis **carregam em paralelo e falham
independentemente** — uma varredura lenta de SEO nunca segura o analytics, e credencial faltando
quebra uma célula, não a tela.

```
Host MCP (deco / Claude)
   │  chama unhide_dashboard
   ▼
api/ (servidor MCP, @decocms/runtime)     ──►  Shopify Admin GraphQL API (ShopifyQL, produtos,
   │  serve o recurso ui://mcp-app/…            descontos, pedidos, metafields)
   ▼                                      ──►  Shopify Storefront API (listagem de produtos)
web/ (React 19, bundle único)
   └─ cada painel chama de volta o servidor via callServerTool
```

**Camadas do código:**

- **`api/tools/`** — a superfície MCP: cada arquivo é uma ferramenta com schemas Zod de entrada e
  saída.
- **`api/lib/`** — a lógica de verdade: transporte para a Admin API (com retry de throttling e
  limite de concorrência), consultas ShopifyQL, cálculo de score de SEO/GEO, descontos, lookup de
  produto.
- **`api/app.ts`** — núcleo agnóstico de plataforma; exporta um handler `{ fetch }` com middleware
  de log e o rewrite de `/api/mcp` → `/mcp`.
- **`api/main.bun.ts`** — entrypoint Bun (padrão). Para outra plataforma, basta um novo
  `api/main.<plataforma>.ts`.
- **`web/`** — a UI React que conecta no host via `@modelcontextprotocol/ext-apps`.

---

## Instruções de execução

### Pré-requisitos

- [**Bun**](https://bun.sh) (runtime do projeto — não Node)
- Uma **loja Shopify** com um **custom app** criado (para obter os tokens)
- Um **host MCP** para abrir o dashboard (deco Studio, Claude, ou qualquer cliente MCP)

### 1. Instalar

```bash
bun install
```

### 2. Configurar as variáveis de ambiente

```bash
cp .env.example .env
# preencha SHOPIFY_STORE_DOMAIN e os tokens — ver a seção de envs abaixo
```

### 3. Rodar em desenvolvimento

```bash
bun run dev
```

Sobe duas coisas em paralelo (via `concurrently`):

- a **API MCP** em `http://localhost:3001`, com hot reload → endpoint MCP em
  `http://localhost:3001/api/mcp`
- o **build do front** em modo watch, gerando `dist/client/index.html`

> ⚠️ O recurso da UI lê `dist/client/index.html` do disco. Rodar só `bun run dev:api` sem nunca ter
> buildado o front faz o dashboard falhar ao abrir — use `bun run dev`, ou rode um
> `bun run build:web` antes.

Comandos individuais:

```bash
bun run dev:api      # só a API (porta 3001, hot reload)
bun run dev:web      # só o build do front (watch)
```

### 4. Conectar em um host MCP

Para testar em um host remoto (como o deco Studio), exponha o servidor local por um túnel:

```bash
bun start
# Tunnel started -> 🌐 Preview: https://<seu-id>.deco.host
#    -> 🔗 MCP URL: https://<seu-id>.deco.host/api/mcp
```

Depois, conecte no host usando a **MCP URL** impressa. Localmente, a URL é
`http://localhost:3001/api/mcp`.

Com a conexão feita, chame a ferramenta **`unhide_dashboard`** — ela é o ponto de entrada visual.

### 5. Build de produção

```bash
bun run build          # front + servidor
bun run build:web      # só o front  -> dist/client/index.html
bun run build:server   # só o server -> dist/server/main.js

NODE_ENV=production bun dist/server/main.js
```

### 6. Docker

```bash
docker build -t unhide .
docker run -p 3001:3001 --env-file .env unhide
```

### Referência rápida de scripts

| Comando | O que faz |
| --- | --- |
| `bun run dev` | API + build do front, em paralelo (watch) |
| `bun run dev:api` | Só a API, porta 3001, hot reload |
| `bun run dev:web` | Só o build do front, em watch |
| `bun start` | `deco link` — expõe o servidor local por um túnel público |
| `bun run build` | Build completo de produção |
| `bun run check` | Type check (`tsc --noEmit`) |
| `bun run ci:check` | Lint + format check do Biome (modo CI, sem auto-fix) |
| `bun run fmt` | Formata com o Biome |
| `bun run lint` | Corrige lint automaticamente |
| `bun test` | Roda os testes (test runner do Bun) |
| `bun test <arquivo>` | Roda um arquivo de teste específico |
| `bun run scripts/diagnose-analytics.ts` | Diagnostica valores nulos vindos do ShopifyQL |

---

## Configuração de ambiente (envs)

Todas as variáveis ficam em `.env` na raiz (há um `.env.example` versionado como modelo). O `.env`
está no `.gitignore` — nunca comite tokens.

### Obrigatórias

| Variável | Descrição |
| --- | --- |
| `SHOPIFY_STORE_DOMAIN` | Domínio da loja, **sem protocolo**. Ex.: `minha-loja.myshopify.com` |
| `SHOPIFY_ADMIN_ACCESS_TOKEN` | Token da **Admin API** (`shpat_…`). Usado por praticamente tudo: analytics, SEO, GEO, promoções, estoque parado, updates de produto |

### Opcional (mas necessária para uma ferramenta específica)

| Variável | Descrição |
| --- | --- |
| `SHOPIFY_ACCESS_TOKEN` | Token da **Storefront API**. Usado apenas por `shopify_list_products` |

### Opcionais com padrão

| Variável | Padrão | Descrição |
| --- | --- | --- |
| `SHOPIFY_API_VERSION` | `2025-10` | Versão da Storefront API |
| `SHOPIFY_ADMIN_API_VERSION` | `2026-07` | Versão da Admin API |
| `SHOPIFY_GEO_METAFIELD_NAMESPACE` | `custom` | Namespace do metafield `geo_data` lido/escrito pelo relatório de GEO. Só mude se a loja guardar o campo em outro lugar |
| `SHOPIFY_CURRENCY` | — | Override ISO 4217 (ex.: `BRL`) para os valores monetários. Sem ele, a moeda da loja é lida uma vez da Admin API — defina para pular esse round trip ou quando o token não puder ler `shop` |
| `SHOPIFY_ANALYTICS_DEBUG` | — | Qualquer valor liga o trace das chamadas à Admin API no console. Útil para entender por que um número voltou nulo |
| `PORT` | `3001` | Porta do servidor |
| `NODE_ENV` | — | `production` no build/servidor de produção |

### Escopos da Admin API

O token precisa dos escopos das ferramentas que você pretende usar:

| Escopo | Habilita |
| --- | --- |
| `read_reports` | Todas as ferramentas `shopify_analytics_*` (ShopifyQL) |
| `read_products` | Relatórios de SEO e GEO, busca e leitura de produto |
| `write_products` | `shopify_update_product` e `shopify_update_product_geo` |
| `read_discounts` | `shopify_list_promotions` |
| `write_discounts` | `shopify_create_promotions` |
| `read_orders` | `shopify_ai_discount_usage` e `dead_stock_campaign` (pedidos e checkouts abandonados) |
| `read_customers` | Dados de contato dos clientes nos segmentos de `dead_stock_campaign` |

> 💡 A Shopify limita `read_orders` aos **últimos 60 dias**. Como a janela padrão do estoque parado
> é de 90 dias, uma janela maior que 60 dias exige o escopo `read_all_orders` (concedido sob
> solicitação à Shopify) — ou reduza `deadStockWindowDays`.

**Onde obter os tokens:** Shopify admin → *Settings* → *Apps and sales channels* → *Develop apps*
→ seu app → configure os escopos de **Admin API** (e/ou **Storefront API**) → *Install* → revele o
token.

---

## Ferramentas MCP disponíveis

19 ferramentas registradas em `api/tools/index.ts`. Só a primeira carrega UI.

### Entrada visual

| Ferramenta | O que faz |
| --- | --- |
| `unhide_dashboard` | Abre o dashboard do Unhide. Resolve as configurações dos painéis (loja, período, limites) — os dados vêm depois, painel a painel |

### Analytics da loja

| Ferramenta | O que faz |
| --- | --- |
| `shopify_analytics_overview` | Painel consolidado: funil de navegação, tráfego e intenção por origem, busca interna e quebra de conversão. Seções que falham degradam individualmente, reportadas em `errors` |
| `shopify_analytics_sessions` | Sessões, visitantes, pageviews, bounce, duração, carrinho e checkout — com quebra por device, país, região, cidade, SO, tipo de landing page ou dia |
| `shopify_analytics_intent` | Sinais de intenção de compra por origem de tráfego, páginas de produto mais acessadas e split novo × recorrente |
| `shopify_analytics_search` | Termos buscados na loja, intenção detectada, CTR e funil de busca. Filtro para buscas **sem resultado** |
| `shopify_analytics_conversion` | Quebra de compras por produto, tipo, coleção, fornecedor, canal ou tipo de cliente, com AOV e share de pedidos |
| `shopify_ai_discount_usage` | Receita atribuída aos descontos criados por este servidor: varre os pedidos da janela e atribui o valor por cupom e por dia |

### Catálogo

| Ferramenta | O que faz |
| --- | --- |
| `shopify_search_products` | Busca produtos por nome, marca, categoria, tag, SKU ou código de barras. Ponto de partida quando o usuário **cita** um produto em vez de linkar |
| `shopify_get_product` | Carrega tudo de um produto em uma chamada: descrição, SEO e nota, tags, preço, estoque, variantes e imagens. Lista os *runner-ups* quando o nome foi ambíguo |
| `shopify_list_products` | Listagem simples via **Storefront API** — útil para validar a conexão de saída com a Shopify |
| `shopify_update_product` | Atualiza título, descrição, handle, tags, campos de SEO e imagem (por URL ou upload). Só os campos enviados mudam |

### SEO

| Ferramenta | O que faz |
| --- | --- |
| `shopify_seo_report` | Varre o catálogo e pontua o SEO (0–100) de cada produto, com os pontos de melhoria |
| `shopify_seo_product_report` | A mesma análise, focada em um produto (aceita handle, id, URL da loja ou URL do admin) |

### GEO

| Ferramenta | O que faz |
| --- | --- |
| `shopify_geo_report` | Varre o catálogo e pontua a saúde de GEO (0–100) pelo metafield `geo_data` |
| `shopify_geo_product_report` | A mesma análise, focada em um produto |
| `shopify_update_product_geo` | Escreve o `geo_data`: descrição longa, marca, MPN, material, cor, público, specs, FAQ e destaques. Merge parcial — o resto do metafield é preservado |

### Ação comercial

| Ferramenta | O que faz |
| --- | --- |
| `shopify_create_promotions` | Cria descontos automáticos em lote (% ou valor fixo, um por produto). Cada desconto é marcado duas vezes (prefixo no título + metafield `mcp_promotions`) para ser reencontrado. Tem `dryRun` |
| `shopify_list_promotions` | Lê de volta os descontos criados por aqui, com o metafield do lote já parseado |
| `dead_stock_campaign` | Encontra estoque parado e monta, por produto, o público a abordar (checkout abandonado + quem comprou o mesmo tipo). Retorna segmento para exportação — **não dispara nada** |

### Prompt

| Prompt | O que faz |
| --- | --- |
| `improve-product-data` | Recebe o handle de um produto, analisa os relatórios de SEO e GEO, propõe os campos faltantes e aplica **após sua aprovação** |

---

## Estrutura de pastas

```
.
├── api/                              # Servidor MCP (agnóstico de plataforma)
│   ├── app.ts                        # Núcleo: runtime, middleware de log, rota /api/mcp
│   ├── main.bun.ts                   # Entrypoint Bun (padrão, usado no dev local)
│   ├── tools/                        # Uma ferramenta MCP por arquivo (schemas Zod in/out)
│   │   ├── index.ts                  # Registro de todas as ferramentas
│   │   ├── unhide-dashboard.ts       # A única ferramenta com UI (_meta.ui)
│   │   ├── analytics-*.ts            # Overview, sessions, intent, search, conversion
│   │   ├── shopify-seo-*.ts          # Relatório de SEO (loja e produto)
│   │   ├── shopify-geo-*.ts          # Relatório de GEO + update do metafield
│   │   ├── shopify-{get,search,list}-product*.ts
│   │   ├── promotions-*.ts           # Criação e listagem de descontos
│   │   ├── dead-stock-campaign.ts    # Estoque parado + segmento de clientes
│   │   └── ai-discount-usage.ts      # Receita atribuída aos descontos da IA
│   ├── lib/                          # Lógica de domínio e transporte
│   │   ├── shopify-admin.ts          # Porta única da Admin GraphQL: retry de throttle,
│   │   │                             #   limite de concorrência, score de SEO, upload de imagem
│   │   ├── shopify-analytics.ts      # Consultas ShopifyQL e mapeamento de colunas
│   │   ├── shopify-discounts.ts      # Descontos automáticos (criação/leitura)
│   │   ├── seo-report.ts             # Varredura e scoring de SEO
│   │   ├── geo-report.ts             # Metafield geo_data, scoring de GEO
│   │   ├── product-lookup.ts         # Resolve nome/handle/id/URL para um produto
│   │   ├── improve-product-prompt.ts # Texto do prompt de melhoria
│   │   ├── analytics/                # Funis: sessions, intent, search, conversion, descontos
│   │   └── coerce.ts                 # Coerções de tipo dos retornos do ShopifyQL
│   ├── prompts/                      # Prompts MCP (improve-product-data)
│   ├── resources/
│   │   └── unhide-dashboard.ts       # Serve dist/client/index.html como recurso MCP
│   └── types/env.ts                  # StateSchema + tipo Env
│
├── web/                              # UI React (MCP App) — bundle único
│   ├── app.tsx                       # Composição raiz (providers)
│   ├── context.tsx                   # Ponte com o host MCP + estado da chamada
│   ├── router.tsx                    # ToolRouter — TOOL_PAGES tem uma entrada só
│   ├── types.ts                      # McpStatus e tipos do ciclo de vida
│   ├── tools/
│   │   ├── unhide-dashboard/         # A tela: abas, grid, FeaturePanel, useServerTool
│   │   ├── analytics-overview/       # Abas de tráfego, sessões, busca, conversão, descontos IA
│   │   ├── shopify-seo-report/       # Lista + filtros + edição de SEO
│   │   ├── shopify-geo-report/       # Lista + filtros + formulário de GEO
│   │   └── dead-stock-campaign/      # Segmentos + exportação CSV
│   ├── components/
│   │   ├── patterns.tsx              # Primitivos do design system (PageShell, Chip, StatTile…)
│   │   ├── ai-fill-button.tsx        # Botão "preencher com IA"
│   │   ├── product-score.tsx         # Selo de nota do produto
│   │   └── ui/                       # shadcn/ui
│   ├── hooks/ · lib/                 # use-mobile, cn(), formatadores
│   └── globals.css                   # Tailwind v4 + fonte Manrope
│
├── scripts/
│   ├── start.ts                      # `deco link` + túnel, imprime a MCP URL
│   ├── diagnose-analytics.ts         # Sondas ShopifyQL para depurar valores nulos
│   └── dev-worktree.ts               # Dev server por worktree
│
├── .github/workflows/                # Release: versão, changelog, imagem Docker, deploy Coolify
├── index.html                        # Entrada única do Vite
├── vite.config.ts                    # React + Tailwind + singlefile, alias @ -> web/
├── Dockerfile                        # Build multi-stage em Bun
├── app.json                          # Manifesto do app deco (nome, conexão, metadados)
├── biome.json · tsconfig.json · components.json
├── .env.example                      # Modelo das variáveis de ambiente
├── CLAUDE.md / AGENTS.md             # Guia para agentes de código neste repo
└── data/                             # Snapshots e corpus locais (fora do git)
```

---

## Tecnologias usadas

**Runtime e servidor**

- [**Bun**](https://bun.sh) — runtime, gerenciador de pacotes e test runner
- [**@decocms/runtime**](https://github.com/decocms/runtime) — servidor MCP (tools, prompts,
  resources); exposto em `/api/mcp` via SSE
- [**@modelcontextprotocol/sdk**](https://modelcontextprotocol.io) — protocolo MCP
- [**Zod v4**](https://zod.dev) — schemas de entrada/saída de toda ferramenta

**Front-end**

- [**React 19**](https://react.dev) + **React Compiler** (via `babel-plugin-react-compiler`)
- [**@modelcontextprotocol/ext-apps**](https://www.npmjs.com/package/@modelcontextprotocol/ext-apps)
  — SDK de MCP Apps: conexão com o host, input/resultado da ferramenta, `callServerTool`
- [**TanStack Router**](https://tanstack.com/router) (hash-based) + [**TanStack Query**](https://tanstack.com/query)
- [**Tailwind CSS v4**](https://tailwindcss.com) + [**shadcn/ui**](https://ui.shadcn.com) +
  [**Radix UI**](https://radix-ui.com) / [**Base UI**](https://base-ui.com)
- [**Recharts**](https://recharts.org) — gráficos do diagnóstico
- **lucide-react**, **sonner**, **react-hook-form**, **date-fns**

**Build e qualidade**

- [**Vite 7**](https://vitejs.dev) + [**vite-plugin-singlefile**](https://github.com/nickreese/vite-plugin-singlefile)
  — um HTML autocontido, com CSS e JS inlined
- [**Biome**](https://biomejs.dev) — lint + format (tab, aspas duplas, extensão obrigatória nos
  imports)
- **TypeScript 5.9** em modo estrito

**Integrações externas**

- **Shopify Admin GraphQL API** — ShopifyQL (analytics), produtos, metafields, descontos, pedidos
- **Shopify Storefront API** — listagem pública de produtos

### Convenções de código

- Imports **precisam** incluir a extensão `.ts` / `.tsx` (`useImportExtensions: error`)
- Alias `@/*` → `web/*`
- Indentação com **tab**, aspas duplas (Biome)
- Todo schema (entrada, saída, estado) em Zod
- Design system: **glassmorphism suave**, sem bordas em containers — use os primitivos de
  `web/components/patterns.tsx`. As regras completas estão em `CLAUDE.md`

---

## Qualidade, testes e CI

```bash
bun test              # todos os testes
bun test api/lib/seo-report.test.ts
bun run check         # type check
bun run ci:check      # lint + format (CI)
```

Os testes ficam ao lado do código que cobrem (`*.test.ts`) e concentram-se na lógica pura:
scoring de SEO/GEO, mapeamento de colunas do ShopifyQL, coerções, parsing de referência de
produto, montagem de campanhas e geração de CSV.

Para depurar analytics vindo nulo:

```bash
bun run scripts/diagnose-analytics.ts             # todas as sondas
bun run scripts/diagnose-analytics.ts sessions    # só as que casam com "sessions"
bun run scripts/diagnose-analytics.ts --raw       # inclui o payload GraphQL cru
```

Cada sonda mostra, por coluna, o nome retornado, o `dataType` e o primeiro valor — o que distingue
"coluna ausente" de "sem dado na janela" de "bug de mapeamento".

---

## Deploy

### Multi-plataforma

A separação entre `api/app.ts` (lógica) e `api/main.bun.ts` (wiring de plataforma) permite
adicionar um alvo novo com um arquivo fino:

- **Bun** — `api/main.bun.ts` (padrão)
- **Cloudflare Workers** — ~5 linhas + `wrangler.toml`
- **Deno** — ~5 linhas
- **Node.js** — ~5 linhas + `@hono/node-server`
- **AWS Lambda** — ~5 linhas + `hono/aws-lambda`

Veja a skill [`add-deploy-target`](.claude/skills/add-deploy-target/SKILL.md) para o passo a passo.

### Pipeline atual

O workflow `.github/workflows/release.yml` dispara em push na `main` que altere `package.json`:
prepara a versão e o changelog, cria a release, builda e publica a imagem Docker e aciona o deploy
no **Coolify** por webhook.

### Publicar no deco

1. Ajuste `app.json` com nome, descrição e a URL de conexão do seu app
2. Faça push — o CI valida o build
3. Siga o fluxo de publicação do deco (veja a skill
   [`publish-store`](.claude/skills/publish-store/SKILL.md))



## Telas do Projeto

### Aba Diagnóstico
<img width="1920" height="4640" alt="screencapture-studio-decocms-low-cortisol-78ed97eb-477b-4d79-a704-22e5e4e7fd2e-2026-08-09-20_53_45" src="https://github.com/user-attachments/assets/4f898b21-e747-44d4-88a1-7dbe4baf3323" />

### Aba SEO
<img width="1920" height="1639" alt="screencapture-studio-decocms-low-cortisol-78ed97eb-477b-4d79-a704-22e5e4e7fd2e-2026-08-09-20_58_56" src="https://github.com/user-attachments/assets/8db82f23-1a8d-4c40-ac1e-96db611e8422" />

### Aba GEO
<img width="1920" height="1639" alt="screencapture-studio-decocms-low-cortisol-78ed97eb-477b-4d79-a704-22e5e4e7fd2e-2026-08-09-20_59_24" src="https://github.com/user-attachments/assets/d9dd0268-7a0b-4d51-891d-827849c762ce" />

### Aba Estoque Parado
<img width="1920" height="2483" alt="screencapture-studio-decocms-low-cortisol-78ed97eb-477b-4d79-a704-22e5e4e7fd2e-2026-08-09-20_59_37" src="https://github.com/user-attachments/assets/117d0b69-8d2a-4d60-a8c9-1c5b0a632948" />