# Simples Agenda Download

> Automate downloads of appointment schedules from Simples Agenda. Use this skill whenever a user needs to download, export, or extract appointment data from Simples Agenda with specific date ranges, professionals, services, or clients. The skill handles authentication, applies filters to the native agendamento.php export function, and saves the Excel file automatically to the user's Downloads folder. Includes date validation, error handling, and guardrails to ensure data integrity.

- Skill: `projetvs-pdi/simples-agenda-download` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add projetvs-pdi/simples-agenda-download`
- Raw SKILL.md: https://api.skillmd.com/api/skills/projetvs-pdi/simples-agenda-download/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: projetvs-pdi (https://skillmd.com/u/projetvs-pdi)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/projetvs-pdi/simples-agenda-download

---


# Simples Agenda Download Automation Skill

## Overview

This skill automates the download of appointment schedules from **Simples Agenda**, a Brazilian scheduling and financial management system. Instead of manually logging in, navigating to filters, and exporting the file, users can simply request the skill to download appointments for a specific period with optional filters.

**Key point:** This is a **wrapper/integrator** skill — it does NOT recreate the download functionality. It calls the same endpoints that the `agendamento.php` screen calls (`crud.php` com `acao=exporta_agendamentos`) and automates the process.

### What This Skill Does

1. **Authenticates** with Simples Agenda (login/password)
2. **Applies filters** to the native export function:
   - Mandatory: Date range (dd/mm/yyyy format)
   - Optional: Professional(s), Service(s), Client(s)
3. **Downloads** the Excel file generated by Simples Agenda
4. **Saves** to the user's Downloads folder with timestamp to avoid overwrites
5. **Validates** the downloaded file and confirms success to the user

### Flow

```
User defines parameters (periodo + filtros opcionais)
    ↓
GET  autenticacao_usuario.php      -> cookie PHPSESSID
    ↓
POST crud_autenticacao.php         -> acao=autentica_usuario
    ↓                                 (UsuarioSA / SenhaSA)
POST crud.php                      -> acao=exporta_agendamentos
    ↓                                 <nome_excel>caminho</nome_excel>
GET  <nome_excel>                  -> .xls binario
    ↓
Skill valida magic bytes & salva em Downloads/
    ↓
Sincroniza no MySQL e gera planilha ordenada (import-db-agenda)
    ↓
Envia a planilha por email (email-sender)
    ↓
