This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Pipeline de dados da NASA GCN (Gamma-ray Coordinates Network) usando Databricks Asset Bundles e Lakeflow Declarative Pipelines. Ingere alertas astronômicos em tempo real do stream Kafka da NASA através de uma arquitetura medallion (Bronze -> Silver -> Gold).
Stack: Databricks Asset Bundles, Spark Declarative Pipelines (SDP), PySpark, NASA GCN Kafka, gerenciador de pacotes uv.
IMPORTANTE: Antes de executar qualquer alteração no código, SEMPRE seguir este protocolo:
┌─────────────────────────────────────────────────────────────┐
│ USUÁRIO apresenta o problema/requisito │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ CLAUDE analisa e sugere abordagens │
│ - Explica os trade-offs │
│ - Apresenta opções quando aplicável │
│ - Identifica riscos ou dependências │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ USUÁRIO dá o OK para prosseguir │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ CLAUDE executa seguindo o dev-workflow │
└─────────────────────────────────────────────────────────────┘
Após o OK do usuário, seguir SEMPRE este fluxo:
git checkout -b feature/<nome>- Criar branch- Implementar as alterações
pytest tests/ -v- Rodar testes unitários./deploy.sh- Deploy em dev./deploy.sh run-only- Executar e validar pipeline em devgit commit+git push- Commit e pushgh pr create- Criar PRgh pr merge --delete-branch- Merge após aprovação- (Opcional)
TARGET=prod ./deploy.sh- Deploy em prod
Nunca fazer commit direto na main. Todas as alterações passam por PR.
Ver skill /dev-workflow para detalhes completos.
# Instalar dependências
uv sync --dev
# Executar todos os testes
pytest
# Executar teste específico
pytest tests/main_test.py::test_format_number -v
# Executar testes com cobertura
pytest --cov=nasa_gcn --cov-report=term-missing
# Lint e correção automática
ruff check src/ tests/ --fix
# Formatar código
ruff format src/ tests/
# Verificação de tipos
mypy src/
# Validar configuração do bundle
databricks bundle validate
# Deploy e execução (carrega credenciais do .env automaticamente)
./deploy.sh run
# Apenas deploy
./deploy.sh
# Executar job sem fazer novo deploy
./deploy.sh run-only
# Deploy para produção
TARGET=prod ./deploy.sh runO pipeline usa uma arquitetura medallion com 3 pipelines SDP (Spark Declarative Pipelines) separados:
NASA GCN Kafka Stream
│
▼
┌─────────────────────────────────────────────────────────────┐
│ PIPELINE BRONZE (bronze_pipeline.py) │
│ └─ gcn_raw: Todas as mensagens brutas do Kafka │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ PIPELINE SILVER (silver_pipeline.py) │
│ ├─ gcn_circulars (relatórios escritos por humanos) │
│ ├─ gcn_notices (alertas JSON gerados por máquina) │
│ ├─ gcn_classic_text (formato texto legado) │
│ ├─ gcn_classic_voevent (XML VOEvent) │
│ ├─ gcn_classic_binary (pacotes binários parseados) │
│ ├─ gcn_gwalert (ondas gravitacionais) │
│ └─ gcn_heartbeat (saúde do sistema) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ PIPELINE GOLD (gold_pipeline.sql) │
│ ├─ gcn_events_summary (narrativas de eventos enriquecidas) │
│ └─ gcn_daily_stats (agregações diárias) │
└─────────────────────────────────────────────────────────────┘
Orquestração do Job: nasa_gcn.job.yml executa os pipelines sequencialmente: validate → bronze → silver → gold → report
Os pipelines usam _bootstrap.py para resolver imports no Free/Community Edition do Databricks.
Por quê: O Free Edition não suporta wheels gerenciados ou repositórios Git com PYTHONPATH automático. O módulo centraliza a manipulação de sys.path que seria necessária em cada pipeline.
Como funciona:
# No pipeline (bronze_pipeline.py, silver_pipeline.py)
import _bootstrap
_bootstrap.setup_environment(spark) # spark é global no contexto SDPContraste Pedagógico - Free Edition vs Produção:
- Free Edition (atual): Resolução de path em runtime via
sys.path.insert - Produção Real: Construir Python Wheel (
.whl) e declarar nolibrariesdo YAML:libraries: - whl: /Volumes/catalog/schema/wheels/nasa_gcn-1.0.0-py3-none-any.whl
Ver _bootstrap.py para documentação completa sobre a arquitetura.
silver_pipeline.py contém lógica do parser binário embutida (linhas 61-196) que deve permanecer sincronizada com binary_parser.py.
Por quê: O DLT serverless do Databricks não consegue importar módulos customizados de forma confiável nos executores Spark. UDFs requerem que todo código esteja inline.
Ao modificar o parser binário:
- Atualize
binary_parser.py(fonte da verdade) - Sincronize manualmente as mudanças para
silver_pipeline.py:61-196 - Mantenha o dict
PACKET_TYPE_NAMESsincronizado
sparké uma variável global no contexto SDP - não é importada, mas está disponível em runtime- UDFs no SDP não conseguem importar de módulos irmãos nos executores - todo código deve estar inline no arquivo da UDF
- Pipelines Silver/Gold usam
spark.readStream.table()para ler de tabelas de outros pipelines - Cada pipeline tem sua própria configuração de catalog/schema via
spark.conf.get() - Usar
from pyspark import pipelines as dp(nãoimport dlt) cluster_bynão é suportado em@dp.materialized_view()no Python API - usar SQL comCLUSTER BY (coluna)como alternativa- Sintaxe
CLUSTER BY AUTO: Usar sem parênteses -CLUSTER BY AUTO(correto) vsCLUSTER BY (AUTO)(incorreto - interpreta AUTO como coluna). Em produção, preferir chaves manuais para padrões de acesso conhecidos. DESCRIBE DETAILnão funciona em materialized views: Esse comando Delta só funciona em tabelas físicas (streaming tables). Materialized views são registradas como views no Unity Catalog — usarSELECT COUNT(*) FROM mvcomo fallback. Vermain.py:get_table_count()para padrão implementado.- Gold MVs fazem full-refresh a cada execução: Esperado —
gcn_events_summaryfaz JOIN comgcn_gwalert(SCD Type 2), o que impede refresh incremental. Não é bug.
Auto-Optimize (Bronze + Silver):
table_properties={
"delta.autoOptimize.optimizeWrite": "true",
"delta.autoOptimize.autoCompact": "true",
}Data Quality Expectations (Silver):
@dp.expect_or_drop("valid_id", "id IS NOT NULL")gcn_circulars: valid_circular_id, valid_event_idgcn_notices: valid_notice_idgcn_classic_binary: valid_parse (parse_error IS NULL)gcn_gwalert: valid_event_id
Row Tracking (Silver - gcn_circulars, gcn_notices, gcn_gwalert):
table_properties={
...,
"delta.enableRowTracking": "true",
}Habilita refresh incremental das materialized views Gold que fazem join com essas tabelas.
Change Data Feed (Gold):
table_properties={"delta.enableChangeDataFeed": "true"}O Databricks Community Edition não suporta a API de Secrets. Credenciais são armazenadas em .env (ignorado pelo git):
# Preferido: Codificado em Base64
GCN_CLIENT_ID_B64=...
GCN_CLIENT_SECRET_B64=...
# Alternativa: Texto puro
GCN_CLIENT_ID=...
GCN_CLIENT_SECRET=...Use python scripts/encode_credentials.py para codificar credenciais. O deploy.sh detecta e decodifica Base64 automaticamente.
- Dev:
sandbox.bronze,sandbox.silver,sandbox.gold - Prod:
nasa_gcn.bronze,nasa_gcn.silver,nasa_gcn.gold
- Adicione o schema em
src/nasa_gcn/schemas.py(se necessário) - Adicione definição
@dp.tableemsrc/nasa_gcn/pipelines/silver_pipeline.py - Atualize o padrão de filtro para corresponder ao novo tópico
- Adicione nova
MATERIALIZED VIEWemsrc/nasa_gcn/pipelines/gold_pipeline.sql - Use
CLUSTER BY (colunas)com as dimensões de filtro mais comuns (ver seção de performance) - Referencie tabelas Silver via
${silver_catalog}.${silver_schema}.table_name
CREATE OR REPLACE MATERIALIZED VIEW nova_agregacao
COMMENT 'Descrição da agregação'
CLUSTER BY (dimensao_principal, dimensao_secundaria)
AS
SELECT ...
FROM `${silver_catalog}`.`${silver_schema}`.tabela_silver;Para MVs sem padrão de acesso definido, CLUSTER BY AUTO é aceitável em desenvolvimento.
- Teste falhando:
tests/main_test.py::test_get_logger- asserção de handler do logger falha - Exceções genéricas:
config.py:45-46ebinary_parser.py:369-372engolem erros silenciosamente
Veja TECHNICAL_DEBT.md para rastreamento completo de issues e planejamento de sprints.
| Arquivo | Propósito |
|---|---|
src/nasa_gcn/pipelines/_bootstrap.py |
Setup de ambiente (Free Edition workaround) |
src/nasa_gcn/pipelines/bronze_pipeline.py |
Bronze: Ingestão Kafka para gcn_raw |
src/nasa_gcn/pipelines/silver_pipeline.py |
Silver: Parsing por tópico (7 tabelas) |
src/nasa_gcn/pipelines/silver_gwalert_cdc.sql |
Silver: AUTO CDC para gcn_gwalert (SCD Type 2) |
src/nasa_gcn/pipelines/gold_pipeline.sql |
Gold: Agregações — gcn_events_summary (CLUSTER BY AUTO), gcn_daily_stats (CLUSTER BY date) |
src/nasa_gcn/binary_parser.py |
Decodificador de pacotes binários GCN (fonte da verdade) |
src/nasa_gcn/schemas.py |
Schemas PySpark para todos os tópicos GCN |
src/nasa_gcn/config.py |
Configuração do Kafka e credenciais |
src/nasa_gcn/main.py |
Relatório de status e métricas do pipeline |
deploy.sh |
Script de deploy com tratamento de credenciais |
databricks.yml |
Configuração do asset bundle |
resources/nasa_gcn.job.yml |
Orquestração do job (DAG de pipelines) |
resources/pipelines/*.yml |
Configurações individuais dos pipelines |
docs/GCN_*_RAG.md- Documentação de contexto RAG para cada tópico GCNdocs/GOLD_LAYER.md- Lógica de enriquecimento da camada GoldTECHNICAL_DEBT.md- Rastreamento de issues e planejamento de sprints