Backend Utilities¶
Utility modules provide common functionality for spatial calculations, logging, metrics collection, and data processing across the Changemaker Lite platform.
Utility Modules¶
Spatial Utilities¶
spatial.ts (utils/spatial.ts)
Provides geospatial calculations and polygon operations:
Point-in-Polygon - Ray-casting algorithm for polygon containment - Supports GeoJSON polygon format - Handles holes in polygons - Used for cut assignment
import { isPointInPolygon } from '../utils/spatial';
const inside = isPointInPolygon(
{ lat: 43.65, lng: -79.38 },
geoJsonPolygon
);
Haversine Distance - Calculate distance between two coordinates - Returns distance in kilometers - Great-circle distance calculation
import { haversineDistance } from '../utils/spatial';
const distance = haversineDistance(
{ lat: 43.65, lng: -79.38 },
{ lat: 43.66, lng: -79.39 }
);
// Returns: 1.23 (km)
Bounds Calculation - Calculate bounding box for set of locations - Returns min/max lat/lng - Used for map centering
import { calculateBounds } from '../utils/spatial';
const bounds = calculateBounds(locations);
// Returns: { minLat, maxLat, minLng, maxLng }
Centroid Calculation - Calculate center point of locations - Geographic mean of coordinates - Used for map initial center
import { calculateCentroid } from '../utils/spatial';
const center = calculateCentroid(locations);
// Returns: { lat, lng }
GeoJSON Parsing - Parse GeoJSON geometry to coordinate arrays - Support for Polygon and MultiPolygon - Coordinate validation
Logging Utilities¶
logger.ts (utils/logger.ts)
Winston-based logging with multiple transports:
Log Levels
- error - Error conditions
- warn - Warning messages
- info - Informational messages
- http - HTTP request logs
- debug - Debug-level messages
Usage
import logger from '../utils/logger';
logger.info('Campaign created', { campaignId: 123 });
logger.error('Failed to send email', { error: err.message });
logger.debug('Geocoding result', { lat, lng });
Features - JSON formatting for production - Colorized console output for development - File rotation for error logs - Separate error log file - Timestamp on all logs - Request ID tracking
Metrics Utilities¶
metrics.ts (utils/metrics.ts)
Prometheus metrics collection with 12 custom cm_* metrics:
Counter Metrics
- cm_api_uptime_seconds - API uptime counter
- cm_canvass_visits_total - Total canvass visits
- cm_campaign_emails_sent_total - Total campaign emails
- cm_geocode_requests_total - Total geocode requests
Gauge Metrics
- cm_canvass_sessions_active - Active canvass sessions
- cm_email_queue_size - Email queue depth
- cm_geocode_queue_size - Geocode queue depth
- cm_external_service_health - Service health status (0/1)
Histogram Metrics
- cm_geocode_duration_seconds - Geocoding request duration
- http_request_duration_ms - HTTP request duration
Usage
import { metrics } from '../utils/metrics';
// Increment counter
metrics.campaignEmailsSent.inc();
// Set gauge
metrics.emailQueueSize.set(42);
// Observe histogram
const end = metrics.geocodeDuration.startTimer();
await geocode(address);
end();
HTTP Metrics
Automatic tracking of: - Request count by method, route, status - Request duration percentiles - Active requests gauge
Path Validation¶
path-validator.ts (utils/path-validator.ts)
Security utilities for path validation:
Features
- Null byte detection
- Path traversal prevention (../ patterns)
- Encoded traversal detection (%2e%2e)
- Path normalization
import { validatePath } from '../utils/path-validator';
const safe = validatePath(userInput);
if (!safe) {
throw new Error('Invalid path');
}
HTML Sanitization¶
sanitize.ts (utils/sanitize.ts)
XSS prevention utilities:
import { escapeHtml } from '../utils/sanitize';
const safe = escapeHtml(userInput);
// Escapes: < > & " ' to HTML entities
Utility Functions Summary¶
| Utility | Function | Purpose |
|---|---|---|
| Spatial | ||
isPointInPolygon() |
Check if point is inside polygon | |
haversineDistance() |
Calculate distance between points | |
calculateBounds() |
Calculate bounding box | |
calculateCentroid() |
Calculate center point | |
parseGeoJSON() |
Parse GeoJSON to coordinates | |
| Logging | ||
logger.info() |
Log informational message | |
logger.error() |
Log error message | |
logger.debug() |
Log debug message | |
| Metrics | ||
metrics.*.inc() |
Increment counter | |
metrics.*.set() |
Set gauge value | |
metrics.*.startTimer() |
Start histogram timer | |
| Security | ||
validatePath() |
Validate file path safety | |
escapeHtml() |
Sanitize HTML content |
Configuration¶
Utilities are configured via environment variables:
# Logging
LOG_LEVEL=info # Minimum log level
NODE_ENV=production # Environment mode
# Metrics
METRICS_ENABLED=true # Enable Prometheus metrics