User receives confirmation message
```

---

## How to Use

When the user asks to download or export appointment data from Simples Agenda, follow these steps:

### 1. Gather Parameters

Collect from the user:

**Required:**
- **Email** (Simples Agenda login) — e-mail de acesso ao sistema

**Optional (com defaults automáticos):**
- **Start Date** (Data Início) — in dd/mm/yyyy format
  - Example: "01/01/2024"
  - **DEFAULT se omitido:** hoje - 7 dias
  - Validation: Reject other formats (mm/dd/yyyy, yyyy-mm-dd, text, etc.)
  
- **End Date** (Data Fim) — in dd/mm/yyyy format
  - Example: "31/01/2024"
  - **DEFAULT se omitido:** hoje - 1 dia
  - Validation: Must be >= Start Date

**Outros opcionais:**
- **Professionals** — select one or more (IDs or names, depending on what Simples Agenda returns)
- **Services** — select one or more
- **Clients** — select one or more
- **EnviarPara** (Melhoria #3) — email(s) **de destino** (destinatários) da planilha ordenada final, separados por vírgula. O remetente NÃO é este parâmetro: é a conta configurada na skill `email-sender` para o serviço `simples-agenda` (ver seção 8). Todo destinatário precisa estar na allowlist daquele serviço. Default: `amazonasterapiafisio@gmail.com` (não é preciso perguntar ao usuário se ele não mencionar email).
- **NaoEnviarEmail** — se o usuário pedir explicitamente para não enviar email, pule o envio (ver seção 8).

**Comportamento com defaults:**

Se o usuário não informar `-DataIni` e `-DataFim`, o script usa automaticamente:
- DataIni = hoje - 7 dias
- DataFim = hoje - 1 dia

Isso permite executar sem datas: `.\baixar_agenda.ps1 -Email seu@email.com` busca os últimos 7 dias.

### 2. Validate Inputs

Before proceeding:

**Date Format Validation:**
- ✓ Date format is strictly dd/mm/yyyy
- ✗ Reject formats like: 01-01-2024, 2024/01/01, 1/1/2024, "January 2024"
- ✗ Reject invalid dates like: 01/13/2024 (no month 13), 32/01/2024 (no day 32)

**Date Range Validation:**
- ✗ Reject: Data Início > Hoje (não pode pedir data futura)
  - Example: "Hoje: 02/01/2024, Data Início: 03/01/2024" → REJEITAR
- ✗ Reject: Data Fim > Hoje (não pode pedir data futura)
  - Example: "Hoje: 02/01/2024, Data Fim: 31/01/2024" → REJEITAR
- ✓ Accept: Data Início ≤ Hoje (pode ser hoje ou passado)
  - Example: "Hoje: 02/01/2024, Data Início: 02/01/2024" → ACEITAR
  - Example: "Hoje: 02/01/2024, Data Início: 01/01/2024" → ACEITAR
- ✓ Accept: Data Fim ≤ Hoje (pode ser hoje ou passado)
  - Example: "Hoje: 02/01/2024, Data Fim: 02/01/2024" → ACEITAR
  - Example: "Hoje: 02/01/2024, Data Fim: 25/12/2023" → ACEITAR
- ✗ Reject: Data Fim < Data Início (range invertido)
  - Example: "Data Início: 31/01/2024, Data Fim: 01/01/2024" → REJEITAR
- ✓ Accept: Data Fim ≥ Data Início (mesmo dia é válido)
  - Example: "Data Início: 02/01/2024, Data Fim: 02/01/2024" → ACEITAR

If validation fails, inform the user with the exact issue: "Invalid format. Use dd/mm/yyyy (example: 01/01/2024)" or "Data Início não pode ser no futuro" or "Data Fim deve ser >= Data Início"

### 3. Authenticate (Melhoria #1 — implementada)

Credenciais NAO sao geridas por esta skill diretamente: ela chama a skill
separada **`credential-manager`** (`../credential-manager`), que guarda a
senha de forma criptografada no cofre do SO (DPAPI no Windows via
`credential_manager.ps1`).

1. **1a execucao**: usuario informa email + senha. A senha e usada E salva
   automaticamente via `credential-manager` — nao ha flag extra para lembrar.
2. **Proximas execucoes**: basta informar o email (+ periodo). A senha e
   carregada sozinha do `credential-manager`; o usuario nao digita nada.
3. **Logout**: `-Logout` remove a senha salva para aquele email.
4. Se a senha carregada estiver errada (credenciais mudaram no site), a
   autenticacao falha com `AUTH_FAILED` normalmente — o usuario deve rodar de
   novo informando a senha nova, que substitui a antiga no cofre.

Chamada interna: `baixar_agenda.ps1` invoca
`..\..\credential-manager\scripts\credential_manager.ps1` diretamente
(splatting via hashtable).

Validado (testes reais nesta maquina, 01/09/2026): salvar, carregar
automaticamente, isolar por `service_name`, e logout — todos via
`credential_manager.ps1` (ver `credential-manager/SKILL.md`).

### 4. Login, Export, Download

**Step 5a: Login — HTTP puro, sem navegador**

Sao duas chamadas:

```
GET  https://www.simplesagenda.com.br/autenticacao_usuario.php
     -> so para obter o cookie PHPSESSID inicial

POST https://www.simplesagenda.com.br/crud_autenticacao.php
  acao=autentica_usuario
  login=<email>          <-- e "login", NAO "email"
  senha=<senha>
  conectado=1
  captcha_resposta=      (vazio quando nao ha captcha)
```

Resposta XML:
```xml
<data>
  <endereco>agendamento.php</endereco>
  <mostraToast>N</mostraToast>
  <houve_erro>N</houve_erro>
