import { SmrtObjectOptions } from '@happyvertical/smrt-core'; import { SupportCase, SupportCaseCollection } from '../models/support-case.js'; import { SupportCaseEvent, SupportCaseEventCollection } from '../models/support-case-event.js'; import { SupportInteraction, SupportInteractionCollection } from '../models/support-interaction.js'; import { SupportPlan, SupportPlanCollection } from '../models/support-plan.js'; import { SupportWorkLink, SupportWorkLinkCollection } from '../models/support-work-link.js'; import { SupportActorKind, SupportCaseEventType, SupportCaseStatus, SupportChannelKind, SupportInteractionDirection, SupportWorkLinkKind } from '../types.js'; export interface OpenCaseInput { tenantId?: string | null; subject: string; description?: string; priority?: string; severity?: string; channelKind?: SupportChannelKind | ''; clientProfileId?: string | null; openedByProfileId?: string | null; projectId?: string | null; bindingId?: string | null; threadKey?: string; planId?: string | null; preferredSpecialistId?: string | null; metadata?: Record; } export interface RecordInteractionInput { direction: SupportInteractionDirection; channelKind: SupportChannelKind; actorKind: SupportActorKind; authorProfileId?: string | null; body: string; occurredAt?: Date; sourceType?: string | null; sourceId?: string | null; /** Idempotency key; generated (`manual:`) when omitted. */ sourceKey?: string; /** RFC 822 Message-ID for email interactions (keyed reply threading). */ rfcMessageId?: string; metadata?: Record; } export interface CaseActor { actorKind: SupportActorKind; actorProfileId?: string | null; } export interface CaseTimelineItem { kind: 'interaction' | 'event'; occurredAt: Date; interaction?: SupportInteraction; event?: SupportCaseEvent; } /** * The write facade. Construct with {@link SupportCaseService.create}. */ export declare class SupportCaseService { readonly cases: SupportCaseCollection; readonly interactions: SupportInteractionCollection; readonly events: SupportCaseEventCollection; readonly workLinks: SupportWorkLinkCollection; readonly plans: SupportPlanCollection; protected constructor(collections: { cases: SupportCaseCollection; interactions: SupportInteractionCollection; events: SupportCaseEventCollection; workLinks: SupportWorkLinkCollection; plans: SupportPlanCollection; }); static create(options: SmrtObjectOptions): Promise; /** Load a case or throw a descriptive error. */ getCase(caseId: string): Promise; /** The persisted id of a saved case (all facade entry points save first). */ private caseIdOf; /** * Open a new Support Case. Applies the plan snapshot when a plan is given * and writes the `created` audit event. */ openCase(input: OpenCaseInput): Promise; /** * Capture the plan terms onto the case (`planSnapshot`) so later plan edits * never rewrite what this case was handled under. A tenant-owned plan only * applies to that tenant's cases (global NULL-tenant template plans apply * anywhere) — a foreign plan would snapshot another tenant's pricing, * approval, and escalation terms. */ applyPlan(supportCase: SupportCase, plan: SupportPlan): Promise; /** * Record a channel interaction on a case (idempotent on `sourceKey`). * Inbound client activity un-parks `waiting_on_client` cases; the first * outbound reply stamps `acknowledgedAt`/`firstRespondedAt`. */ recordInteraction(caseRef: SupportCase | string, input: RecordInteractionInput): Promise; /** Transition a case's lifecycle status (guarded by the model). */ transition(caseRef: SupportCase | string, to: SupportCaseStatus, actor: CaseActor & { reason?: string; }): Promise; /** Assign (or reassign) a case to a specialist. */ assign(caseRef: SupportCase | string, input: CaseActor & { specialistId: string; rationale?: Record; }): Promise; /** Resolve a case with a resolution summary. */ resolve(caseRef: SupportCase | string, input: CaseActor & { summary: string; resolutionKind?: 'automated' | 'human' | 'delivery'; }): Promise; /** Close a resolved case. */ close(caseRef: SupportCase | string, actor: CaseActor & { reason?: string; }): Promise; /** * Reopen a resolved/closed case, preserving the prior resolution in the * reopen event (FR-29b) and bumping `reopenCount`. */ reopen(caseRef: SupportCase | string, actor: CaseActor & { reason?: string; to?: SupportCaseStatus; }): Promise; /** * Record that the Client explicitly requested a human (FR-28b). The actual * handoff (routing + context transfer) is performed by the handoff service; * this stamps the request and its audit event. */ requestHuman(caseRef: SupportCase | string, input: { byProfileId?: string | null; note?: string; }): Promise; /** * Link separately tracked work to the case (Support Work Item or a * Delivery Handoff's Development Work Item). Support keeps the Case as the * canonical client record; the linked item's execution belongs to its * owning domain (FR-29a). */ linkWork(caseRef: SupportCase | string, input: CaseActor & { linkKind: SupportWorkLinkKind; targetType: string; targetId: string; targetLabel?: string; externalUrl?: string; metadata?: Record; }): Promise; /** * Record a status echo reported back from the domain owning a linked work * item (Delivery Operations reports progress; Support never drives it). */ recordWorkStatus(linkId: string, input: { status: string; note?: string; }): Promise; /** Append an audit event to a case. */ recordEvent(caseRef: SupportCase | string, eventType: SupportCaseEventType, input: { actorKind: SupportActorKind; actorProfileId?: string | null; summary: string; payload?: Record; occurredAt?: Date; }): Promise; /** * The merged case timeline: interactions and audit events in one * chronological stream (the queue/detail UI's data shape, and the context * package a Human Handoff transfers). */ getTimeline(caseId: string): Promise; } export default SupportCaseService; //# sourceMappingURL=support-case-service.d.ts.map