Internal Enterprise Tool - Illinois State Water Survey

FEMA Grant Management.
Built from scratch. Built to fit.

CHAMP PM is a purpose-built program management system for a ~$15M FEMA flood hazard mitigation grant portfolio. Timesheets, budget burndown, staff salary projections, project scheduling, pay equity, and AI-assisted staff planning - all in one tool, all using the same formulas the grants require.

Live in production Vite + React + Tailwind Cloudflare Pages + D1 Not commercially available ~$15M portfolio
Could something like this work for you? → Visit champ-pm.app ↗ ← Back to Reep Works

Managing FEMA grants is genuinely hard work

Before CHAMP PM, the work that this system now handles was being done manually - spreadsheets, email threads, and tribal knowledge. Here's what that actually looks like at scale.

⚠️ Budget tracking was fragmented

Multiple active FEMA grants, each with its own budget, period of performance, and cost structure. Keeping track of actual vs. projected spend required manually pulling timesheet data and applying salary + fringe + F&A formulas. Any change to a staff member's salary cascaded through everything by hand.

⚠️ Staff cost projections were opaque

Allocating a staff member's time across grants required knowing their current salary, fringe rate, and how many hours remained in each grant. Doing this for a team of 10–15 people across 5–6 active grants was error-prone. No one had a real-time view of program runway.

⚠️ Salary data lived in a separate HR system

Salary changes flowed through the university's PRIDE system - a legacy PHP application with no REST API. Keeping CHAMP PM in sync required a manual data handoff. Any lag meant budget projections were running on stale numbers.

⚠️ Scheduling had no PoP guardrails

FEMA projects have hard period-of-performance end dates. Scheduling project phases without those constraints visible in the same tool meant it was easy to build a schedule that was technically impossible within the grant. What-if scenarios required duplicate spreadsheets.

What CHAMP PM does

Six modules, all connected. The same salary and fringe data that drives timesheets also drives budget projections, runway calculations, equity analysis, and staff plans.

📊

Grant & Budget Tracking

Track FEMA grant budgets, period-of-performance dates, and burndown in real time. Cost calculations - salary, fringe, and F&A at 0.317 MTDC - applied consistently across every grant. Alerts fire when grants approach their PoP with insufficient budget consumed.

⏱️

Timesheets

Staff enter hours against specific tasks and projects. The system calculates loaded costs using each person's actual salary and appointment-type fringe rate. Weekly submission and approval workflow. Admin view shows all staff timesheet status at a glance.

AI-Assisted Staff Plans

Allocate staff time across the grant portfolio with a linear programming optimizer. Natural-language goals - "prioritize FY24 grants," "keep Zoe off the mapping project" - get translated by Claude into constraint overrides and fed into the solver. Deterministic math, AI-shaped inputs.

📅

Gantt Scheduling + What-If

Project phases and milestones on a SVG Gantt chart, constrained by the grant's period of performance. Structured templates for FEMA data development and mapping project types. Sandboxed what-if scenarios let you explore schedule changes without touching the base plan.

📈

Program Runway

See how far current funding extends under different staffing scenarios. Budget burndown shows actual vs. projected spend across the full portfolio. Salary projection uses current salary records and fringe rates - no manual data entry required after each pay change.

⚖️

Equity & Salary Analysis

Staff pay equity analysis against classification bands. Salary history as an append-only audit trail - never edited, always inserted. Promotions tracker with scoring criteria. Salary records feed directly into all cost projections throughout the system.

🔄

PRIDE Salary Sync

Illinois NCSA's PRIDE system has no REST API. A browser bookmarklet runs inside the authenticated PRIDE session, scrapes current salary data, and POSTs it to CHAMP PM. When PRIDE shows a higher salary than CHAMP PM, a new salary record is automatically inserted.

📥

Import & Data Migration

CSV import for legacy timesheet history with configurable staff and project mappings. Handles edge cases in historical data including staff name variations and project name changes. Mapping tables stored in D1 for reuse.

🔐

Auth & Access Control

Clerk-powered authentication with email-matched D1 user records. Admin vs. staff role separation enforced at the API layer. Onboarding flow for new staff. Holding page for authenticated users not yet in the system. Invite-based access - not open registration.

What's shipped

Active development. Major capability milestones in reverse order.

AI-Assisted Staff Plan Goals May 2026