</data>
```
`houve_erro == "N"` = sucesso; so entao os cookies `UsuarioSA` e `SenhaSA`
sao definidos. Em falha vem `<mensagem>` (com HTML embutido, limpe antes de
exibir) e, as vezes, `<requer_captcha>S</requer_captcha>` +
`<captcha_pergunta>`.

> **NAO faca POST de login em `autenticacao_usuario.php`.** Aquele endpoint
> responde HTTP 200, define apenas `PHPSESSID` e **nao autentica**. Era por
> causa desse engano que a versao antiga da skill precisava de Selenium/Chrome.
> O endpoint correto esta declarado em `assets/pages/scripts/login.js`
> (`crudPadrao: "crud_autenticacao.php"`, `acao: "autentica_usuario"`).

> Atencao: `/index.php` redireciona para `/site/index.php`, que e a pagina de
> marketing com um formulario de *cadastro* ("Experimente Gratis") — nao e login.
> A pagina de login e `autenticacao_usuario.php`.

> O campo `captcha_resposta` fica oculto (`display:none`) em condicoes normais,
> mas o servidor pode exigi-lo apos erros de senha. Se `requer_captcha == "S"`,
> ABORTAR e pedir login manual — nunca tentar resolver.

**Step 5b: Export Request (POST)**
```
POST https://www.simplesagenda.com.br/crud.php

  acao=exporta_agendamentos    <-- acao correta para gerar o Excel
  dataIni=04/08/2026           (dd/mm/yyyy)
  dataFim=31/08/2026           (dd/mm/yyyy)
  cod_usuario_array=           (opcional: IDs de profissionais, separados por virgula)
  cod_cliente=                 (opcional)
  cod_produto=                 (opcional: ID do servico)
```

Resposta: XML contendo o caminho real do arquivo:
```xml
<nome_excel>excel/excel71400/Agendamentos_DDMMYYYYHHMMSS.xls</nome_excel>
```

> `acao=filtraResumido` apenas renderiza a tabela na tela e NAO gera Excel.
> Nunca adivinhe o nome do arquivo — leia sempre `<nome_excel>` da resposta.

**Step 5c: Download (GET)**
```
GET https://www.simplesagenda.com.br/<nome_excel>
```
Retorna: arquivo .xls binario (OLE2, magic `D0CF11E0A1B11AE1`).

### 5. Validate and Save the File

When Simples Agenda returns the .xls file:

1. **Validate file integrity:**
   - Check file extension: `.xls`
   - Verify magic bytes (should start with `D0CF11E0` for .xls format)
   - File size > 0 bytes

2. **Naming:**
   - Preserve original filename from Simples Agenda + add timestamp
   - Pattern: `agenda_[original]_YYYYMMDD_HHMMSS.xls`
   - Example: `agenda_2024_20240115_143025.xls`

3. **Handle conflicts:**
   - If file already exists, append numeric suffix
   - Example: `agenda_2024_20240115_143025_1.xls`

4. **Save location:**
   - Windows: `C:\Users\[username]\Downloads\`
   - macOS: `/Users/[username]/Downloads/`
   - Linux: `/home/[username]/Downloads/`

### 6. Confirm to User

**On success:**
```
✓ "Arquivo 'agenda_2024_20240115_143025.xls' baixado com sucesso em C:\Users\[username]\Downloads"
```

**On error:**
- "Falha de conexão. Verifique sua internet e tente novamente."
- "Credenciais inválidas. Verifique login e senha."
- "Nenhum agendamento encontrado para: 01/01/2024 até 31/01/2024"
- "Erro ao processar resposta do servidor. Contate suporte."

### 7. Sync com Banco e Planilha Ordenada (Melhoria #2 — delegada à skill `import-db-agenda`)

Depois do download do `.xls` original, `baixar_agenda.ps1` chama a skill
**[`import-db-agenda`](../import-db-agenda)** para:

1. Validar (`init-schema`) que a tabela `sbx990` e as referências (empresa/filial)
   existem no MySQL, criando a UNIQUE KEY de dedup se ainda não existir
2. Sincronizar os agendamentos baixados nessa tabela (`sync`)
3. Gerar a **planilha ordenada final** (`.xlsx`) a partir do banco, na ordem
   pedida em `-SortBy` (`cliente+data` por padrão)

O `.xls` original do Simples Agenda é apagado depois que os dados estão no
banco e a planilha ordenada foi gerada com sucesso — a planilha ordenada é o
entregável, não o `.xls` bruto.

`-NoSyncToDb` pula só a sincronização (passo 2); a exportação ordenada
(passo 3) sempre acontece a partir do que já estiver no banco. Sem a skill
`import-db-agenda` disponível, o `.xls` original é mantido e a skill encerra
(a planilha ordenada não pode ser gerada sem ela).

**Destino (desde 07/09/2026):** tabela `sbx990` no banco `4clinics`
(`localhost:3306`) — sistema externo, não gerenciado por esta skill. A tabela
tem colunas com nomes próprios (`dataAgenda`, `dataAcao`, `executadoPor`) e
campos obrigatórios sem equivalente no Simples Agenda (`empresaId`, `filialId`,
`filialOrigemId`), preenchidos com valor fixo. Ver
[`import-db-agenda/manifest.json`](../import-db-agenda/manifest.json) →
`schema.column_mapping` e `schema.fixed_identifiers` para o mapeamento completo.

Parâmetros de conexão: `-DbHost` (`127.0.0.1`), `-DbPort` (`3306`), `-DbUser`
(`root`), `-Database` (`4clinics`), `-DbPassword` (opcional — carregada do
`credential-manager` se omitida), `-EmpresaId` (`001`), `-FilialId` (`01`),
`-FilialOrigemId` (`01`).

### 8. Send Email (Melhoria #3 — delegada à skill `email-sender`)

O Passo 9 do `baixar_agenda.ps1` envia a planilha ordenada por email chamando a
skill **[`email-sender`](../email-sender/SKILL.md)**. O script faz isso sozinho:
não há sinalização para o orquestrador nem passo manual.

```
baixar_agenda.ps1  ──chama──>  email-sender/scripts/send_email.ps1
                                   -Service 'simples-agenda'
                                   -To <EnviarPara>
                                   -Subject "Agenda Ordenada: <periodo>"
                                   -Body  <periodo, ordenacao, arquivo, timestamp>
                                   -Attachment <planilha .xlsx>
