Finance — Gift Processing subsystem · C# .NET Framework 4.7 / jQuery / SOAP → a modernized Angular 20 single-page UI presenting the whole gift-batch journey as one continuous flow, on .NET 10 / Azure App Service + PostgreSQL
Prepared by Concho.AI · May 2026 · Run 004
This engagement modernizes one subsystem of the OpenPetra platform — the Finance — Gift Processing module that handles donation batch management, multi-currency gift processing, tax-deductible receipt generation, and general ledger integration — rather than rewriting the whole application at once. The chosen subsystem is rebuilt on a current runtime (.NET 10), a modern user interface (Angular 20), and a cloud-native hosting platform (Azure App Service); the rest of the application keeps running unchanged. As subsequent subsystems follow the same pattern, the legacy stack shrinks one piece at a time until the modernization is complete. Subsystems are picked by combining business-functionality boundaries with technical boundaries so each modernization is small enough to ship safely but large enough to deliver visible business value. Because the modernization is C# → C#, domain knowledge embedded in 279 source files transfers directly — the focus is architectural, not linguistic.
Modern web stackjQuery + SOAP/.asmx → Angular 20 + REST APIs. Responsive on every device; TypeScript end-to-end; reactive forms replace DOM manipulation.
Dependency cleanup20 of 28 dependencies retired or replaced; 7 architectural concerns resolved; 1 known-CVE entry (axios 0.21.4) removed; NAnt + code-gen replaced by dotnet CLI + Bicep.
Behavior preserved12 of 14 business rules carried over verbatim. 1 is a deliberate improvement (live period validation); 1 (confidential gift privacy) requires documented mitigation. 5 corroborated by legacy NUnit tests.
The gift-processing UI is rebuilt as an Angular 20 SPA with reactive forms, donor autocomplete, live multi-currency totals, and a pre-commit GL journal preview — replacing three separate jQuery/AngularJS pages and full-page form posts.
The server-side code moves from .NET Framework 4.7 + ASMX SOAP to .NET 10 Minimal APIs with async/await, dependency injection, FluentValidation, and System.Text.Json — containerized and hosted on Azure App Service.
The database (PostgreSQL) is preserved — no engine migration, no data loss. The data access layer moves from XML-generated typed datasets to EF Core 10 + Npgsql with parameterized LINQ and source-generated migrations.
Hosting moves from Mono/FastCGI on bare metal to Azure App Service (P1v3 Linux) with managed scaling, Azure API Management for strangler-fig routing, Debezium + Azure Service Bus for change-data coexistence, and Microsoft Entra ID for authentication.
How the subsystem was chosen
Business boundary: Gift Processing is self-contained — clear inputs (donation batches from data entry staff and bank-statement imports in CAMT/MT940/CSV formats) and clear outputs (posted journal entries to GL + tax receipts to donors).
Technical boundary: the subsystem lives in 279 source files across 10 database tables with documented seams to Partner Management (read-only validation) and General Ledger (one-way posting). The posted/unposted batch state machine is the natural strangler routing key.
Risk profile: operationally critical (revenue operations) but with a well-defined blast radius — modernizing Gift Processing does not touch GL posting logic, partner management, or conference modules. Banking is held in reserve as Plan B if pilot constraints shift.
3-agent consensus: three independent analysis lenses (standard weighted / feasibility / business-value) evaluated all 27 business functions; two of three converged on Gift Processing as the optimal first slice. The downstream service-architecture consensus then scored the 2-service decomposition at 7.8/10 across DDD, Technical, and Business lenses.
Roadmap
Phase 1
Build the modernized subsystem
Stand up the 2-service architecture (Gift Processing API + Receipt Generation Service) on .NET 10 with Angular 20 SPA on Azure App Service; preserve every business rule; validate against real test data.
Phase 2
Run side-by-side
Azure APIM routes gift-processing SOAP traffic to legacy nginx; incrementally shift calls to modern REST endpoints, reads before writes. Debezium + Azure Service Bus carry change events to keep both sides in sync.
Phase 3
Cutover
Shift remaining gift-processing writes to the modern services in 5 risk-ordered stages keyed on the posted/unposted batch state machine. Parallel-run for one fiscal period before decommissioning the legacy gift code paths.
Phase 4
Next subsystem
Apply the same playbook to Finance — Banking (the documented Plan-B alternative) or Finance — Accounting. Each cycle shrinks the legacy footprint and grows the modern one.
How we know it works — automated verification
Concho read the entire OpenPetra codebase — 572,757 lines across 1,396 files — and pre-computed a complete inventory of business rules, data relationships, platform constraints, and integration points. From that inventory, the workflow derived 14 formal behavioral rule specifications with Given-When-Then scenarios (5 of them corroborated by surviving legacy NUnit tests), generated schema mappings for all 161 columns across 10 gift-processing tables, and reconciled platform-affinity findings across three independent runs at 100% consensus.
The analysis runs in hours, not months.
The full modernization report — architecture design, code translation examples, business rule catalog, data mapping strategy, UI transformation examples, modernization choreography, and deployment automation — was generated in approximately 2 hours via 28 sub-agent dispatches and roughly 135 Concho MCP queries. Comparable manual analysis is estimated at 16–29 weeks. This speed comes from Concho’s pre-built Language-Agnostic Deep Scan, which provides 100% codebase coverage versus the 20–30% sampling typical of manual reviews.
Codebase coverage572,757 lines / 1,396 files analyzed at 100% coverage.
27 business functions cataloged, 215 project-wide rules surfaced, 48 aggregate roots across 34 bounded contexts.
Behavioral fidelity14 formal rule specifications with Given-When-Then scenarios, confidence scores (0.70–0.95, mean 0.78), and source code evidence.
5 corroborated by surviving NUnit tests; 12 transfer verbatim; 1 deliberate improvement; 1 requires documented mitigation.
How Concho understands the code — the context-graph pyramid
That 100% coverage is not full-text search. Concho compiles the codebase into a context-graph pyramid: deterministic hard facts at the base, each layer synthesized and handed to an inference model that asks what those facts mean together, until the apex is a compact description of the system small enough to fit in a single prompt. An agent enters at any altitude — whole-system architecture or a single line of code — and the same slice can be extracted across an entire portfolio. A similarity index (vector RAG) cannot make that move.
What Happens Next — Automated Code Generation
This report is not the end of the process — it is the input to a companion agentic code generation workflow that turns the architectural guidance, schema decisions, business rule specifications, and UI transformation patterns documented here into runnable implementation artifacts: ASP.NET Core 10 services, EF Core entity models, Angular 20 components, PostgreSQL schemas, Dockerfiles, Bicep IaC templates, and GitHub Actions CI/CD pipelines.
The code generation workflow uses a BDD/TDD iterate-till-green approach, and the tests are generated from the derived business rules: each Given-When-Then specification in the rule catalog becomes an executable test, and the same specs drive the implementation — so the code is validated against the very rules extracted from the legacy system. The workflow runs the suite, and if any test fails it identifies the discrepancy, corrects the artifact, and re-runs until green. An adversarial validation agent runs at every step — the same discipline that produced this report, where each generation step is checked by an independent validator before the next consumes it. A human never reviews a broken artifact. It does not arrive and get polished — it arrives already verified.
The modernized gift-processing experience — five screens
Three legacy jQuery + AngularJS pages (GiftBatches, GiftDetailEntry, MotivationPicker) plus the legacy modal alerts collapse into a single Unified Gift Batch Workspace with five distinguishable interaction surfaces. Each panel below is derived from the storyboard that drove Section 7 — same fields, same business rules, modern interaction. Live multi-currency totals, live period validation, a 0–100 tax-deductible clamp, and a pre-commit GL journal preview were never possible in legacy Petra.
Gift Batches List
Gift Batches — Ledger 43
Status: AllMay 20261 unposted
#
Date
Status
Total
44
19 May
Posted
€8,420
45
20 May
Posted
€1,250
46
21 May
Unposted
€2,460
+ New Gift Batch
Gift Detail Grid
Batch #46 — Pending
Period 5 / May 2026 — open
Donor
Mot.
Amt
Cur
Tax%
Base €
Müller [UNIT]
SUPPORT
500.00
USD
87
454.55
Berger [FAMILY]
SUPPORT
200.00
EUR
100
200.00
Kongo Fund [UNIT/FIELD]
FIELD
1,800.00
EUR
100
1,800.00
Base €2,454.55 · USD memo $2,700
BR-GIFT-003 / 009 / 010 live
Motivation Side-Panel
Motivation — Row 3
Donor: Kongo Mission Fund
Class: UNIT/FIELD
BR-GIFT-011 → GIFT › FIELD