225 lines
5.4 KiB
Markdown
225 lines
5.4 KiB
Markdown
# 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
|
|
|
|
```typescript
|
|
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
|
|
|
|
```typescript
|
|
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
|
|
|
|
```typescript
|
|
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
|
|
|
|
```typescript
|
|
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**
|
|
|
|
```typescript
|
|
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**
|
|
|
|
```typescript
|
|
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
|
|
|
|
```typescript
|
|
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:
|
|
|
|
```typescript
|
|
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:
|
|
|
|
```bash
|
|
# Logging
|
|
LOG_LEVEL=info # Minimum log level
|
|
NODE_ENV=production # Environment mode
|
|
|
|
# Metrics
|
|
METRICS_ENABLED=true # Enable Prometheus metrics
|
|
```
|
|
|
|
## Related Documentation
|
|
|
|
- [Backend Overview](../index.md)
|
|
- [Observability](../../features/observability/index.md)
|
|
- [Security](../../deployment/security.md)
|
|
- [Map Features](../../features/map/index.md)
|
|
- [Monitoring Stack](../../deployment/monitoring-stack.md)
|