← Production← Produção

Six questions, six reports.

Seis perguntas, seis relatórios.

The last stretch of the pipeline: turning a consolidated CSV into something an investment committee reads at 9am. Every screenshot below is from a real report, with every name and number deleted before the image was rendered — not blurred, deleted from the page itself.

O último trecho do pipeline: transformar um CSV consolidado em algo que o comitê de investimentos lê às 9h. Cada print abaixo é de um relatório real, com todo nome e número apagado antes da imagem ser renderizada — não borrado, apagado da própria página.

One consolidated table, three audiences.

Uma tabela consolidada, três públicos.

By the time the ETL layer has produced a clean, consolidated position, three different questions still need answers: is anything overdue (aging), is the portfolio too concentrated in one debtor or region (concentration), and will there be enough cash to cover redemptions (liquidity)? A fourth question sits underneath all three — is the fund still inside its own regulatory limits (compliance)?

Quando a camada de ETL já produziu uma posição consolidada e limpa, três perguntas diferentes ainda precisam de resposta: há algo vencido (aging), a carteira está concentrada demais num devedor ou região (concentração), e vai sobrar caixa para cobrir resgates (liquidez)? Uma quarta pergunta sustenta as três — o fundo continua dentro dos próprios limites regulatórios (enquadramento)?

Each question gets its own generator rather than one mega-report: different audiences read at different frequencies, and a single failing report shouldn't block the other five.

Cada pergunta ganha seu próprio gerador em vez de um mega-relatório: públicos diferentes leem em frequências diferentes, e um relatório que falha não pode travar os outros cinco.

Report types
Tipos de relatório
6
Aging, concentration, liquidity, receivables flow, payment performance, compliance.
Aging, concentração, liquidez, fluxo de recebíveis, performance de pagamento, enquadramento.
Rendering
Renderização
Self-contained HTML
HTML autocontido
pandas Styler tables + matplotlib charts inlined as base64 — one file, no server needed to view it.
Tabelas pandas Styler + gráficos matplotlib embutidos como base64 — um arquivo só, dispensa servidor pra abrir.
Delivery
Entrega
Dashboard + email
Dashboard + e-mail
An internal Flask dashboard serves them on demand; a mailbox-driven watcher pushes the daily ones out automatically.
Um dashboard Flask interno serve sob demanda; um watcher de caixa de e-mail dispara os diários automaticamente.

How a report gets from data to inbox

Do dado ao e-mail

report layer camada de relatórios consolidated datadado consolidado generatorgerador deliveryentrega

The six generators

Os seis geradores

01

Aging — delinquency by every cut that matters

Aging — inadimplência por todo corte relevante

A heatmap of receivables by days-overdue bucket, sliced by portfolio, assignor, originator, state, and payment-capacity rating, plus a weighted score ranking the segments from healthiest to riskiest.

Um heatmap de recebíveis por faixa de dias em atraso, cortado por carteira, cedente, originador, UF e rating de capacidade de pagamento, mais um score ponderado ranqueando os segmentos do mais saudável ao mais arriscado.

02

Concentration — how spread out is the portfolio, really

Concentração — o quão pulverizada a carteira está, de fato

Nine cumulative-share curves (by debtor, product, PDD band, agreement, originator, referral partner, state, payment-capacity rating, age bracket) answering the same question nine ways: what share of the book do the N largest exposures represent?

Nove curvas de participação acumulada (por sacado, produto, faixa de PDD, convênio, originador, promotora, UF, rating de capacidade e faixa etária) respondendo a mesma pergunta de nove formas: que fatia da carteira as N maiores exposições representam?

03

Liquidity — will there be cash when redemptions land

Liquidez — vai ter caixa quando os resgates chegarem

Projects the fund's asset and liability cash flows forward using table-driven amortization rules, a senior/subordinated waterfall, and a sensitivity matrix for stress scenarios.