```

Toda a segurança vive na `email-sender`: SMTP+TLS obrigatório, allowlist de
destinatários, credencial em DPAPI sem texto plano. Esta skill não manipula
senha de email nem abre conexão SMTP.

#### Histórico: por que não é Gmail MCP

O desenho anterior emitia linhas `[EMAIL]` para que o Claude Code enviasse via
conector Gmail MCP. **Foi abandonado por limite de tamanho no anexo.** Testes em
05/09/2026 mostraram:

| Anexo | Base64 | Resultado |
|-------|--------|-----------|
| nenhum | — | chegou |
| 5 bytes | 8 chars | chegou |
| planilha real de 1 dia (11,9 KB) | 15.880 chars | falhou 4x |

Uma planilha real sempre passa desse tamanho, e períodos maiores só pioram.
O erro (`Tool execution failed`) não trazia detalhe, então não foi possível
atribuir o limite ao servidor do Google, ao transporte MCP ou a timeout — mas
o efeito prático era o mesmo: o anexo nunca chegava.

#### Remetente x destinatário

- `-EnviarPara` define o **destinatário**.
- O **remetente** é a conta configurada no setup da `email-sender` para o serviço
  `simples-agenda`. Trocar o remetente = rodar o setup daquela skill de novo.

#### Configuração (uma única vez)

Enquanto a `email-sender` não estiver configurada para o serviço
`simples-agenda`, a planilha continua sendo gerada normalmente e o script apenas
avisa como configurar (exit 0 — não é falha).

```bash
powershell -ExecutionPolicy Bypass -File .claude/skills/email-sender/scripts/send_email.ps1 -Action setup -Service simples-agenda
```

**Allowlist:** o destinatário precisa estar autorizado no serviço
`simples-agenda`, senão o envio é bloqueado. Isso é proposital — a planilha
carrega dado pessoal de pacientes, e destinatário errado é incidente de
vazamento. Para autorizar:

```bash
powershell -ExecutionPolicy Bypass -File .claude/skills/email-sender/scripts/send_email.ps1 -Action add-recipient -Service simples-agenda -Recipient alguem@dominio.com
```

#### Tratamento de falha (não bloqueante)

A planilha já foi gerada quando o envio acontece. Qualquer falha de envio vira
`[AVISO]` com instrução de correção, a planilha é preservada em `Downloads` e a
skill encerra com **exit 0**. Nunca reverta nem apague a planilha por falha de
email.

| Exit da `email-sender` | O que o script informa |
|------------------------|------------------------|
| 0 | Enviado (a própria `email-sender` imprime o `[OK]`) |
| 2 | Não configurado — mostra o comando de setup |
| 3 | Destinatário fora da allowlist — mostra o comando de autorização |
| 6 | Senha de app recusada — orienta gerar outra |
| outros | Falha genérica, com o código |

Se `-NaoEnviarEmail` for passado, o passo inteiro é pulado.

**Default de destinatário:** sem `-EnviarPara`, o script usa
`amazonasterapiafisio@gmail.com` (ver seção 1).

---

## Error Scenarios

| Scenario | User Action | Skill Action | Message |
|----------|-------------|--------------|---------|
| **Connection failure** | None (server/network issue) | Abort after 30s timeout | "Falha de conexão. Verifique sua internet e tente novamente." |
| **Bad credentials** | Provided wrong login/password | Don't save, request retry | "Credenciais inválidas. Verifique login e senha." |
| **Session expired** | Token/session no longer valid | Auto re-authenticate silently or request credentials | "Sessão expirada. Fazendo login novamente..." |
| **No appointments** | Valid filters, but no results | Show message, allow retry with different filters | "Nenhum agendamento encontrado para: 01/01/2024 até 31/01/2024. Tente outro período." |
| **Invalid date format** | User provides "01-01-2024" or "2024/01/01" | Reject immediately | "Formato de data inválido. Use dd/mm/yyyy (exemplo: 01/01/2024)" |
| **Start date in future** | User provides: Today 02/01/2024, Start 03/01/2024 | Reject before calling server | "Data Início não pode ser no futuro" |
| **End date in future** | User provides: Today 02/01/2024, End 31/01/2024 | Reject before calling server | "Data Fim não pode ser no futuro" |
| **End date < start date** | User provides: Start 31/01/2024, End 01/01/2024 | Reject before calling server | "Data Fim deve ser maior ou igual a Data Início" |
| **Disk full / permission denied** | Not user's fault | Inform the error | "Erro ao salvar em Downloads: [motivo]. Verifique permissões." |
| **Corrupted file** | Download incomplete / truncated | Delete partial file, retry or abort | "Download interrompido. Tente novamente." |
| **Unexpected server response** | Simples Agenda changed format | Log error, notify user | "Erro ao processar resposta do servidor. Contate suporte." |
| **Rate limiting (HTTP 429)** | Varias execucoes/logins em sequencia | Abortar sem repetir; nao insistir | "Muitas requisicoes em sequencia (HTTP 429). Aguarde alguns minutos e tente de novo." |
| **CAPTCHA exigido** | Servidor respondeu `requer_captcha=S` | ABORTAR. Nunca resolver captcha | "O site esta pedindo CAPTCHA no login. Faca login manual no navegador e tente depois." |
| **Falha na sincronizacao/exportacao do BD** | MySQL indisponivel ou skill import-db-agenda ausente | Preserva o .xls original, exit 7 | "Falha ao preparar/sincronizar o banco. O .xls original foi mantido em: [caminho]" |
| **email-sender nao configurada** | Setup ainda nao feito para o service 'simples-agenda' | Avisa e segue (exit 0). Planilha preservada | "email-sender ainda nao configurado... Configure uma unica vez: -Action setup -Service simples-agenda" |
| **Destinatario fora da allowlist** | Endereco nao autorizado no service | BLOQUEIA o envio inteiro. Planilha preservada | "Destinatario fora da allowlist do servico 'simples-agenda'. Nada foi enviado. Para autorizar: -Action add-recipient..." |
| **Senha de app revogada** | 2FA desativado ou senha revogada no Google | Avisa e segue (exit 0). Planilha preservada | "Autenticacao SMTP recusada... Gere uma nova senha de app e rode o setup novamente." |
| **Falha generica no envio** | Rede, servidor SMTP indisponivel | Avisa e segue (exit 0). NUNCA reverter nem apagar a planilha | "Falha ao enviar o email (exit N). Planilha preservada em: [caminho]" |

---

## Guardrails (Prevent Common Mistakes)

### 1. Date Format Validation
```
✗ Reject:  01/13/2024 (month out of range)
✗ Reject:  2024-01-01 (ISO format)
✗ Reject:  1/1/2024    (no zero-padding)
✗ Reject:  janeiro de 2024 (text format)
✓ Accept:  01/01/2024 (dd/mm/yyyy)
✓ Accept:  31/12/2024 (dd/mm/yyyy)
```

### 2. Date Range Validation
```
✗ Reject:  Start 31/01/2024, End 01/01/2024 (reversed / End < Start)
✗ Reject:  Today 02/01/2024, Start 03/01/2024 (Start > Today / future date)
✗ Reject:  Today 02/01/2024, Start 01/01/2024, End 31/01/2024 (End > Today / future date)
✓ Accept:  Today 02/01/2024, Start 01/01/2024, End 02/01/2024 (End <= Today)
✓ Accept:  Today 02/01/2024, Start 02/01/2024, End 02/01/2024 (today is OK)
✓ Accept:  Today 02/01/2024, Start 01/01/2024, End 25/12/2023 (all in past)
```

### 3. File Type Validation
```
✗ Reject:  Attempting to parse as CSV
✗ Reject:  Assuming text/plain format
✓ Accept:  Binary .xls file from Simples Agenda
```

### 4. Session Management
```
✓ Reuse:   Valid token/session from previous call
✗ Don't:   Ask for credentials if session is still valid
✓ Ask:     Only when token is expired or invalid
```

### 5. Data Cleanup
```
✓ Remove:  Trailing blank rows
✓ Remove:  Extra spaces in column headers
✓ Keep:    Original data integrity
```

---

## Mapped Parameters & Confirmed Behavior

✅ **ALL PARAMETERS CONFIRMED** (execucao real em 31/08/2026)

### 1. Parameter Mapping ✅ (verificado em execucao real)
- [x] `crud.php`:
  - Acao de exportacao: `acao=exporta_agendamentos`
  - Data inicial: `dataIni` (dd/mm/yyyy)
  - Data final: `dataFim` (dd/mm/yyyy)
  - Profissionais: `cod_usuario_array` (IDs separados por virgula, ou vazio)
  - Servico: `cod_produto`
  - Cliente: `cod_cliente`
- [x] A resposta traz o caminho do arquivo em `<nome_excel>`

### 2. Authentication Mechanism ✅ (corrigido em 31/08/2026)
- [x] Endpoint real: `crud_autenticacao.php` (POST), `acao=autentica_usuario`
- [x] Campos: `login` (email), `senha`, `conectado=1`, `captcha_resposta`
- [x] Resposta XML: `<houve_erro>`, `<endereco>`, `<mensagem>`,
      `<requer_captcha>`, `<captcha_pergunta>`
- [x] Cookies obtidos: `PHPSESSID` (na pagina), `UsuarioSA` + `SenhaSA` (no login)
- [x] **Selenium removido** — HTTP puro (`requests` ou `Invoke-WebRequest`) basta
- [x] `autenticacao_usuario.php` NAO autentica por POST: responde 200, define so
      `PHPSESSID`. Esse era o motivo real da dependencia de navegador.
- [x] Campo `captcha_resposta` fica oculto; se `requer_captcha=S`, abortar

### 3. File Response Details ✅
- [x] Caminho: lido de `<nome_excel>` (ex.: `excel/excel71400/Agendamentos_31082026095116.xls`)
- [x] Formato: OLE2 / BIFF (`D0CF11E0A1B11AE1`)
- [x] Planilha `AGENDAMENTOS`, 10 colunas:
      Data, Cliente, Telefone, Email, Servico, Observacao, Profissional,
      Status, Data Acao, Executado por
- [x] Tamanho observado: ~152 KB para 786 linhas (04/08/2026–31/08/2026)
- [x] Nota: `xlrd` exige `ignore_workbook_corruption=True` para abrir o arquivo

### 4. Runtime / Ambiente ✅
- [x] `scripts/baixar_agenda.ps1` cobre o fluxo inteiro com PowerShell 5.1,
      sem dependencias externas

### 5. Rate Limiting & SLA ✅ (parcial)
- [x] Rate limiting CONFIRMADO: apos varias requisicoes/logins em poucos
      segundos o servidor responde **HTTP 429 Too Many Requests**
- [x] Tratamento: abortar com mensagem clara, sem retry automatico
      (codigo `RATE_LIMITED` / exit 6)
- [ ] Janela exata do limite: nao medida
- [ ] SLA: Not documented
- [x] Timeouts: 30s conexao/login, 120s exportacao, 180s download

---

## Triggering Phrases

This skill should activate when users mention:
- "download agenda from Simples Agenda"
- "export appointments"
- "baixar agenda" (Portuguese)
- "extract appointment data"
- "get appointments for [date range]"
- "download Simples Agenda"
- "exportar agendamentos"
- "baixe minha agenda" (português, sem datas — usa defaults)
- When user mentions Simples Agenda or appointments (com ou sem datas explícitas)

---

## Limitations & Out of Scope

- ✗ Cannot modify, delete, or create appointments in Simples Agenda
- ✗ So os endpoints do fluxo de exportacao: `autenticacao_usuario.php` (GET),
  `crud_autenticacao.php` (login), `crud.php` (`exporta_agendamentos`) e o
  caminho retornado em `<nome_excel>`
- ✗ Cannot access other Simples Agenda features (financial, invoicing, etc.)
- ✗ Must not block system on errors — all failures graceful and non-blocking
- ✗ Navegador/Selenium nao e mais usado nem necessario — o fluxo e HTTP puro
- ✗ CAPTCHA nunca e resolvido automaticamente: abortar e pedir login manual
- ✗ Nao repetir chamadas apos HTTP 429 — aguardar

---

## Permissions Required

- ✓ Network access to `https://www.simplesagenda.com.br`
- ✓ Credential storage: OS Credential Manager (Windows) / Keychain (macOS) / Secret Manager (Linux)
- ✓ File system write access to Downloads folder
- ✓ No arbitrary file creation outside of Downloads

