import { SmrtObjectOptions } from '@happyvertical/smrt-core'; import { SmrtJobCollection } from '@happyvertical/smrt-jobs'; import { SupportCase } from '../models/support-case.js'; import { SupportInteraction } from '../models/support-interaction.js'; import { SupportEscalationCollection, SupportServiceTarget, SupportServiceTargetCollection } from '../models/support-service-target.js'; import { EscalationStep, ServiceTargetMinutes, SupportCaseStatus } from '../types.js'; import { CoverageCalendar } from './coverage-calendar.js'; import { SupportCaseService } from './support-case-service.js'; /** Queue name for support escalation jobs. */ export declare const SUPPORT_JOB_QUEUE = "support"; /** Priority for escalation jobs (`high` — breaches are time-critical). */ export declare const ESCALATION_JOB_PRIORITY = 75; /** Severity assumed when a case has not been assigned one yet. */ export declare const DEFAULT_SEVERITY_KEY = "sev3"; /** The plan terms a case's clocks run against (snapshot-first). */ export interface ResolvedTargetPlanTerms { calendar: CoverageCalendar; pauseStatuses: string[]; escalationPolicy: EscalationStep[]; targetsForSeverity(severity: string): ServiceTargetMinutes; } /** Options for {@link ServiceTargetEngine.create}. */ export interface ServiceTargetEngineOptions extends SmrtObjectOptions { /** Share an existing case service (and its collections) with the engine. */ caseService?: SupportCaseService; /** * Whether to enqueue real `_smrt_jobs` escalation rows (default `true`). * Disable only where a jobs table is unavailable by design. */ scheduleJobs?: boolean; } /** * The clock engine. Construct with {@link ServiceTargetEngine.create}. */ export declare class ServiceTargetEngine { readonly caseService: SupportCaseService; readonly targets: SupportServiceTargetCollection; readonly escalations: SupportEscalationCollection; readonly jobs: SmrtJobCollection; readonly scheduleJobs: boolean; private readonly options; private routing?; protected constructor(deps: { options: SmrtObjectOptions; caseService: SupportCaseService; targets: SupportServiceTargetCollection; escalations: SupportEscalationCollection; jobs: SmrtJobCollection; scheduleJobs: boolean; }); static create(options: ServiceTargetEngineOptions): Promise; private resolveCase; private requireId; private getRoutingService; /** * Resolve the plan terms governing a case's clocks: the frozen * `planSnapshot` when present, else the loaded plan, else conservative * defaults (24×7 calendar, default target minutes, pause on * `waiting_on_client`, empty escalation policy). */ resolvePlanTerms(supportCase: SupportCase): Promise; /** * Start the case's Service Target clocks (idempotent: target types that * already have an active clock are skipped). One clock per non-null * configured minutes for the case severity — the `update` clock only when * the plan configures `updateMinutes`. A first start creates cycle 0; * starting again after clocks settled (e.g. a reopen) creates the next * cycle, preserving the settled rows. */ startTargetsForCase(caseRef: SupportCase | string, opts?: { at?: Date; }): Promise; private startTargets; private startTarget; /** * Enqueue the one-shot escalation job for a clock at `runAt` and record * its id on the target (`escalationJobId`) so satisfying can cancel it. */ private scheduleEscalationJob; /** * Cancel a clock's pending escalation job, tolerating jobs that already * ran, were cancelled, or are missing (at-least-once semantics). */ private cancelEscalationJob; /** * React to a recorded interaction. Outbound specialist/agent interactions * satisfy the acknowledgement clock (first outbound of any kind), the * response clock (first substantive outbound — the same trigger), and the * active update-cycle clock (which then restarts at the next cycle from * the interaction instant). Inbound client interactions never satisfy * clocks. */ onInteractionRecorded(caseRef: SupportCase | string, interaction: SupportInteraction): Promise; private satisfyTarget; /** * React to a case lifecycle transition: * - to `resolved` — satisfy the resolution clock, cancel every other * active clock (and its job); * - to `closed` — cancel all remaining active clocks; * - reopen (`resolved`/`closed` → an open status) — start fresh clocks on * the next cycle for every type; * - entering a plan pause status — freeze pending clocks (FR-29b: only * when the plan says so); * - leaving a pause status — resume paused clocks with `dueAt` recomputed * from the remaining covered minutes and a fresh escalation job. */ onCaseTransition(caseRef: SupportCase | string, from: SupportCaseStatus, to: SupportCaseStatus, opts?: { at?: Date; }): Promise; private settleTargetsForTerminal; private pauseTargets; private resumeTargets; /** * Escalate a breached clock through the plan's escalation policy: write * the {@link SupportEscalation} audit row, apply the step action * (`notify` records the profiles to notify; `reassign` routes to the next * eligible specialist, excluding the current assignee), bump the case * escalation level, transition the case to `escalated` (unless already * resolved/closed), and schedule the next policy step when it declares a * `delayMinutes`. */ escalateForBreach(target: SupportServiceTarget, opts?: { at?: Date; }): Promise; /** * Continue a delayed escalation on an already-breached clock: consumes the * pending-level marker and escalates the next policy step, unless the case * has since left its open states. */ continueEscalation(target: SupportServiceTarget, at: Date): Promise; } export default ServiceTargetEngine; //# sourceMappingURL=service-target-engine.d.ts.map