Skip to main content

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

FileResponsibility
budgetForecastingService.tsTime-aware burn-rate forecasting and actionable insights
budgetAlerts.tsPer-budget-line alert checking, creation, and notification dispatch
budgetCategories.tsBudget category CRUD and default category seeding
receiptStorage.tsFirebase 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()
}

Burn Rate Formula

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:
  1. Creates a BudgetAlert document if the threshold is crossed for the first time.
  2. Calls notifyBudgetThresholdReached() from shared/notifications to dispatch an in-app notification.
  3. 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:
IDNameAlert Threshold
cat-personnelPersonnel80%
cat-operationsOperations85%
cat-travelTravel & Events90%
cat-equipmentEquipment85%
cat-consultancyConsultancy80%
cat-overheadOverhead90%

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

CallerUses
src/features/projects/generateForecast(), checkBudgetAlerts(), getBudgetCategories()
src/features/expenses/uploadReceipt(), deleteReceipt(), checkBudgetAlerts()
src/extensions/budget-forecaster/generateForecast(), generateActionableInsights() — scenario modelling widget
Firebase Cloud FunctionscheckBudgetAlerts() — nightly batch alert sweep