Documentation Index
Fetch the complete documentation index at: https://grantmaster.dev/llms.txt
Use this file to discover all available pages before exploring further.
shared/budget — API Reference
The shared/budget module provides budget forecasting, alert management, category definitions, and receipt storage for the project budget system. It is consumed primarily by src/features/projects/ and src/features/expenses/.
Module Map
| File | Responsibility |
|---|
budgetForecastingService.ts | Time-aware burn-rate forecasting and actionable insights |
budgetAlerts.ts | Per-budget-line alert checking, creation, and notification dispatch |
budgetCategories.ts | Budget category CRUD and default category seeding |
receiptStorage.ts | Firebase Storage upload/download/delete for expense receipts |
budgetForecastingService
Generates forward-looking budget forecasts for projects and individual budget lines.
generateForecast()
import { generateForecast } from '@/shared/budget/budgetForecastingService';
const forecast = await generateForecast(
project, // LegacyProject — provides dates, totals, budget lines
budgetLine?, // Optional: scope forecast to a single budget line
journalEntries? // Optional: JournalEntry[] for monetary spend calculation
);
Returns BudgetForecast:
interface BudgetForecast {
allocatedBudget: number;
currentSpent: number;
remainingBudget: number;
burnRate: number; // per day
projectedSpend: number; // at project end date
projectedOverrun: number; // projectedSpend - allocatedBudget (0 if under)
percentSpent: number; // 0–100
daysElapsed: number;
daysRemaining: number;
totalProjectDays: number;
onTrack: boolean; // false if projectedSpend > allocatedBudget
insights: BudgetInsight[]; // see generateActionableInsights()
}
burnRate = currentSpent / daysElapsed (EUR or hours per day)
projectedSpend = currentSpent + (burnRate × daysRemaining)
When journalEntries are provided and the project has a monetary budget, spent amount is recalculated from actual timesheet records using user billing rates.
generateActionableInsights()
import { generateActionableInsights } from '@/shared/budget/budgetForecastingService';
const insights = generateActionableInsights(forecast, project);
Returns an array of BudgetInsight objects with type (warning | critical | info), a human-readable message, and a suggested action. Examples:
- “Project is on track to overspend by 23% — consider reducing scope”
- “80% of budget spent with 60% of time elapsed — monitor closely”
- “Only 5 days remaining with 30% budget unspent — accelerate activity”
budgetAlerts
Checks configured alert thresholds per budget line and creates or updates BudgetAlert documents.
checkBudgetAlerts()
import { checkBudgetAlerts } from '@/shared/budget/budgetAlerts';
const alerts = await checkBudgetAlerts(project);
Iterates each budget line on the project. For lines that have both maxLimit and alertThreshold configured, calculates spentPercentage and:
- Creates a
BudgetAlert document if the threshold is crossed for the first time.
- Calls
notifyBudgetThresholdReached() from shared/notifications to dispatch an in-app notification.
- Returns the full list of active alerts for the project.
Alert Types (BudgetAlertType): WARNING (approaching threshold), CRITICAL (at or over limit), RESOLVED (spent dropped back below threshold).
Firestore collection: budgetAlerts/{alertId}.
Other Methods
getBudgetAlerts(projectId): Promise<BudgetAlert[]>
resolveBudgetAlert(alertId): Promise<void>
clearResolvedAlerts(projectId): Promise<void>
budgetCategories
Manages the taxonomy of budget categories used when creating budget lines.
Key Methods
import {
DEFAULT_BUDGET_CATEGORIES,
getBudgetCategories,
createBudgetCategory,
updateBudgetCategory,
deactivateBudgetCategory,
seedDefaultCategories,
} from '@/shared/budget/budgetCategories';
DEFAULT_BUDGET_CATEGORIES
Seeded for every new organisation:
| ID | Name | Alert Threshold |
|---|
cat-personnel | Personnel | 80% |
cat-operations | Operations | 85% |
cat-travel | Travel & Events | 90% |
cat-equipment | Equipment | 85% |
cat-consultancy | Consultancy | 80% |
cat-overhead | Overhead | 90% |
BudgetCategory Schema
interface BudgetCategory {
id: string;
name: string;
description: string;
isActive: boolean;
colorCode: string; // hex, used in UI
defaultAlertThreshold: number; // 0–100
}
Firestore collection: organizations/{orgId}/budgetCategories/{categoryId}.
receiptStorage
Handles Firebase Storage operations for expense receipts and supporting documents.
import {
uploadReceipt,
getReceiptDownloadUrl,
deleteReceipt,
listOrgReceipts,
} from '@/shared/budget/receiptStorage';
// Upload
const { path, downloadUrl } = await uploadReceipt(orgId, expenseId, file);
// Retrieve
const url = await getReceiptDownloadUrl(path);
// Delete
await deleteReceipt(path);
Storage paths: organizations/{orgId}/receipts/{expenseId}/{filename}
Calls validateFileUpload() from shared/billing/storageQuotaHelper before uploading, and incrementStorageUsage() / decrementStorageUsage() after upload/delete to keep quota counters accurate.
EventBus Events
This module emits no EventBus events directly. Budget threshold crossings are communicated via shared/notifications (in-app notification dispatch) rather than the EventBus. The projects feature service emits BUDGET_THRESHOLD_80, BUDGET_THRESHOLD_90, and BUDGET_THRESHOLD_EXCEEDED events at a higher level when processing project budget updates.
Callers
| Caller | Uses |
|---|
src/features/projects/ | generateForecast(), checkBudgetAlerts(), getBudgetCategories() |
src/features/expenses/ | uploadReceipt(), deleteReceipt(), checkBudgetAlerts() |
src/extensions/budget-forecaster/ | generateForecast(), generateActionableInsights() — scenario modelling widget |
| Firebase Cloud Functions | checkBudgetAlerts() — nightly batch alert sweep |