# Documentação Geral e Técnica do Projeto ProcessoPro Marketplace
**Plataforma:** ProcessoPro (`processopro.net`)  
**Data:** Setembro/2026  
**Versão:** 2.5 (Produção Estável)  
**Ambiente:** VPS Dedicada (`84.247.189.155` • Linhares/ES)  
**Core Tecnológico:** MedusaJS v2 • PostgreSQL (Porta 5434) • Nginx • PWA • WhatsApp Notifier

---

## 1. Visão Geral da Arquitetura

O ProcessoPro é um marketplace local de alta performance criado para conectar lojas físicas e compradores do município de Linhares/ES, unificando estoque físico real, checkout sem atrito (sem senha), validação de retirada via PIN/QR Code e entregas expressas no mesmo dia.

```
       [ Usuário / PWA Mobile (processopro.net) ]
                         │
                         ▼ (HTTPS / Porta 443)
       [ Nginx Reverse Proxy (SSL Let's Encrypt) ]
           │                 │                   │
           ▼                 ▼                   ▼
    [ SPA Frontend ]  [ MedusaJS v2 Core ]  [ Monitor Preços ]
     (/var/www/html)   (Porta 9000 / Node)    (Porta 8500)
                             │
                             ▼
         [ PostgreSQL 16 Central - processopro_db (Porta 5434) ]
                   (Multi-Tenant por linha: loja_id)
```

---

## 2. Banco de Dados Relacional & Multi-Tenant (PostgreSQL 5434)

Para garantir escalabilidade com centenas de lojistas sem degradação de memória, o sistema utiliza a arquitetura **Multi-tenant por Linha (Row-Level Tenancy)** com chave estrangeira `loja_id`.

### Tabela `lojas`
Armazena os dados cadastrais, endereço físico no município e canais sociais:
- `id`: Chave primária serial.
- `slug`: Identificador amigável (ex: `loja_calcados_silva`).
- `nome_fantasia`: Nome da loja física (ex: `Calçados Silva & Cia`).
- `endereco`: Endereço completo no município de Linhares/ES.
- `whatsapp`: Número do balcão para avisos de separação (`5527998881234`).
- `instagram`: Perfil social para injeção no WhatsApp (`@calcados.silva`).
- `tiktok`: Perfil de vídeos curtos da loja (`@calcados.silva`).

### Tabela Centralizada `produtos`
- `id`: Chave primária.
- `loja_id`: Chave estrangeira que isola a posse do produto.
- `sku`: Código único de identificação no ERP.
- `titulo`: Nome comercial do item.
- `preco`: Preço de tabela em centavos (ex: `15990` = R$ 159,90).
- `preco_pix`: Preço promocional para pagamento instantâneo.
- `estoque_balcao`: Saldo bruto em unidades físicas.
- `tamanhos`: String parseável de variações com saldo individual (ex: `38:6,39:9,40:12,41:8,42:3,43:0`).
- `ativo`: Booleano para exibição ou pausa na vitrine pública.
- `trava_preco`: Flag de escudo contra sobrescrita indevida do ERP.
- `trava_status`: Flag que impede o ERP de reativar item pausado no balcão.

### Segurança de Isolamento (Tenant Isolation)
Tentativas de alteração de produtos cruzando lojas são barradas no nível de query e API:
```sql
UPDATE produtos 
SET preco = $1, estoque_balcao = $2 
WHERE id = $3 AND loja_id = $4;
```
*Se a `loja_id` não for dona do produto, 0 linhas são afetadas e a API retorna imediatamente `HTTP 403 Forbidden`.*

---

## 3. APIs REST no MedusaJS v2 (`/opt/processopro-medusa`)

Todas as rotas de negócio do ProcessoPro operam como módulos nativos do MedusaJS v2:

### `GET /api/lojas/:loja_id/produtos`
Lista os produtos ativos da loja informada, retornando a grade de numerações estruturada em JSON (`tamanhos_lista: [{ tamanho: '40', estoque: 12 }, ...]`).

### `POST /api/produtos` e `PATCH /api/produtos`
Cadastra e atualiza itens na tabela central com validação estrita de posse e tenant.

### `POST /api/pedidos/status`
Gerencia a máquina de estados do pedido:
- `pending`: Pedido gerado, aguardando confirmação do Pix.
- `paid`: Pagamento aprovado; reserva o estoque e dispara o WhatsApp duplo.
- `pronto_retirada`: Item separado no balcão físico, aguardando o cliente com PIN.
- `saiu_entrega`: Despachado com entregador local com estimativa de tempo.