Claude (claude-3-5-haiku) translates natural-language staff planning goals into constraint overrides for the LP optimizer - grant urgency multipliers, per-person caps and floors, exclusions. Zero change to the optimizer when goals aren't used. Violet ✨ toggle in the Plan Builder UI; explanation banner shown after each AI-guided run.

PRIDE Salary Sync Bookmarklet May 2026

Bookmarklet-based integration with Illinois NCSA's PRIDE staff plan system. Runs in the authenticated browser session, scrapes salary and job end-date data for 25 mapped CHAMP staff, and POSTs to a CHAMP PM endpoint authenticated with a pre-shared token. Auto-inserts new salary records on increase; flags for review otherwise.

Gantt Scheduling + What-If Scenarios April 2026

SVG Gantt chart with drag-to-edit in what-if mode. Phase and milestone scheduling with PoP ceiling enforcement - no phase may extend past the grant end date. Structured templates for FEMA data development (8 phases, 8 milestones) and mapping (5 phases, 5 milestones) project types. Sandboxed scenarios store deltas only; base schedule never modified during what-if exploration.

Full Account String Refactor April 2026

Corrected a structural data model issue where fund numbers - not unique in the grants database - were being used as grant identifiers in joins and matching. Fund 100026 maps to 8+ distinct accounts. All logic now uses full_account_string as the canonical key throughout staff plans, budget, and reports.

Budget Burndown + Program Runway March 2026

Real-time budget burndown tracking actual vs. projected costs across all active grants. Program runway projections using current salary records and fringe rates. Alert system surfaces grants approaching PoP end with insufficient budget consumed or projected to exceed grant ceiling.

LP Optimizer for Staff Plans February 2026

Linear programming optimizer allocates staff hours across the grant portfolio. Respects 100% appointment constraints, salary math, budget caps, and pinned manual overrides. Generates allocation scenarios that can be saved, compared, and activated as the live plan.

Core Platform Launch Late 2025

Grants, projects, tasks, timesheets, salary records, fringe rates, staff management, import tooling, and admin dashboard. Deployed on Cloudflare Pages + D1 with Clerk authentication. Auto-deploys on push to main.

How it's built

Entirely serverless. No containers, no persistent servers, no DevOps overhead. A small team running a large grant portfolio can't afford infrastructure complexity.

Frontend Vite + React + Tailwind CSS Single-page app, no SSR, builds to static assets
Backend Cloudflare Pages Functions Edge workers co-located with the frontend deploy
Database Cloudflare D1 (SQLite) Relational, globally replicated, zero managed infra
Auth Clerk JWT-based, email-matched D1 user records, role metadata
Hosting Cloudflare Pages Auto-deploys on push to main; ~60–90 second build cycle
AI Integration Anthropic API (Claude) claude-3-5-haiku for staff plan goals; never touches financial calculations
🔒Salary records are append-only. The salary history table is never edited - every pay change creates a new record with an effective date. The full history is always preserved.
🔒Fringe rates are immutable after creation. Changing a fringe rate retroactively would silently corrupt historical cost calculations. The system enforces this at the API layer.
🔒Grant PoP ceilings are hard limits. No project phase or milestone may be scheduled past the grant's period-of-performance end date. Enforced in the API (400 error) and surfaced in the UI as a warning before blocking.
⚙️D1 correlated subqueries don't work in SELECT + GROUP BY. A D1 limitation discovered in production. The pattern: run separate queries, combine in JavaScript. Documented in every place it matters.
⚙️AI is never in the critical path for financial data. The LP optimizer runs entirely on deterministic logic. Claude only touches natural-language inputs that get translated to constraint parameters - never salary math, never budget calculations.

What CHAMP PM says about what's possible

CHAMP PM isn't a product. It's a demonstration of what a purpose-built internal tool looks like when it's designed around the actual work - not a generic solution stretched to fit.

Your operation has workflows that software doesn't quite fit.

You've probably got spreadsheets doing things spreadsheets shouldn't do. Or you're paying for software that's close to what you need but requires workarounds everywhere it matters. CHAMP PM started as the same frustration - a $15M grant portfolio being managed in Excel and email, with no single source of truth and too many manual calculations to trust.

The technology stack is genuinely cheap to operate: Cloudflare Pages and D1 run at near-zero cost for an internal team. The investment is in design and development time - understanding the domain deeply enough to build something that fits the actual work.

If you're running a grant program, a specialized consulting practice, a nonprofit with complex operational needs, a government agency with reporting obligations, or any organization where the right answer is "something custom" rather than "another SaaS subscription" - this is what that looks like.