Projeta os fluxos de caixa de ativo e passivo do fundo usando regras de amortização orientadas a dados, uma cascata sênior/subordinada e uma matriz de sensibilidade para cenários de estresse.

04

Receivables flow — the next ten business days, day by day

Fluxo de recebimentos — os próximos dez dias úteis, dia a dia

A short, non-cumulative window (five business days back, today, five forward) computed straight from the installment-level raw file rather than the consolidated position — a deliberately independent second read of the same cash reality.

Uma janela curta e não cumulativa (cinco dias úteis para trás, hoje, cinco para frente) calculada direto do bruto em nível de parcela, não da posição consolidada — uma segunda leitura deliberadamente independente da mesma realidade de caixa.

05

PMT — did payments come in as scheduled

PMT — os pagamentos entraram como programado

Compares consecutive snapshots to separate what was expected to be paid from what actually reduced the stock, broken down by agreement, and estimates the loss from early settlements at a different rate than projected.

Compara snapshots consecutivos para separar o que era esperado ser pago do que de fato reduziu o estoque, detalhado por convênio, e estima a perda das liquidações antecipadas a uma taxa diferente da projetada.

06

Compliance — still inside the fund's own rulebook

Enquadramento — ainda dentro das próprias regras do fundo

Evaluates every regulatory and contractual limit (minimum equity, issuer concentration, allocation bounds) through a small boolean-expression engine and marks each one OK, alert, or breached — see subsystem 04.

Avalia todo limite regulatório e contratual (patrimônio mínimo, concentração de emissor, faixas de alocação) por um pequeno motor de expressões booleanas e marca cada um como OK, alerta ou violado — ver subsistema 04.

Engineering decision

Decisão de engenharia

Why scrape a mailbox instead of watching a synced folder Por que raspar uma caixa de e-mail em vez de vigiar uma pasta sincronizada

