# Plano de Implementação: pack-mcp-google-chat-notification

## Visão Geral

Implementação incremental do MCP server para envio de notificações ao Google Chat via Webhooks. O plano segue a ordem: estrutura do projeto → módulo de erros → client HTTP → tools MCP → integração final. Cada etapa constrói sobre a anterior, garantindo que não haja código órfão.

## Tarefas

- [x] 1. Configurar estrutura do projeto e dependências
  - Criar `pyproject.toml` com hatchling, entry point `pack-mcp-google-chat-notification` apontando para `pack_mcp_google_chat_notification.server:main`, dependências `httpx>=0.27.0`, `mcp>=1.0.0`, Python `>=3.10`
  - Criar `src/pack_mcp_google_chat_notification/__init__.py` com `__version__ = "0.1.0"`
  - Criar estrutura de diretórios: `src/pack_mcp_google_chat_notification/` e `tests/`
  - Criar `tests/__init__.py` e `tests/conftest.py` com fixtures base (mock de env vars, reset do singleton)
  - Adicionar `hypothesis` e `pytest` como dependências de desenvolvimento
  - _Requisitos: 10.1, 10.2, 10.4, 10.5_

- [x] 2. Implementar módulo de erros (`errors.py`)
  - [x] 2.1 Implementar `sanitize_url`
    - Criar `src/pack_mcp_google_chat_notification/errors.py`
    - Implementar `sanitize_url(url: str) -> str` que substitui valores de `key` e `token` por `***` usando `urllib.parse`
    - _Requisitos: 7.1, 7.2_

  - [x] 2.2 Escrever teste de propriedade para sanitização de URL
    - Criar `tests/strategies.py` com estratégia `webhook_urls_with_tokens()`
    - Criar `tests/test_errors.py`
    - **Propriedade 2: Sanitização de URLs remove tokens sensíveis**
    - **Valida: Requisitos 7.1, 7.2**

  - [x] 2.3 Implementar decorator `handle_error`
    - Implementar `handle_error(func)` que converte `ValueError` → `McpError` com mensagem original, propaga `McpError` sem alteração, e converte outras exceções em `McpError` com mensagem genérica
    - _Requisitos: 6.1, 6.2, 6.3_

  - [x] 2.4 Escrever teste de propriedade para conversão de exceções
    - **Propriedade 8: Conversão de exceções pelo decorator handle_error**
    - **Valida: Requisitos 6.1, 6.3**

- [x] 3. Checkpoint - Verificar módulo de erros
  - Garantir que todos os testes passam, perguntar ao usuário se houver dúvidas.

