Inspiration
💡A project bids at 15% margin. Six months later, realized margin is under 7%. The signals were buried across labor logs, change orders, RFIs, and billing records that nobody had time to cross-reference.
👉 We detected that failure in the data and decided to build something that catches it before it's too late.
What it does
1️⃣ The dashboard loads and immediately shows which projects are bleeding! Click into the worst one and you see exactly where the money went.
2️⃣ Then it tells you what to do, such as "bill the 9 approved change orders totaling $214,600 this week" and "submit applications for the $1.9M in completed but unbilled work this month."
3️⃣ Our ReAct Based analyst agent goes deeper on demand. In our demo, It cross-references the project's $59.85 average hourly rate against the Nashville market average of $27-$31, identifies RFI-053 as a specific unforeseen condition that was never converted into a change order, and quantifies what that failure cost.
🔧 For agentic tools calls: Every SQL query, every web search, and every calculation is visible so you can verify the reasoning.
How we built it
🧹 The first day was almost entirely data cleaning. The dataset was designed to be messy in that the same job role written 15 different ways, dates in three different formats, field notes that required keyword extraction to be useful. We wrote a Python/pandas pipeline to normalize all of it before any analysis could happen.
📄 Once the data was clean, we aggregated 1.2 million labor rows down to a 405-row project summary. This was the critical step for later agent memory and context design. It provides useful tools which later be handy for the agent.
👉 From there, a background thread runs claude-haiku-4-5 (now switch to Gemini) against every project's summary at startup and caches the results in SQLite. By the time a user opens the dashboard, the analysis is already done. For projects that need deeper investigation, a agent with SQL, web search, and calculator tools handles real-time queries and streams the results to the browser.
🖼️ The frontend was built with v0 and React 19, deployed on Vercel with a self-hosted FastAPI backend.(we also use Vercel’s font family Geist:))
Challenges we ran into
🤯Data cleaning took longer than expected. Role normalization alone required careful regex work to avoid false matches. Mixed date formats broke standard parsers and needed custom handling.
👉 The billing gap metric surfaced a genuine ambiguity in the data: two plausible interpretations that led to very different conclusions. We chose not to resolve it artificially. The live agent flags it explicitly and recommends the CFO clarify with accounting before acting on it. That felt more honest than picking an interpretation and presenting it as fact.
👉 Getting the feature engineering right was harder than the agent work. Deciding which 84 features to compute and making sure they were computed correctly took most of day one. The agent is only as good as what you feed it.
Accomplishments that we're proud of
PRJ-2021-260 was the find that made it real. A $2.6M project that bled to $5M in actual costs, caught and explained automatically. The recovery actions are specific enough to hand directly to a PM and act on today. We're also proud that the agent flags its own uncertainty. When billing data was ambiguous, it said so instead of picking an answer.
What we learned
The AI part was the easy part. Cleaning 1.46M records and engineering 84 meaningful features took more time and judgment than writing any prompt. The output is only as good as what clean data we feed in.
Built With
- claude
- fastapi
- pandas
- python
- react
- recharts
- sqlite
- tavily
- typescript
- v0
- vercel

Log in or sign up for Devpost to join the conversation.