Pipeline de dados
Fontes
Section titled “Fontes”| Camada | Onde | Conteúdo |
|---|---|---|
| Bronze | kanban-ekyte-experiment/data/raw/*.json | Páginas brutas Ekyte API (workspaces, squads, projects, users, tasks status 10/20/30/40, time_trackings) |
| Silver | kanban-ekyte-experiment/data/events.db (SQLite) | Event store: CardCreated, CardCompleted, CardCancelled, CardMoved (inferido), HoursLogged |
| Gold | kanban-ekyte-experiment/data/marts.duckdb (DuckDB) | Marts: mart_cards, mart_hours_vs_flow, mart_aging_wip, mart_throughput_weekly, etc. |
Extração para o Starlight
Section titled “Extração para o Starlight”Script /tmp/squad_v2_pipeline.py:
- Lê
mart_cardsvia DuckDB CLI (metadata por card) - Lê
data/raw/time_trackings_p*.jsondireto (preservaphaseIdpor entry — não está no events.db) - Computa por card:
first_any_hour,first_work_phase_hour,entered_work_first,entered_aprov_first,h_by_logger,h_by_phase_cat - Junta com
entered_current_phase_atdo mart (necessário para cardsstatus=activeem Aprovação cliente) - Aplica fórmulas v2 (ver Modelo de tempo)
- Emite
src/data/{squad}.json(cards detalhados) esrc/data/{squad}_summary.json(stats agregadas)
Atribuição de horas — caveat crítico
Section titled “Atribuição de horas — caveat crítico”Mart mart_cards.total_minutes_logged agrega tudo sob executor_name do card (= assignee, frequentemente o gerente). Para “quem realmente trabalhou”, agregamos HoursLogged.payload.executor_name (= logger).
Exemplo descoberto em ABM: Ana Julia (gerente) aparecia como dona de 135.8h via mart. Pelo HoursLogged real: Diego Artur 143.7h (94%), Ana 8.8h (6%). Gerente é assignee burocrática; dev executa.
Por isso o quadro “horas por pessoa” sempre usa o logger, nunca o assignee.
Trilha A vs Trilha B
Section titled “Trilha A vs Trilha B”| Sinal | Trilha | Confiança | Cobertura |
|---|---|---|---|
| effort_h, estimated_h | A (TT direto) | alta | ABM 90%, MWM 100%, Mercosul 94% |
| lead_time (delivered − created) | A | alta | 100% |
| wip_age, current_phase | A | alta | 100% |
| CardMoved (transições) | B (inferido) | baixa | ABM 47%, MWM 23%, Mercosul 47% |
Não usar transições intra-board como argumento de fluxo sem qualificar como inferência fraca. Para o modelo v2, usamos phaseId de HoursLogged direto do raw — mais confiável que CardMoved.
Reprodução
Section titled “Reprodução”# Refresh rawcd ~/.obsidian/99-development/kanban-ekyte-experimentuv run python scripts/pull.py # ou equivalente
# Rebuild martsuv run python scripts/ingest.pyuv run python scripts/build_marts.py
# Rebuild Starlight datapython3 /tmp/squad_v2_pipeline.pypython3 /tmp/build_squad_stats.py
# Dev servercd ~/.obsidian/99-development/kanban-docspnpm dev