Project · 2026
Dashboards Administrativos em .NET
An administrative-dashboards platform for a higher-education institution — .NET 10 + React 19 on Postgres, reading the CRM and the academic system — whose heart is a daily snapshot creating the historical source the ERP doesn't have.
The ERP and the BI answer a single question: "how much is it today?". Nobody could say how many enrollments existed six months ago. The platform photographs the day, every day — and the question has an answer forever.
The third platform I've built for the same operation — after the CRM (Node.js) and the data platform (Fabric) — and the first in .NET: a .NET 10 API (C#, EF Core, PostgreSQL) with a React 19 SPA, started in August 2026, with 180+ commits in the first two weeks.
The problem that justifies it: the ERP's queries and the BI reflect only the current state — the question "how many enrollments did we have in March?" had no answer anywhere. A job photographs the closed day in the early hours of the next one (00:30) and writes the series to Postgres: the acquisition photo already runs in production with backfill, and the enrollment/finance one is born behind a gate — nothing is captured before the definitions are validated with the business areas. It's the historical source of truth, designed to feed CRM, marketing, sales and finance.
The product rules are written in a glossary made for the people who use the screens — and they apply before any data is captured: a dash is not zero ("—" means "we don't know"; R$ 0.00 would mean "it cost nothing", which would be a lie); every date cut uses the local timezone; and each number has exactly one declared source — three sources that never talk to each other: the CRM read-only, the academic system through a typed API, and the ad platforms. No magic joins across worlds.
The architecture is simple on purpose, and that is written as a rule in the repository itself: a single project, no DDD layers; endpoints as static classes under /api; snake_case by convention in EF Core; Google SSO issuing JWTs. Nothing touches Oracle directly — the academic system only comes in through the API. And no data started being captured before the definitions were validated with the business areas.
By the numbers
- 180+
- Commits in 2 weeks
- 00:30
- The closed-day photo
- 3
- Sources, never joined
- — ≠ 0
- Glossary rule #1
Engineering decisions
- 01
The photo the ERP doesn't take
The finding that shaped the design: the ERP's status queries reflect the current state, not the state at a past date — retroactive history can only be rebuilt from dated movement tables. So the platform doesn't promise the impossible: it photographs each closed day going forward and rebuilds from the past only what the movement tables support. Even the photo's time is a revised decision: the design said 23:50, and it became 00:30 of the next morning — because the day's final ten minutes, missing from the photo, would be missing forever. All documented before the first byte was captured.
- 02
A dash is not zero
A dash means "we don't know"; zero means "we know, and it's zero". The screen never swaps one for the other: any calculation that would divide by zero returns "—". A cost-per-lead of R$ 0.00 would claim each lead cost nothing — and the platform doesn't claim what it doesn't know. It's the same number-honesty discipline I carry from the CRM, now as a written product rule.
- 03
Each number with exactly one source
Three sources feed the platform — the CRM (read-only, no writes), the academic system (only through a typed API, never Oracle directly) and the ad platforms — and they never talk to each other. Every metric declares which source it comes from, and no screen adds different worlds into a single number. Enrollment is confirmed academic data; a lead is CRM data; and the historical series is born from the snapshot, separate from them all.
- 04
Simple on purpose
A single project, no modules, no DDD — and the anti-patterns are written down in the repository to keep it that way: no extra layers, no raw colors outside the design tokens, no skipping the /api prefix, no querying Oracle directly. A platform born with its maintenance rules documented ages much more slowly.
Architecture
Fontes
CRM · Academic API
Read-only Mongo and a typed HTTP client — never Oracle directly.
API .NET 10
Endpoints under /api
C# with EF Core and snake_case; Google SSO issuing JWTs.
Snapshot
The 00:30 photo
A daily job photographs the closed day and writes the history series to Postgres.
SPA React 19
TanStack Router & Query
Zustand, Tailwind 4 and design tokens inherited from the in-house design system.
Stack