---

## Testing Strategy

### Test Cases to Validate

1. **Happy path:** Valid date range, no filters → Download succeeds
2. **With filters:** Date range + specific professional → Download with filtered results
3. **Date validation:** Reject invalid formats (01-01-2024, 2024-01-01, etc.)
4. **Date range:** Reject End Date < Start Date
5. **No results:** Valid filters but no appointments → Clear message
6. **Connection error:** Timeout after 30s → Graceful error message
7. **Authentication retry:** Expired session → Re-authenticate and retry
8. **File handling:** Multiple downloads → Timestamps prevent overwrites
9. **Large volume:** Download 1 year of appointments → Performance acceptable

---

## Implementation Status

✅ **IMPLEMENTATION COMPLETE — validada em execucao real (31/08/2026)**

### Scripts
- [baixar_agenda.ps1](scripts/baixar_agenda.ps1) — fluxo completo: login,
  export, download, sync BD, planilha ordenada, email
- [README.md](scripts/README.md) — documentacao de uso

### Contrato de saida

Via **exit codes**: 0 OK, 1 AUTH_FAILED, 2 NO_RESULTS, 3 CORRUPTED_FILE,
4 INVALID_INPUT, 5 CONNECTION_ERROR, 6 RATE_LIMITED, 7 falha na sincronizacao/
exportacao do banco (skill `import-db-agenda`).

