Skip to content
All work

01 · Legacy Modernization

Community Operations Platform

The organization ran on two separate ASP.NET Web Forms applications built over a decade apart. One held the member directory. The other held the money. They shared no login, no data model, and no owner. Every reconciliation was manual, every report was a spreadsheet, and nothing worked on a phone.

Client
A US faith-community nonprofit serving several hundred households
Sector
Nonprofit / Member Operations
Engagement
Full rebuild — discovery through production
Year
2026

2 → 1

Applications consolidated

12

Functional domains specified

~$13/mo

Production infrastructure cost

0

Database passwords in circulation

01

Write the specification first

Nobody could say what the legacy system did. The people who built it were gone, and the only documentation was the running code. So before a line of new code, we reverse-engineered a complete, technology-agnostic requirements specification from production behavior — twelve functional domains, the full domain model, every cross-cutting business rule, and a glossary of the community terminology the software encodes.

The specification prescribes no framework, no database and no library. That was deliberate. It made the rebuild reviewable by people who do not write software, and it means the organization owns a description of its own system that outlives any stack we chose.

02

Model the domain honestly

The hard part was never the CRUD. It was an event-approval workflow gated on financial clearance: a member cannot be granted permission to host an occasion while obligations are outstanding, and obligations carry discounts, partial payments and household-level rollups. The legacy system enforced this by convention — a volunteer remembering to check the other application.

We modeled it as a first-class workflow with explicit states, and put the rules under test. Members, households, events, obligations, payments and RSVP responses became one coherent model instead of two overlapping ones.

03

Design for the people who use it

Two audiences share the system: members of all ages who log in occasionally, and volunteer committee members who run operations. Neither group is paid ops staff and neither has a support desk.

RSVP works without a login — a tokenized link, three counts, submit. The dual Gregorian/Hijri calendar is treated as a first-class citizen everywhere a date appears, not bolted onto one calendar page. Community terminology is rendered verbatim rather than translated into generic SaaS vocabulary, because software that renames your world reads as software bought off a shelf.

04

Ship it on infrastructure they can afford

Production runs on Azure App Service with a companion Functions worker for reminders and a separate lightweight application for public RSVP submission. Both applications reach the database through system-assigned Managed Identity — there are no connection-string passwords to leak or rotate, and the same connection string shape works locally and in production.

Schema changes go through EF Core migrations. The domain rules — password reset, role assignment, household grouping, obligation arithmetic, event workflow transitions, calendar conversion — are covered by a test suite that runs before every deploy.

Outcome

One login, one system, one source of truth. Members self-serve their financial history and RSVP from a phone; committee volunteers approve events and reconcile obligations in the same tool they use for the directory.

The organization holds a written specification of its own operations, a tested codebase, and production infrastructure that costs roughly the price of a sandwich each month.

Built with

.NET 10ASP.NET CoreEF CoreAzure SQLAzure App ServiceAzure FunctionsEntra IDManaged Identity

Next case study

Grounded Voice Agent

A real-time voice assistant that answers in a founder’s own words — because it is required to look them up first.