### `POST /api/pedidos/validar-pin`
Utilizado pelo atendente no balcão ou via leitura de QR Code no smartphone:
1. Valida o PIN (ex: `PP-4821`).
2. Transiciona o pedido para `entregue_no_balcao`.
3. Dispara mensagem automática de conclusão no WhatsApp do comprador com recibo digital.

### `GET /api/metricas/municipio`
Consolida os indicadores de desempenho da cidade de Linhares/ES:
- Volume total transacionado via Pix (R$ 148.920,50).
- Crescimento mensal (+38.4%).
- Total de pedidos (842 entregues).
- Bairros com maior demanda (Centro 34%, Interlagos 22%, Aviso 14%).
- Tempo médio de liberação no balcão: **3.4 minutos**.

---

## 4. Sistema de Notificações WhatsApp & Catálogo Social

O serviço `src/services/whatsapp-notifier.ts` orquestra a comunicação em tempo real tanto com o comprador quanto com o lojista:

### Notificação Dupla (Two-Way Notification):
1. **Comprador:**
   - Confirmação do pagamento Pix em tempo real.
   - Código do PIN de liberação (`PP-4821`) ou QR Code.
   - Injeção dinâmica dos canais sociais da loja física:
     * 📸 *Instagram:* `instagram.com/calcados.silva`
     * 🎵 *TikTok:* `tiktok.com/@calcados.silva`
2. **Balcão da Loja Física:**
   - Alerta sonoro/visual de novo pedido pago para separação imediata na prateleira física.

---

## 5. Regra de Convivência: ERP da Loja vs. Gestão Manual no Painel

O sistema permite que o lojista crie promoções de fim de semana ou pause produtos sem que o sincronizador do ERP desfaça suas ações:

```sql
INSERT INTO produtos (loja_id, sku, preco, preco_pix, ativo, foto)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT (loja_id, sku) DO UPDATE SET
    estoque_balcao = EXCLUDED.estoque_balcao,
    preco_pix = CASE 
        WHEN produtos.trava_preco = TRUE THEN produtos.preco_pix 
        ELSE EXCLUDED.preco_pix 
    END,
    ativo = CASE 
        WHEN produtos.trava_status = TRUE THEN produtos.ativo 
        ELSE EXCLUDED.ativo 
    END;
```

### Mecanismo de Desconexão (Offline Resilience):
Se a internet ou o computador do caixa da loja física cair, as vendas continuam normais no site. As baixas de estoque acumulam na tabela `fila_sincronizacao_erp` e sincronizam em lote assim que o caixa religar.

---

## 6. Guia Visual "Como Funciona?" (Linguagem Passo a Passo para Todos)

Um sistema intuitivo de botões flutuantes `[ ❓ Como funciona? ]` em cada tela do marketplace, projetado com linguagem tão simples e ilustrada que até uma criança de 10 anos compreende:

### A. Na Vitrine de Produtos:
1. 👟 **Escolha seu Tamanho:**
   - Toque no número do seu pé (ex: 39, 40).
   - 🟢 Verde: Tem na loja! Pode pedir.
   - 🔴 Vermelho: Acabou na loja. Escolha outro número.
2. 🚚 **Escolha a Entrega:**
   - ⚡ **Motoboy:** Chega voando na sua casa em até 2 horas.
   - 🏪 **Pegar na Loja:** Você passa no Centro e retira no balcão sem frete!

### B. No Checkout (Pagar no Pix):
1. 📱 **Sem Senhas Chatas:** Digite só o Nome e o WhatsApp. Os avisos chegam direto no seu zap!
2. 🏦 **Pix em 1 Toque:** Toque em `[ 📋 Copiar Chave Pix ]`, abra o aplicativo do seu banco e cole. Aprovou na hora!
3. 🎟️ **Seu Código Secreto:** Você ganha um PIN (ex: `PP-4821`) e um QR Code. É só mostrar na tela do celular para o atendente da loja para pegar sua caixinha.

### C. No Painel do Lojista:
1. 🟢 **Vender / 🔴 Pausar:** Vendeu o último par na loja física? Toque na chavezinha para ficar Vermelha. O site esconde o produto na mesma hora!
2. 🏷️ **Desconto Relâmpago:** Coloque o preço com desconto. Nosso "Escudo de Proteção" não deixa o ERP apagar sua promoção!

---

## 7. Fluxo de Pagamento Presencial / Pagar no Balcão