### Resolvido nesta versao
- ✅ Endpoint de login corrigido (`crud_autenticacao.php`)
- ✅ Selenium/Chrome eliminado
- ✅ HTTP 429 detectado e reportado
- ✅ Datas de calendario invalidas (31/02) agora rejeitadas
- ✅ Nome do arquivo lido de `<nome_excel>` (nunca adivinhado)
- ✅ Validacao de magic bytes com remocao do arquivo corrompido
- ✅ Erros viram excecao/exit code — nada de `None` silencioso
- ✅ Senha removida dos arquivos de documentacao
- ✅ Saida em ASCII (emoji quebrava no console cp1252 do Windows)

### Next Steps
1. **Credential Storage**: Windows Credential Manager / Keychain
2. **Retry**: backoff exponencial no 429
3. **Logging**: log estruturado para depuracao
4. **Testing**: testes automatizados dos caminhos de erro
5. **Monitoring**: vigiar mudancas no Simples Agenda (login.js e o canario)

### Known Limitations
- Sem cache de credenciais (pede login a cada execucao)
- Sem retry automatico em 429 ou falha transitoria
- Janela exata do rate limiting desconhecida
- Somente entrada manual de credenciais (sem OAuth)
- O caminho `NO_RESULTS` esta implementado mas **nao foi exercitado contra o
  servidor**: a tentativa de testa-lo com um periodo vazio esbarrou no
  rate limiting (HTTP 429)

The skill is designed to be robust against future changes to Simples Agenda — if they update their system, the skill will fail gracefully with clear error messages rather than silently producing incorrect results.

