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/widgets — API Reference

The shared/widgets module contains data services that back the dashboard widget system. Currently it holds one service: grantPipelineService, which computes pipeline metrics and revenue forecasts for the grant application pipeline widget.

Module Map

FileResponsibility
grantPipelineService.tsPipeline stage aggregation, success rate calculation, quarterly revenue forecast

grantPipelineService

getPipelineMetrics()

import { getPipelineMetrics } from '@/shared/widgets/grantPipelineService';

const metrics = await getPipelineMetrics(organizationId);
Returns a PipelineMetrics object containing per-stage counts and values, overall pending totals, expected revenue, the organisation’s average success rate, and a quarterly forecast.

PipelineMetrics

interface PipelineMetrics {
  stages: GrantPipelineStage[];
  totalPending: number;          // submitted + under_review application count
  totalPendingValue: number;     // EUR value of pending applications
  expectedRevenue: number;       // totalPendingValue × (successRate / 100)
  averageSuccessRate: number;    // awarded / (awarded + rejected) × 100
  quarterlyForecast: QuarterlyForecast[];
}

GrantPipelineStage

interface GrantPipelineStage {
  stage: 'draft' | 'submitted' | 'under_review' | 'awarded' | 'rejected';
  count: number;
  totalValue: number;
  averageValue: number;
}

QuarterlyForecast

interface QuarterlyForecast {
  quarter: string;          // e.g. "Q2 2026"
  expectedAwards: number;
  expectedRevenue: number;  // EUR
  confidence: number;       // 0–100
}

Implementation Status

Note: The current implementation returns mock data for demonstration purposes. The production implementation should query the grantApplications Firestore collection filtered by organizationId and aggregate by status.
The intended production query pattern:
const q = query(
  collection(db, 'grantApplications'),
  where('organizationId', '==', organizationId),
  where('status', 'in', ['draft', 'submitted', 'under_review', 'awarded', 'rejected'])
);
const snapshot = await getDocs(q);
// aggregate by status...

Success Rate Formula

successRate = awarded / (awarded + rejected) × 100
expectedRevenue = totalPendingValue × (successRate / 100)
Only decided applications (awarded or rejected) contribute to the success rate; draft and under-review applications are excluded from the denominator.

EventBus Events

This module emits no EventBus events. It is a read-only analytics service.

Callers

CallerUses
src/features/dashboard/Grant pipeline dashboard widget
src/features/grants/Pipeline summary views

Extending the Widget Service Layer

When adding new dashboard widgets that require aggregated data queries, follow the same pattern:
  1. Create a new [domain]WidgetService.ts in src/shared/widgets/.
  2. Export the service function(s) from src/shared/widgets/index.ts.
  3. Keep the service read-only — widget services should never write to Firestore.
  4. Mock the implementation first; replace with live Firestore queries before production.
  5. Cache expensive aggregations in organizations/{orgId}/widgetCache/ if queries are slow.