How we built a compliance platform from scratch
The engineering decisions behind CapitalBridge: a portfolio compliance system handling 7 funds, 191+ borrowers, and 27 reporting types across 23 countries.
What DFIs were doing before
Most development finance institutions track compliance in Excel. Covenant thresholds checked manually. Submissions tracked via email. No borrower visibility into what is due, what has been received, or what is overdue.
When you manage a small portfolio of 10 or 15 borrowers, spreadsheets work. An analyst maintains a workbook per fund, tracks due dates in one tab, logs received documents in another, and checks covenant thresholds by hand each quarter. The process is labor-intensive but manageable. The problems begin when the portfolio grows past 50 borrowers across multiple funds, each with different reporting requirements, different covenant thresholds, and different currencies.
At that scale, the spreadsheet workflow creates four specific failure modes that compound over time.
Covenant breaches discovered after the fact
An analyst checks DSCR thresholds during the quarterly review. If a borrower breached two months ago, the lender has lost the intervention window. There is no early warning, no trend tracking, no "at risk" indicator before the actual breach occurs.
No audit trail for regulators
When was a document received? Who approved it? Was it on time or late? In a spreadsheet, the answer is whatever the cell currently says. There is no history. If someone overwrites a date, that information is gone permanently.
Manual FX conversion errors
A borrower in Zambia reports in ZMW. The fund reports in USD. Someone looks up the exchange rate, pastes it into a reference table, and hopes the VLOOKUP still points to the right cell. Rates go stale. Frontier market currencies require specialized data sources.
15-20 hours per week on email chasing
Checking the tracker, identifying overdue items, composing individual reminder emails, following up on follow-ups. Two full-time staff members spending the majority of each quarter on administrative overhead instead of analysis.
A reconstruction of the compliance tracking state before CapitalBridge.
This is the environment we walked into. Seven funds, each with its own spreadsheet ecosystem. No single source of truth. No automated reminders. No borrower-facing portal. No real-time covenant monitoring. The compliance team was spending more time on administrative overhead than on actual portfolio analysis. Something purpose-built was needed.
The cascading rules engine
The single hardest design problem in the entire system. Every reporting requirement and every covenant threshold needs to cascade through four levels of scope. Getting this wrong would mean reconfiguring hundreds of assignments by hand.
Why cascading scope matters
A fund like AATIF has dozens of borrowers spread across multiple sectors (Agriculture, Financial Institutions, Trade Finance) and sub-sectors. Each sector has different reporting needs. Financial Institutions need PAR30 and PAR90 reports. Direct Investment Companies need DSCR calculations. But within those groups, individual borrowers may have negotiated exemptions or additional requirements.
The naive approach is to assign everything individually: for each borrower, specify every reporting requirement and every covenant threshold. With 191 borrowers and 27 reporting types, that is 5,157 individual assignments to configure and maintain. When a fund-level policy changes, someone has to update every single one.
The cascading system solves this. You set defaults at the Fund level (scope 0). Those flow down automatically to every borrower in that fund. If the Agriculture sector needs different requirements, you override at the Sector level (scope 1). That override applies to all borrowers in that sector, but does not affect borrowers in other sectors. Sub-sector overrides (scope 2) work the same way.
At the bottom, individual Borrower assignments (scope 3) have final say. The most specific scope always wins.
Setting IsActive = false
at the Borrower level excludes that borrower from a requirement, even if the Fund, Sector, and SubSector
levels all say it should apply. This is how exemptions work.
Both ReportingRequirementAssignment and CovenantAssignment
use the same cascading scope pattern. The resolution algorithm is identical: collect all
assignments for a given borrower, group by requirement type, pick the one with the highest
scope number (most specific). This means you configure the rules once and both reporting
submissions and covenant monitoring inherit the same hierarchy.
Most specific scope wins. Borrower-level exclusions override everything above.
The hard problems we solved
Beyond the cascading rules engine, four specific technical challenges required careful design. Each one looks simple in isolation but becomes complex when you need it to work across 7 funds, 191 borrowers, and 23 countries.
Multi-currency at scale
CapitalBridge supports 156 currencies, including frontier market currencies that most FX data providers do not cover well: Zambian Kwacha (ZMW), Mozambican Metical (MZN), Rwandan Franc (RWF), Sierra Leonean Leone (SLE), Eswatini Lilangeni (SZL). These are not exotic edge cases. They are the primary operating currencies of borrowers in the portfolio.
The system syncs both spot rates and forward rates daily via a Hangfire background job. Every financial figure submitted by a borrower is stored in its original local currency. When a fund manager views the portfolio dashboard, all values are converted to the fund's base currency (typically USD or EUR) using the rate that was current on the submission date. Covenant thresholds are evaluated in the borrower's local currency, then the results are presented in the fund's reporting currency for aggregated views.
This dual-currency approach is critical. A covenant threshold of ZMW 5,000,000 means something specific in Zambian Kwacha. Converting that threshold to USD for evaluation would introduce FX risk into the compliance calculation itself. The system keeps thresholds in local currency, evaluates compliance locally, and only converts for reporting purposes.
27 reporting types, not a generic document tracker
A common mistake in compliance software is treating all documents the same: upload a file, attach it to a borrower, mark it as received. That approach ignores the reality of development finance reporting, where each document type has its own frequency pattern, due date calculation, assignment rules, and validation requirements.
Annual Financial Statements (AFS) are due once per year, typically 90 to 180 days after fiscal year-end. Quarterly Management Accounts (QMA) are due every quarter, within 45 days. Portfolio at Risk 30 (PAR30) is a monthly metric specific to financial institution borrowers. Environmental and Social Action Plans (ESAP) have their own cadence. Each type was seeded into the system with its default frequency, due date offset, and applicable borrower categories.
The system distinguishes between two fundamentally different submission types. A ReportingSubmission is a document upload: the borrower uploads a PDF or Excel file. A FormSubmission is structured data entry: the borrower fills in financial metrics through a Blazor-powered form with field-level validation. Both types share the same status workflow (Pending, Submitted, Approved, Rejected, ReworkRequired) but serve different purposes.
A daily Hangfire job (CreatePendingReportingSubmissionsJob) looks 90 days ahead and automatically creates pending submissions for every active assignment. When a new borrower is added to a fund, the cascading rules engine resolves their requirements, and the job creates their pending submissions on the next run. No manual setup needed.
Real-time covenant health
The covenant monitoring engine uses a three-state calculation model. A simple compliant/breached binary is not enough for proactive risk management. The three states are:
Compliant. The metric is within the threshold with adequate headroom. No action needed, no risk flags.
AtRisk. The metric is still within the threshold, but headroom has fallen below the configured warning percentage. The borrower is technically compliant but trending toward trouble. This is where intervention is most effective.
NonCompliant. The metric has crossed the threshold. A breach has occurred. Immediate attention required.
Each covenant assignment stores the threshold value, the comparison operator (>=, <=, >, <), and a headroom percentage. The operator matters: a DSCR covenant requires the value to be greater than or equal to the threshold (e.g., DSCR >= 1.20x). An LTV covenant requires the value to be less than or equal to the threshold (e.g., LTV <= 75%). Getting the operator wrong would invert the compliance logic entirely.
Headroom is calculated as the percentage distance between the current value and the threshold. A DSCR of 1.35x against a 1.25x threshold has 8% headroom. If the headroom warning is set to 10%, this borrower would be flagged as AtRisk even though they are technically above the threshold. That early warning gives the fund manager weeks or months to engage with the borrower before an actual breach occurs.
7-tier automated escalation
Before CapitalBridge, the compliance team spent 15 to 20 hours per week composing and sending reminder emails to borrowers. Each email was written individually. Follow-up threads got buried in inboxes. When the person responsible for reminders was on leave, the process stopped entirely.
The escalation engine replaces all of this with a configurable 7-tier notification system. Each tier has its own timing (relative to the submission due date), its own email template, and its own recipient list. The first tier is a gentle reminder sent 7 days before the due date. The final tier is a management escalation sent 30 days after the deadline, copying senior stakeholders on both sides.
A Hangfire background job runs daily, evaluates every pending submission against the escalation schedule, and sends the appropriate notification for the current tier. If a borrower submits before the due date, no further reminders are sent. If they submit after tier 3 but before tier 4, the remaining tiers are cancelled. The system tracks which tiers have been sent and when, creating a complete audit trail of the reminder process.
The recipient list expands as escalation progresses. Early tiers go to the borrower's primary contact. Mid-tier reminders copy the borrower's CFO or compliance officer. Late-tier escalations include the fund manager and the relationship manager on the lender side. Each tier is configurable per fund, so different funds can have different escalation cadences based on their borrower relationships.
The technology behind it
We chose ASP.NET Boilerplate (ABP) for its built-in multi-tenancy, audit logging, and permission system. In a fund management context, these are not nice-to-haves. Multi-tenancy means each fund operates with proper data isolation. Audit logging means every change to every record is tracked with the user, timestamp, and previous value. The permission system provides granular role-based access control: Fund Admins see everything across their funds, Analysts see their assigned portfolios, and Borrowers see only their own data.
Blazor handles the form submission data entry. Financial forms with 50+ fields, conditional validation rules, and currency-aware input masks are complex to build in traditional Razor Pages. Blazor's component model lets us compose form sections, validate on the fly, and provide a responsive editing experience without full page reloads. The rest of the application (dashboards, grids, document management, settings) is standard Razor Pages with Telerik Kendo UI components.
Hangfire runs three categories of daily jobs. First, the submission scheduling job that looks 90 days ahead and creates pending submissions based on active assignments. Second, the escalation engine that evaluates every pending or overdue submission against the 7-tier notification schedule. Third, the FX sync job that pulls spot and forward rates for all 156 currencies. These jobs run on their own schedule, are retry-safe, and produce detailed logs that the operations team can monitor through the Hangfire dashboard.
Not a prototype
This is not a prototype, a demo environment, or a proof of concept. CapitalBridge runs real fund operations for Cygnum Capital every day. Borrowers log in to their portal to check deadlines and upload documents. The escalation engine sends reminder emails automatically. Covenant thresholds are evaluated on every form submission. Currency rates update every morning before the team starts work.
The implementation timeline was 4 weeks from kickoff to live submissions. Week 1 covered fund structure, sector hierarchies, and reporting requirement configuration. Week 2 was borrower data import and covenant threshold setup. Week 3 was borrower portal deployment and user onboarding. Week 4 was the first live submission cycle. The system has been running in production since then, processing submissions, monitoring covenants, and sending automated reminders every day.
What this means for you
We built CapitalBridge because we saw a gap in the market. Development finance institutions and private debt fund managers were running critical compliance workflows on spreadsheets, and the available software either targeted the wrong market (hedge funds, private equity) or was too generic to handle the specific requirements of DFI lending: cascading assignment rules, multi-currency covenant calculations, borrower self-service portals, and multi-tier escalation workflows.
But the engineering capabilities CapitalBridge required are not unique to fund compliance. The cascading rules engine is a pattern that applies to any hierarchical policy system. The multi-currency calculation layer works for any cross-border financial application. The automated escalation engine works for any workflow where deadlines matter and follow-ups need to happen without human intervention. The counterparty portal pattern works for any multi-party data collection process.
Proceptio is a software development team. We build data infrastructure for institutional clients. Our portfolio includes work for IKEA and Baillie Gifford. CapitalBridge is one product we have built from the ground up, and it demonstrates what we are capable of: taking a complex operational workflow, understanding the domain deeply, designing the data model and rule systems correctly, and delivering production-grade software that runs reliably every day.
If your organization has operational workflows running on spreadsheets, legacy systems, or internal tools that need replacing, this is the kind of thing we build. Complex data models. Rule engines. Multi-party portals. Automated workflows. Enterprise security. If the problem involves structured data, business rules, and multiple stakeholders, we have almost certainly solved something similar.