Para atender clientes que preferem não pagar antecipadamente por canais digitais, a plataforma oferece a modalidade **"Pagar no Balcão ao Retirar"**:
1. **Reserva Sem Fricção:** Cliente seleciona Retirar na Loja e forma de pagamento "Pagar no Balcão".
2. **PIN de Reserva (ex: `PP-4821`):** O MedusaJS v2 reserva o item na tabela `pedidos` com `status: 'reservado_balcao'` e `forma_pagamento: 'presencial_balcao'`.
3. **Comprovante WhatsApp:** O cliente recebe na hora mensagem com endereço da loja e o PIN.
4. **Cobrança Segura em 2 Etapas:**
   - Ao informar o PIN no balcão, o sistema exibe um alerta âmbar: `⚠️ Cobrança Obrigatória: Receber R$ 180,40 no Balcão`.
   - O atendente recebe no dinheiro, Pix da loja ou maquininha e clica em `[ 💵 Confirmar Pagamento & Liberar Calçado ]`.
   - O pedido é transicionado para `pago_e_entregue_no_balcao`.

---

## 8. Sistema de Rastreamento Transparente em Tempo Real (`rastreio.js`)

Consulta descomplicada sem senhas ou cadastros longos:
- **Acesso Direto:** Pelo menu do topo ou link direto `https://processopro.net/?rastreio=PP-4821`.
- **Barra Visual Colorida de 5 Etapas:**
  1. 🟡 *Pedido Recebido / Reservado*
  2. 🟠 *Separando no Balcão da Loja*
  3. 🟢 *Pronto para Retirada no Centro*
  4. 🚚 *Saiu para Entrega (Motoboy a caminho)*
  5. 🏁 *Entregue com Sucesso!*
- **Ações Rápidas:** Botão direto para traçar rota no Waze/Google Maps ou chamar no WhatsApp do lojista.

---

## 9. Sistema de Ligação de Voz Automática (TTS) com Número Fixo Exclusivo

Para garantir 100% de leitura de avisos críticos sem risco de banimento de chips ou dependência exclusiva de mensagens:
- **Telefonia Integrada (`voice-notifier.ts`):** Dispara chamada telefônica automática nos eventos `saiu_entrega` e `pronto_retirada`.
- **Número Fixo Oficial Blindado:** Bina identificada exclusivamente com **(27) 3000-0000** (`+552730000000`).
- **Mensagem Vocal Dinâmica:** *"Olá! Aqui é da plataforma ProcessoPro avisando que seu pedido da Calçados Silva acabou de sair para entrega com o motoboy. Fique atento para receber!"*

---

## 10. Arquitetura Antifraude 100% Blindada em 4 Etapas Visuais

O sistema anula qualquer tentativa de golpe através de 4 barreiras ilustradas:
1. 🛒 **Passo 1: Pedido Rápido sem Senhas:** Checkout sem atrito via WhatsApp sem risco de vazamento de credenciais.
2. 📦 **Passo 2: Separação Expressa no Balcão:** Conferência física e lacre de segurança imediato pela equipe local.
3. 📞 **Passo 3: Ligação Oficial com Bina Única (27) 3000-0000:** Chamada de voz confirmando o despacho para o telefone real do comprador.
4. 🤝 **Passo 4: Aperto de Mão Digital (Validação do PIN Secreto):** O pacote só é liberado mediante digitação ou bipagem do PIN de 4 dígitos gerado no celular do cliente.

---

## 11. Regra Oficial de Redes Sociais da Loja (Instagram & TikTok)

Para garantir foco total na conversão local e eliminar poluição visual na vitrine e nos produtos:
- **Produtos 100% Locais:** Cards de produtos e páginas de detalhes (`/produtos/...`) possuem estritamente funções de compra local (seletor de numeração, saldo no balcão, entrega motoboy e retirada). Nenhum card individual abre redes externas.
- **Exibição Restrita ao Perfil da Loja (`/lojas/:slug`):** Os links oficiais ficam localizados exclusivamente no cabeçalho de informações da loja física parceira:
  * `[ 📸 Ver Instagram da Loja ]` $\rightarrow$ `https://instagram.com/usuario_da_loja`
  * `[ 🎵 Ver TikTok da Loja ]` $\rightarrow$ `https://tiktok.com/@usuario_da_loja`
- **Ajuda Simplificada na Loja:** Balão explicativo orientando clientes: *"Quer ver os provadores e vídeos da loja? Clique no botão do Instagram ou TikTok acima no cabeçalho da loja."*
- **Rodapé Discreto no WhatsApp:** Confirmações de pedidos enviadas ao comprador incluem os links sociais no rodapé da mensagem.
- **Cadastro Simples no Painel (`/app`):** No menu *"Dados da Loja"*, o comerciante cadastra apenas `@instagram` e `@tiktok` e clica em Salvar.

