Reserve Fund — Monthly Contribution Field
Reserve Fund — Monthly Contribution Field
The monthly contribution is the primary income variable in the reserve fund's year-by-year projection calculation. This field determines how much is added to the reserve fund each month and directly drives funding gap alerts and scenario projections.
Overview
Every reserve fund account has a Monthly Contribution that can be sourced in one of two ways:
| Source | Description |
|---|---|
| Manual | A fixed amount entered directly by an admin. Stays constant until changed. |
| Budget-Linked | Automatically derived from the block's service charge budget: annual reserve_fund line item ÷ 12. Updates when you refresh. |
The current source is shown as a badge on both the Monthly Contribution Card and the account stats card.
Monthly Contribution Card
The Monthly Contribution Card appears on the reserve fund account detail page. It shows:
- The current monthly amount and its annual equivalent
- A Manual or Budget-Linked source badge
- When budget-linked: the budget name, financial year, status, and annual reserve fund line amount
- Projection impact: if a funding gap exists, the card shows how many months it will take to close it at the current contribution rate. If contributions are zero, a warning is displayed.
Setting a Manual Contribution
- Open the reserve fund account detail page.
- In the Monthly Contribution Card, click Set Manually.
- Enter the monthly amount in pounds (e.g.
250.00). - The annual equivalent is shown inline as a preview.
- Click Save Contribution.
If the account was previously budget-linked, saving a manual amount will unlink the budget and switch the source to Manual.
Permission required: Admin role.
Linking to a Service Charge Budget
Linking derives the monthly contribution automatically from the block's service charge budget:
monthly contribution = annual reserve_fund line item ÷ 12
Steps
- Open the reserve fund account detail page.
- In the Monthly Contribution Card, click Link to Budget.
- A dropdown lists all budgets for the block. Each entry shows the budget name, financial year, status, and the reserve fund line amount (if any).
- Budgets with no
reserve_fundline item are shown but cannot be selected.
- Budgets with no
- Select a budget. A preview shows the resulting monthly contribution.
- Click Link Budget to confirm.
The contribution is immediately updated and all projections and gap alerts are recalculated.
Requirement: The selected budget must belong to the same block as the reserve fund account and must contain at least one
reserve_fundcategory line item.
Refreshing from a Budget
When a linked budget is edited (e.g. the reserve fund allocation is changed), the reserve fund contribution is not updated automatically. Use Refresh from Budget to pull in the latest value.
- In the Monthly Contribution Card, click Refresh from Budget.
- The system recalculates
annual reserve_fund line ÷ 12from the current budget data. - A success toast confirms whether the value changed or was already up to date.
Unlinking a Budget
To stop automatic derivation and return to manual control:
- In the Monthly Contribution Card, click Unlink Budget.
- Confirm the prompt.
The current contribution amount is preserved — only the source tracking changes from "budget" to "manual". You can then adjust the amount manually.
Projection Impact
The Monthly Contribution Card displays a funding gap projection when the account's current balance is below its target:
- If contributions are set: shows the number of months to close the gap at the current rate.
- If contributions are zero: shows a warning that the gap will not close.
This is a simplified projection (linear, no inflation uplift). Full scenario projections including inflation uplift are available via the Projections section.
API Reference
All endpoints are under the reserveFund router and require authentication. Mutations require admin role.
reserveFund.getContributionSummary
Type: Query
Input:
{ accountId: string }
Returns:
{
accountId: string;
blockId: string;
blockName: string;
accountName: string;
monthlyContributionPence: number;
annualContributionPence: number;
contributionSource: "manual" | "budget";
linkedBudgetId: string | null;
linkedBudget: {
id: string;
name: string;
financialYear: number;
status: string;
totalAmountPence: number;
reserveFundLineAmountPence: number;
} | null;
availableBudgets: Array<{
id: string;
name: string;
financialYear: number;
status: string;
totalAmountPence: number;
reserveFundLineAmountPence: number;
derivedMonthlyContributionPence: number;
}>;
currentBalancePence: number;
targetBalancePence: number;
fundingGapPence: number;
monthsToTarget: number | null; // null if no contributions set
}
reserveFund.updateContribution
Type: Mutation (Admin)
Manually set the monthly contribution. Sets contributionSource to "manual" and clears any budget link.
Input:
{
accountId: string;
monthlyContributionPence: number; // non-negative integer
}
Returns:
{
monthlyContributionPence: number;
previousMonthlyContributionPence: number;
annualContributionPence: number;
contributionSource: "manual";
}
reserveFund.linkBudget
Type: Mutation (Admin)
Link contribution to a service charge budget. Monthly contribution is set to annual reserve_fund line ÷ 12.
Input:
{
accountId: string;
budgetId: string;
}
Errors:
NOT_FOUND— Budget does not exist or does not belong to this organisation.BAD_REQUEST— Budget belongs to a different block, or has noreserve_fundline items.
Returns:
{
monthlyContributionPence: number;
previousMonthlyContributionPence: number;
annualContributionPence: number;
annualReserveFundPence: number;
contributionSource: "budget";
linkedBudgetId: string;
budgetName: string;
budgetFinancialYear: number;
}
reserveFund.unlinkBudget
Type: Mutation (Admin)
Remove the budget link. Current contribution amount is preserved; source reverts to "manual".
Input:
{ accountId: string }
Returns:
{
monthlyContributionPence: number;
contributionSource: "manual";
}
reserveFund.refreshContributionFromBudget
Type: Mutation (Admin)
Recalculate the contribution from the linked budget's current reserve fund line items.
Input:
{ accountId: string }
Errors:
BAD_REQUEST— Account is not currently budget-linked.
Returns:
{
monthlyContributionPence: number;
previousMonthlyContributionPence: number;
changed: boolean;
annualReserveFundPence: number;
}
Audit Trail
Every contribution change is recorded in the audit log.
| Audit Action | Trigger |
|---|---|
reserve_fund.contribution_updated | Manual amount update |
reserve_fund.contribution_linked_to_budget | Budget linked |
reserve_fund.contribution_unlinked_from_budget | Budget unlinked |
reserve_fund.contribution_refreshed_from_budget | Refresh from budget (only logged when value changes) |
All entries include previous and new values, source types, and budget identifiers where applicable.
Database Schema
Two columns were added to the reserve_fund_accounts table:
contribution_source TEXT DEFAULT 'manual'
linked_budget_id TEXT DEFAULT NULL
contribution_source:"manual"or"budget". Defaults to"manual"for all existing and new accounts.linked_budget_id: Foreign reference to the linked service charge budget.NULLwhen source is"manual".