- [x] 4. Implementar client HTTP (`client.py`)
  - [x] 4.1 Criar classe `GoogleChatClient` com singleton e métodos base
    - Criar `src/pack_mcp_google_chat_notification/client.py`
    - Implementar `GoogleChatClient` com `_instance`, `get_instance()`, `reset()`, `DEFAULT_TIMEOUT = 10.0`
    - Implementar `resolve_webhook_url(webhook_url: str | None) -> str` com fallback para env var
    - Implementar `validate_webhook_url(url: str)` que valida prefixo `https://chat.googleapis.com/`
    - Implementar `get_client()` como atalho para `get_instance()`
    - _Requisitos: 9.1, 9.2, 9.3, 4.1, 4.2, 4.3, 1.2, 8.1_

  - [x] 4.2 Escrever teste de propriedade para identidade do singleton
    - **Propriedade 7: Identidade do singleton**
    - **Valida: Requisitos 9.1, 9.2**

  - [x] 4.3 Escrever teste de propriedade para validação de webhook URL
    - Adicionar estratégias `valid_webhook_urls()` e `invalid_webhook_urls()` em `tests/strategies.py`
    - **Propriedade 1: Validação de Webhook URL por prefixo**
    - **Valida: Requisitos 4.1, 4.2**

  - [x] 4.4 Escrever teste de propriedade para fallback de webhook URL
    - **Propriedade 9: Fallback de webhook URL para variável de ambiente**
    - **Valida: Requisitos 1.2, 8.1**

  - [x] 4.5 Implementar funções de construção de payload
    - Implementar `build_text_payload(text: str) -> dict`
    - Implementar `build_card_payload(title: str, sections: list[dict], subtitle: str | None = None) -> dict` com geração de `cardId` via `uuid4`
    - Implementar `parse_card_payload(payload: dict) -> tuple[str, list[dict], str | None]`
    - _Requisitos: 11.1, 11.2, 11.3_

  - [x] 4.6 Escrever teste de propriedade para serialização de texto
    - Adicionar estratégia `valid_texts()` em `tests/strategies.py`
    - **Propriedade 4: Serialização de payload de texto**
    - **Valida: Requisitos 11.2, 1.1**

  - [x] 4.7 Escrever teste de propriedade para round-trip de Card V2
    - Adicionar estratégias `valid_titles()`, `valid_sections()` e `card_payloads()` em `tests/strategies.py`
    - **Propriedade 3: Round-trip de payload Card V2**
    - **Valida: Requisitos 11.3**

  - [x] 4.8 Escrever teste de propriedade para subtítulo condicional no Card V2
    - **Propriedade 5: Inclusão condicional de subtítulo no Card V2**
    - **Valida: Requisitos 2.2, 2.3**

  - [x] 4.9 Implementar método `post` e construção de URL com thread params
    - Implementar `async def post(self, webhook_url: str, payload: dict, params: dict | None = None) -> dict` com httpx, Content-Type application/json, timeout 10s
    - Implementar lógica de construção de URL com `threadKey` e `messageReplyOption` para mensagens em thread
    - Tratar respostas HTTP (200 = sucesso, outros = erro com status + body)
    - Tratar `httpx.TimeoutException` com mensagem descritiva
    - Logar URLs sanitizadas via `sanitize_url`
    - _Requisitos: 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 3.1, 7.3_

  - [x] 4.10 Escrever teste de propriedade para URL com parâmetros de thread
    - Adicionar estratégia `valid_thread_keys()` em `tests/strategies.py`
    - **Propriedade 6: Construção de URL com parâmetros de thread**
    - **Valida: Requisitos 3.1**

  - [x] 4.11 Escrever teste de propriedade para tratamento de respostas HTTP
    - Criar `tests/test_client.py` com mock de httpx
    - **Propriedade 10: Tratamento de respostas HTTP**
    - **Valida: Requisitos 5.4, 5.5**

- [x] 5. Checkpoint - Verificar client HTTP
  - Garantir que todos os testes passam, perguntar ao usuário se houver dúvidas.

- [x] 6. Implementar tools MCP (`server.py`)
  - [x] 6.1 Implementar tool `send_message`
    - Criar `src/pack_mcp_google_chat_notification/server.py` com FastMCP
    - Implementar `send_message(text: str, webhook_url: str | None = None) -> dict` com validação de texto não vazio, resolução de webhook, construção de payload e envio via client
    - Implementar `main()` com `mcp.run(transport="stdio")`
    - _Requisitos: 1.1, 1.2, 1.3, 1.4, 10.3_

  - [x] 6.2 Implementar tool `send_card`
    - Implementar `send_card(title: str, sections: list[dict], subtitle: str | None = None, webhook_url: str | None = None) -> dict` com validação de título e sections não vazios, construção de payload Card V2 e envio via client
    - _Requisitos: 2.1, 2.2, 2.3, 2.4, 2.5_

  - [x] 6.3 Implementar tool `send_thread_message`
    - Implementar `send_thread_message(text: str, thread_key: str, webhook_url: str | None = None) -> dict` com validação de texto e thread_key não vazios, construção de URL com thread params e envio via client
    - _Requisitos: 3.1, 3.2, 3.3_

  - [x] 6.4 Escrever testes unitários para as tools MCP
    - Criar `tests/test_server.py` com mock do client
    - Testar edge cases: texto vazio, título vazio, sections vazia, thread_key vazia, sem webhook configurado
    - Testar configuração de LOG_LEVEL via env var e default WARNING
    - _Requisitos: 1.3, 1.4, 2.4, 2.5, 3.2, 3.3, 8.2, 8.3_

- [x] 7. Checkpoint final - Verificar integração completa
  - Garantir que todos os testes passam, perguntar ao usuário se houver dúvidas.

## Notas

- Tarefas marcadas com `*` são opcionais e podem ser puladas para um MVP mais rápido
- Cada tarefa referencia requisitos específicos para rastreabilidade
- Checkpoints garantem validação incremental
- Testes de propriedade validam propriedades universais de corretude
- Testes unitários validam exemplos específicos e edge cases
