/** * ROIDashboardService - Epic 4: ROI Dashboard * * Implements: * - User ROI view with personal metrics * - Stakeholder aggregate view with system-wide metrics * - Automated data refresh and computation * - Export to JSON/CSV (PDF planned for future) */ import type { Database as DatabaseType } from '../db/database-interface.js'; import type { ROIDashboard, ROIMetrics, ExportFormat } from './types.js'; export interface ROIComputeOptions { userId?: string; skillId?: string; startDate?: string; endDate?: string; } /** * Options for the public {@link ROIDashboardService.getDashboard} entrypoint. * Both dates must be provided together (or neither, which defaults to the last 30 days). */ export interface GetDashboardOptions { userId?: string; startDate?: string; endDate?: string; } /** * Strict ISO-8601 / RFC-3339 profile matcher (SMI-4317). Accepts `YYYY-MM-DD` * and `YYYY-MM-DDTHH:MM:SS(.sss)?(Z|[+-]HH:MM)`; rejects RFC-2822, slash * separators, space-as-T, bare date-time without offset, and any trailing * content. Syntactic guard only — calendar validity (e.g., `2026-13-01`) is * caught by the paired `Date.parse` check. Exported for tests/reuse. */ export declare const ISO_8601_STRICT: RegExp; export declare class ROIDashboardService { private repo; private readonly TIME_SAVED_PER_SUCCESS; private readonly VALUE_PER_MINUTE; constructor(db: DatabaseType); /** * Get user ROI dashboard data for a rolling window (last `days` days). * For an explicit ISO-8601 range, use {@link getDashboard}. */ getUserROI(userId: string, days?: number): ROIDashboard['user']; /** * Core per-user ROI computation over an explicit ISO-8601 range. * Shared between {@link getUserROI} (days-based) and {@link getDashboard}. */ private buildUserROI; /** * Get stakeholder aggregate ROI dashboard for a rolling window (last `days` days). * For an explicit ISO-8601 range, use {@link getDashboard}. */ getStakeholderROI(days?: number): ROIDashboard['stakeholder']; /** * Core stakeholder ROI computation over an explicit ISO-8601 range. * Shared between {@link getStakeholderROI} (days-based) and {@link getDashboard}. */ private buildStakeholderROI; /** * Public date-range-aware dashboard entrypoint (SMI-1683 / GitHub #603). * * Behavior: * - Both dates omitted: defaults to the last 30 days ending now. * - Exactly one date provided: throws {@link ValidationError} (the range is ambiguous). * - `startDate >= endDate`: throws {@link ValidationError}. * - `userId` provided: returns `{ user }` with date-filtered per-user metrics. * - `userId` omitted: returns `{ stakeholder }` aggregated over the range. * * @param options.userId Optional — when supplied, returns the per-user dashboard. * @param options.startDate Optional ISO-8601 timestamp; must be paired with `endDate`. * @param options.endDate Optional ISO-8601 timestamp; must be paired with `startDate`. */ getDashboard(options?: GetDashboardOptions): ROIDashboard; /** * Compute and store ROI metrics for a period * This should be run periodically (e.g., daily) to maintain the dashboard */ computeROIMetrics(options?: ROIComputeOptions): ROIMetrics[]; /** * Export ROI dashboard data */ exportROIDashboard(userId: string | null, format: ExportFormat, days?: number): string; /** * Refresh ROI metrics (run this periodically) */ refreshMetrics(): void; private getDateRange; /** * Resolve the range for {@link getDashboard}: default to last 30 days when both * dates are omitted, validate that exactly-one-date was not supplied, and enforce * `startDate < endDate`. */ private resolveDashboardRange; /** * Throw a typed {@link ValidationError} when the supplied range is malformed. * * Validation layers (SMI-4317): * 1. Strict ISO-8601 / RFC-3339 regex — rejects shapes like `2026/01/01`, * `2026-01-01 00:00:00` (space), `Jan 1 2026`, or RFC-2822 that * `Date.parse` would otherwise accept. * 2. `Date.parse` NaN check — catches syntactically valid but semantically * invalid dates (e.g., `2026-13-01`) that the regex cannot detect. * 3. Ordering — rejects when `startDate >= endDate`. */ private assertValidRange; } //# sourceMappingURL=ROIDashboardService.d.ts.map