One of the report inputs arrives as a file attachment from a counterparty, and the obvious design is to watch the local OneDrive-synced folder for new files. The dispatch pipeline scrapes the mailbox instead, for three reasons stated explicitly in the codebase: timing control (a folder watcher fires on sync completion, which the sender doesn't control; a mailbox poll fires on a schedule this system controls), reusing one auth method for both reading and sending, and a small trigger file kept under a kilobyte instead of syncing the full attachment twice.

Uma das entradas do relatório chega como anexo de e-mail de uma contraparte, e o desenho óbvio seria vigiar a pasta local sincronizada do OneDrive por arquivos novos. O pipeline de despacho raspa a caixa de e-mail em vez disso, por três razões documentadas explicitamente no código: controle de timing (um watcher de pasta dispara na conclusão do sync, que o remetente não controla; um poll de e-mail dispara num horário que este sistema controla), reaproveitar um único método de autenticação para ler e enviar, e um arquivo de gatilho de menos de 1 KB em vez de sincronizar o anexo inteiro duas vezes.

Why the dashboard has four dependencies and no build step Por que o dashboard tem quatro dependências e nenhum build step

The internal dashboard that lists and serves these reports is a single-file Flask app: flask, pandas, openpyxl, requests. No ORM, no database — every CRUD form reads and writes the same CSV/XLSX files the pipelines already produce, driven by a declarative schema so a new field means editing one schema module, not five templates. Bootstrap loads from a CDN; six plain JavaScript files handle sorting, cascading dropdowns, and a live rule-expression validator. A cache-bust endpoint clears the in-memory read caches after a file edit — the closest thing to a "deploy" this app has.

O dashboard interno que lista e serve esses relatórios é um app Flask de um arquivo só: flask, pandas, openpyxl, requests. Sem ORM, sem banco — todo formulário CRUD lê e escreve os mesmos CSV/XLSX que os pipelines já produzem, orientado por um schema declarativo, de modo que um campo novo significa editar um módulo de schema, não cinco templates. O Bootstrap carrega de um CDN; seis arquivos de JavaScript puro cuidam de ordenação, dropdowns em cascata e um validador de expressões ao vivo. Um endpoint de cache-bust limpa os caches de leitura em memória depois de uma edição — o mais próximo que esse app tem de um "deploy".

What comes out

O que sai disso

Real reports, sanitized for this page: every table cell and header value was deleted from the HTML before the screenshot was taken (not styled invisible — removed), and every chart image was blurred and desaturated at the pixel level. Fund names, counterparty names, and every figure are gone; the layout and the kind of analysis are real.

Relatórios reais, sanitizados para esta página: todo valor de célula e cabeçalho de tabela foi apagado do HTML antes do print (não estilizado como invisível — removido), e todo gráfico levou blur e dessaturação em nível de pixel. Nomes de fundo, de contraparte e todo número desapareceram; o layout e o tipo de análise são reais.

Aging report header and first table
Aging report — header and the consolidated-portfolio table. Values and the fund name were removed before rendering; only the table structure and column layout remain.
Relatório de Aging — cabeçalho e a tabela da carteira consolidada. Valores e o nome do fundo foram removidos antes da renderização; só a estrutura da tabela e o layout das colunas permanecem.
Aging report broken down by state and payment-capacity rating
The same heatmap re-sliced by state and by payment-capacity rating — two of the five segmentations this generator produces from one run.
O mesmo heatmap recortado por UF e por rating de capacidade de pagamento — duas das cinco segmentações que este gerador produz numa única rodada.
Concentration report header and debtor-concentration chart
Concentration report — the summary box (portfolio totals, all redacted) and the cumulative-share chart for the largest debtors. Chart labels carry real figures baked into the pixels, so the whole image is blurred, not just the table.
Relatório de Concentração — o quadro-resumo (totais da carteira, todos redigidos) e o gráfico de participação acumulada pelos maiores sacados. Os rótulos do gráfico carregam números reais gravados nos pixels, então a imagem inteira leva blur, não só a tabela.
Concentration report by state
Distribution by state — one of nine cuts. The report itself already numbers the axis instead of naming debtors, for exactly this reason.
Distribuição por UF — um dos nove cortes. O próprio relatório já numera o eixo em vez de nomear sacados, exatamente por este motivo.
Liquidity report header and status badge
Liquidity report header, with the pass/fail status badge that opens the document.
Cabeçalho do relatório de Liquidez, com o badge de situação que abre o documento.
Liquidity report asset vs liability curve
Projected asset vs. liability curve over the horizon — the chart the status badge is derived from.
Curva projetada de ativo x passivo ao longo do horizonte — o gráfico do qual o badge de situação deriva.
Receivables flow report header and daily stock table
Receivables flow report — the day-by-day stock table for the ten-business-day window.
Relatório de Fluxo de Recebimentos — a tabela diária de estoque para a janela de dez dias úteis.
PMT report methodology and portfolio summary
PMT report — the methodology block (kept legible; it's a definition, not data) above the redacted portfolio summary.
Relatório PMT — o bloco de metodologia (mantido legível; é definição, não dado) acima do resumo redigido da carteira.
Compliance report header with OK status badge
Compliance report — fund header (redacted) and the first rule, minimum equity, showing a passing status.
Relatório de Enquadramento — cabeçalho do fundo (redigido) e a primeira regra, patrimônio mínimo, com situação OK.
Compliance report issuer concentration rule with no applicable limit
Issuer-concentration rule for a fund whose investors are professional — the rule engine correctly reports "no limit applies" rather than a false pass.
Regra de concentração de emissor para um fundo de investidores profissionais — o motor de regras corretamente reporta "sem limite aplicável", não um OK falso.

Stack

Stack

Reportspandas · matplotlib · Styler
DashboardFlask · Jinja2
DispatchDespachoMicrosoft Graph
FactsheetLâminapython-docx · LibreOffice