---

## 12. Os 5 Pilares Jurídicos no Brasil & Arquitetura de Conformidade

A plataforma ProcessoPro traduz as leis brasileiras em regras práticas de operação, garantindo validade jurídica e proteção mútua:

### 1. Direito de Arrependimento (Art. 49 do CDC)
O consumidor tem até **7 dias** após o recebimento para desistir da compra realizada de forma digital. O lojista é obrigado a acolher a devolução e estornar o valor integral.

### 2. Emissão Obrigatória de Nota Fiscal (Lei nº 8.137/1990)
Toda venda concluída na plataforma conecta-se diretamente ao ERP do comerciante, devendo ser acompanhada da Nota Fiscal oficial (NFC-e / NF-e) junto ao pacote.

### 3. Lei do E-commerce (Decreto nº 7.962/2013)
Exigência de transparência total: CNPJ, Razão Social, endereço físico detalhado no município, prazos de entrega e canais diretos de atendimento visíveis na página de cada loja física parceira (`/lojas/:slug`).

### 4. Proteção de Dados Pessoais (LGPD - Lei nº 13.709/2018)
Coleta estritamente mínima dos dados do comprador (Nome, WhatsApp e Endereço). É expressamente proibido aos estabelecimentos parceiros a utilização desses dados para disparos de SPAM, publicidade não solicitada ou cessão a terceiros.

### 5. Garantia Legal contra Vícios e Defeitos (Art. 26 do CDC)
Produtos duráveis (calçados, confecções e eletrônicos) possuem garantia legal de **90 dias** contra vícios de fabricação, com suporte e troca no balcão da loja física ou via motoboy.

### 6. Registro de Auditoria no PostgreSQL (Porta 5434)
Ambos os aceites são auditados com carimbo de data/hora e endereço IP:
- **Tabela `pedidos`:** Colunas `aceite_termos_cliente` (BOOLEAN), `aceite_termos_em` (TIMESTAMP), `aceite_ip` (VARCHAR).
- **Tabela `lojas`:** Colunas `termos_aceitos_lojista` (BOOLEAN), `termos_aceitos_em` (TIMESTAMP), `termos_ip` (VARCHAR).

---

## 13. Matriz de Permissões e Trava de Segurança por PIN no Painel (`/app`)

Para garantir a integridade dos dados fiscais e evitar fraudes internas ou erros operacionais na loja física, o catálogo de produtos adota uma matriz rigorosa de permissões:

| Campo do Produto | O Lojista / Atendente Pode Alterar? | Regra de Segurança & Regra do Banco de Dados |
| :--- | :--- | :--- |
| **Nome / Título do Produto** | ❌ **BLOQUEADO** | Protegido contra edições. Espelha 100% a descrição cadastrada na Nota Fiscal do ERP. |
| **Código / SKU** | ❌ **BLOQUEADO** | Identificador único e chave de conciliação fiscal com o banco de dados. |
| **Exibir no Marketplace** | ✅ **LIVRE** (Chave Liga/Desliga) | Alterna o status `trava_status` e `ativo` (true/false) instantaneamente. |
| **Preço Final / Desconto Pix** | 🔒 **REQUER PIN DE SEGURANÇA** | Exige código PIN de 4 dígitos enviado via WhatsApp ao celular cadastrado do titular da loja. |
| **Fotos do Produto** | 🔒 **REQUER PIN** (ou Trava ERP) | Bloqueado se a flag `trava_fotos` estiver ativa para preservar o padrão visual. |

### Tabela de Auditoria de Preços no PostgreSQL (`audit_alteracao_precos`)
Toda alteração de preços autorizada via PIN gera um registro imutável no banco de dados para segurança jurídica do proprietário:
- `id`: Chave primária sequencial.
- `loja_id`: Identificador da loja parceira.
- `produto_id`: Identificador do produto alterado.
- `preco_antigo` e `preco_novo`: Histórico financeiro comparativo em centavos.
- `autorizado_por_telefone`: Número do WhatsApp do titular que recebeu o PIN.
- `pin_utilizado`: Hash/código do PIN de segurança.
- `ip_origem`: Endereço IP do dispositivo que executou o comando.
- `criado_em`: Carimbo de data e hora do evento (`NOW()`).

---

## 14. Selo de Atualização Fiscal em Tempo Real & Timeout Preventivo de ERP (60 Minutos)

### 1. Selo de Sincronização Fiscal na Vitrine
Nas páginas de produto (`/produtos/:handle`) e no modal de Pré-Visualização Rápida (*Quick View*), é exibido em destaque o selo:
- `🟢 ESTOQUE & PREÇO SINCRONIZADOS VIA ERP`
- *Última atualização recebida do caixa da loja: Hoje às HH:MM*
- *Vínculo direto com a Nota Fiscal e Sistema de Gestão do Comerciante*
- *Garantia legal de 90 dias (Art. 26 do CDC)*

### 2. Regra de Desligamento Preventivo da Vitrine por Timeout (60 Minutos)
Medida crucial para evitar o **overselling** (vender pelo site um sapato que já foi vendido no balcão presencial durante uma queda de luz, corte de internet ou computador do caixa desligado):
1. **Heartbeat Contínuo:** A cada envio de dados do ERP ou ping de comunicação, o banco atualiza `sincronizado_em = NOW()`.
2. **Janela Máxima de Tolerância (60 Minutos):** Se a loja física ficar mais de 60 minutos sem emitir sinal de vida, a vitrine daquela loja específica é automaticamente ocultada do marketplace.
3. **Visão do Cliente:** Ao acessar a página da loja em timeout (`/lojas/:slug`), o cliente visualiza uma mensagem amigável de pausa técnica:
   > 🏪 **LOJA TEMPORARIAMENTE INDISPONÍVEL**  
   > *A Calçados Silva & Cia está passando por uma manutenção temporária em seu sistema de caixa local (energia ou conexão).*  
   > 💡 *Para sua segurança e garantia de estoque real, os produtos voltarão ao ar assim que a conexão do estabelecimento for restabelecida.*
4. **Visão do Lojista no Painel:** Alerta preventivo com botão `[ 🔄 Reconectar e Sincronizar ERP Agora ]`.
5. **Restabelecimento Automático:** Assim que a energia ou internet retorna e o ERP transmite o primeiro pacote de dados, os produtos voltam ao ar no mesmo segundo com estoque real e corrigido.

---

## 15. Desativação Automática por Estoque Zero e Bloqueio de Numeração Esgotada

A plataforma implementa uma camada de proteção contra ruptura de estoque que conecta a bipagem física do caixa à vitrine digital:

```
 [ Venda no Balcão Físico ou no Site ]
                  │
                  ▼
 [ ERP registra saldo = 0 unidades ]
                  │
                  ▼
 [ Sincronização via API / Webhook em tempo real ]
                  │
                  ▼
 [ Tabela produtos atualiza estoque_balcao = 0 ]
                  │
                  ▼
 [ Item Ocultado Instantaneamente da Vitrine do Marketplace ]
```

### 1. Soma Zero = Produto Escondido
No momento em que o caixa da loja física bipa o último par e o saldo zera, o ERP transmite a baixa e o produto é imediatamente ocultado das listagens e buscas do marketplace.
- **View Pública do PostgreSQL (`v_produtos_vitrine`):**
  ```sql
  CREATE OR REPLACE VIEW v_produtos_vitrine AS
  SELECT 
      p.*,
      l.nome_fantasia AS loja_nome,
      l.cnpj AS loja_cnpj,
      l.whatsapp AS loja_whatsapp,
      (p.sincronizado_em >= NOW() - INTERVAL '60 minutes') AS erp_online
  FROM produtos p
  JOIN lojas l ON l.id = p.loja_id
  WHERE 
      p.ativo = TRUE 
      AND l.ativa = TRUE
      AND p.estoque_balcao > 0
      AND (p.sincronizado_em >= NOW() - INTERVAL '60 minutes' OR p.trava_status = TRUE);
  ```

### 2. Bloqueio no Seletor de Tamanhos
Quando o produto possui grade de numerações (ex: 37, 38, 39, 40, 41, 42) e apenas uma numeração específica acaba no estoque físico:
- A opção correspondente (ex: Tam 42) é renderizada em tom vermelho com riscado (`line-through`) e badge `Esgotado`.
- O elemento recebe o atributo HTML `disabled`, impedindo qualquer tentativa de clique ou seleção.
- Mantém visíveis e selecionáveis exclusivamente os tamanhos com saldo real no balcão da loja.

### 3. Retorno Automático por Reposição
Assim que a loja física dá entrada de nota fiscal de fornecedor ou cadastra novas caixas no sistema do estoque, o produto e a numeração retornam ao ar de forma 100% autônoma, sem necessidade de reconfiguração manual.

