@happyvertical/smrt-support 0.51.31 → 0.51.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +146 -15
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +56 -5
- package/dist/migrations/moneyMinorUnits.d.ts +30 -1
- package/dist/models/service-time-entry.d.ts +2 -1
- package/dist/models/support-ai-run.d.ts +15 -3
- package/dist/models/support-ai-run.d.ts.map +1 -1
- package/dist/models/support-case-event.d.ts +11 -1
- package/dist/models/support-case.d.ts +21 -2
- package/dist/models/support-case.d.ts.map +1 -1
- package/dist/models/support-channel-binding.d.ts +11 -1
- package/dist/models/support-compensation-plan.d.ts +11 -0
- package/dist/models/support-interaction.d.ts +12 -1
- package/dist/models/support-plan.d.ts +19 -1
- package/dist/models/support-policy.d.ts +19 -0
- package/dist/models/support-policy.d.ts.map +1 -1
- package/dist/models/support-service-target.d.ts +15 -1
- package/dist/models/support-settlement.d.ts +20 -1
- package/dist/models/support-specialist.d.ts +15 -1
- package/dist/models/support-work-link.d.ts +13 -1
- package/dist/permissions.d.ts +12 -1
- package/dist/services/coverage-calendar.d.ts +22 -1
- package/dist/services/human-handoff-service.d.ts +18 -3
- package/dist/services/project-assistance-adapter.d.ts +2 -2
- package/dist/services/service-target-engine.d.ts +33 -6
- package/dist/services/service-time-entry-service.d.ts +15 -3
- package/dist/services/support-ai-workflow.d.ts +34 -6
- package/dist/services/support-ai-workflow.d.ts.map +1 -1
- package/dist/services/support-case-service.d.ts +15 -7
- package/dist/services/support-intake-service.d.ts +25 -4
- package/dist/services/support-plan-admin-service.d.ts +17 -4
- package/dist/services/support-routing-service.d.ts +19 -4
- package/dist/services/time-entry-approval-service.d.ts +33 -6
- package/dist/smrt-knowledge.json +53 -4
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +11 -11
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* ServiceTimeEntryService — the shared recording contract for Service Time
|
|
3
|
+
* Entries (FR-40, issue #1930): timer, manual, imported, and automatic agent
|
|
4
|
+
* entries all pass ONE validation and audit gate, so no source can smuggle in
|
|
5
|
+
* an incoherent duration, participant, or work context.
|
|
6
|
+
*
|
|
7
|
+
* Recording is deliberately money-free: entries capture the work (duration,
|
|
8
|
+
* period, evidence, participant, context) and land as `draft`; pricing and
|
|
9
|
+
* earnings derive later, at approval time, in `TimeEntryApprovalService`.
|
|
10
|
+
* Case-attached entries append a `time_recorded` audit event so the case
|
|
11
|
+
* timeline shows the work as it happens.
|
|
12
|
+
*/
|
|
13
|
+
import type { SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
14
|
+
import { type ServiceTimeEntry, ServiceTimeEntryCollection } from '../models/service-time-entry.js';
|
|
15
|
+
import type { ServiceTimeEntrySource, SupportParticipantKind, TimeEntryEvidence } from '../types.js';
|
|
4
16
|
import { SupportCaseService } from './support-case-service.js';
|
|
5
17
|
/** Options for {@link ServiceTimeEntryService.create}. */
|
|
6
18
|
export interface ServiceTimeEntryServiceOptions extends SmrtObjectOptions {
|
|
@@ -1,12 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* SupportAiWorkflow — the Automated Support Response pipeline (FR-28a, issue
|
|
3
|
+
* #1928): on intake a case is immediately acknowledged, classified, and
|
|
4
|
+
* answered from scoped knowledge; only when the resolved {@link SupportPolicy}
|
|
5
|
+
* explicitly allows it may the workflow resolve a low-risk case autonomously.
|
|
6
|
+
* Every phase — run or skipped — writes an append-only {@link SupportAiRun}
|
|
7
|
+
* audit row, and every risk signal (client request, low confidence,
|
|
8
|
+
* sensitivity, high severity, boundary failure, attempt cap) routes through
|
|
9
|
+
* {@link HumanHandoffService} so a Support Specialist takes over with the
|
|
10
|
+
* complete context (FR-28b).
|
|
11
|
+
*
|
|
12
|
+
* The AI call is an injected {@link SupportAiBoundary} and knowledge
|
|
13
|
+
* retrieval an injected {@link SupportKnowledgeProvider} (the `smrt-personas`
|
|
14
|
+
* `ReflectionRunner` injected-boundary idiom) — tests mock only these seams,
|
|
15
|
+
* and the package stays dependency-free: apps plug `smrt-facts` /
|
|
16
|
+
* `smrt-content`-backed providers.
|
|
17
|
+
*/
|
|
18
|
+
import type { SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
19
|
+
import { type SupportAiRun, SupportAiRunCollection } from '../models/support-ai-run.js';
|
|
20
|
+
import type { SupportCase } from '../models/support-case.js';
|
|
4
21
|
import { SupportInteractionCollection } from '../models/support-interaction.js';
|
|
5
22
|
import { SupportPolicyCollection } from '../models/support-policy.js';
|
|
6
|
-
import { HumanHandoffTrigger } from '../types.js';
|
|
23
|
+
import { type HumanHandoffTrigger, type SeverityDefinition } from '../types.js';
|
|
7
24
|
import { HumanHandoffService } from './human-handoff-service.js';
|
|
8
25
|
import { SupportCaseService } from './support-case-service.js';
|
|
9
|
-
import { IntakeResult } from './support-intake-service.js';
|
|
26
|
+
import type { IntakeResult } from './support-intake-service.js';
|
|
10
27
|
/** One knowledge source consulted while drafting an automated answer. */
|
|
11
28
|
export interface KnowledgeSnippet {
|
|
12
29
|
/** Source kind, e.g. `fact`, `article`, `document`. */
|
|
@@ -24,10 +41,17 @@ export interface SupportAiClassifyResult {
|
|
|
24
41
|
category: string;
|
|
25
42
|
/** Whether the matter is sensitive (always triggers a Human Handoff). */
|
|
26
43
|
sensitive: boolean;
|
|
27
|
-
/**
|
|
44
|
+
/** Whether a typed decision lacked a unique majority and requires a human. */
|
|
45
|
+
ambiguous?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Classification certainty in `[0, 1]`. Typed decisions use an audit-only
|
|
48
|
+
* operating aggregate; this is never the answer confidence policy consumes.
|
|
49
|
+
*/
|
|
28
50
|
confidence: number;
|
|
29
51
|
/** Model identifier, when the boundary knows it. */
|
|
30
52
|
model?: string;
|
|
53
|
+
/** Additive provenance for an optional typed-decision classification. */
|
|
54
|
+
metadata?: Record<string, unknown>;
|
|
31
55
|
}
|
|
32
56
|
/** Draft answer returned by {@link SupportAiBoundary.answer}. */
|
|
33
57
|
export interface SupportAiAnswerResult {
|
|
@@ -49,6 +73,8 @@ export interface SupportAiBoundary {
|
|
|
49
73
|
subject: string;
|
|
50
74
|
body: string;
|
|
51
75
|
severityKeys: string[];
|
|
76
|
+
severityDefinitions?: Record<string, SeverityDefinition>;
|
|
77
|
+
allowedCategories?: string[];
|
|
52
78
|
sensitiveCategories: string[];
|
|
53
79
|
}): Promise<SupportAiClassifyResult>;
|
|
54
80
|
answer(input: {
|
|
@@ -152,6 +178,8 @@ export declare class SupportAiWorkflow {
|
|
|
152
178
|
private requestBodyOf;
|
|
153
179
|
/** Severity vocabulary: the case's plan snapshot, else the defaults. */
|
|
154
180
|
private severityKeysOf;
|
|
181
|
+
/** Severity vocabulary and definitions from the frozen plan snapshot. */
|
|
182
|
+
private severityDefinitionsOf;
|
|
155
183
|
/** One-line case summary handed to the answer boundary. */
|
|
156
184
|
private caseSummaryOf;
|
|
157
185
|
/** Route a trigger through the handoff engine and notify the app seam. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"support-ai-workflow.d.ts","sourceRoot":"","sources":["../../src/services/support-ai-workflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"support-ai-workflow.d.ts","sourceRoot":"","sources":["../../src/services/support-ai-workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* SupportCaseService — the closed write facade for Support Cases (the
|
|
3
|
+
* `smrt-chat` `ChatService` idiom): case creation, interaction recording,
|
|
4
|
+
* lifecycle transitions, assignment, resolution, reopening, human requests,
|
|
5
|
+
* and work links all flow through here so the audit trail
|
|
6
|
+
* ({@link SupportCaseEvent}) and the lifecycle guard stay coherent. The
|
|
7
|
+
* generated CRUD surface on the case-side models is read-only.
|
|
8
|
+
*/
|
|
9
|
+
import type { SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
10
|
+
import { type SupportCase, SupportCaseCollection } from '../models/support-case.js';
|
|
11
|
+
import { type SupportCaseEvent, SupportCaseEventCollection } from '../models/support-case-event.js';
|
|
12
|
+
import { type SupportInteraction, SupportInteractionCollection } from '../models/support-interaction.js';
|
|
13
|
+
import { type SupportPlan, SupportPlanCollection } from '../models/support-plan.js';
|
|
14
|
+
import { type SupportWorkLink, SupportWorkLinkCollection } from '../models/support-work-link.js';
|
|
15
|
+
import type { SupportActorKind, SupportCaseEventType, SupportCaseStatus, SupportChannelKind, SupportInteractionDirection, SupportWorkLinkKind } from '../types.js';
|
|
8
16
|
export interface OpenCaseInput {
|
|
9
17
|
tenantId?: string | null;
|
|
10
18
|
subject: string;
|
|
@@ -1,7 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* SupportIntakeService — channel intake: every inbound interaction on a bound
|
|
3
|
+
* transport container deterministically creates or joins one canonical
|
|
4
|
+
* Support Case (FR-28, issue #1926).
|
|
5
|
+
*
|
|
6
|
+
* Channels are transports, not systems of record: the ChatMessage / Email row
|
|
7
|
+
* stays canonical in its package; intake links it as a
|
|
8
|
+
* {@link SupportInteraction} (idempotent on `sourceKey`) and drives the
|
|
9
|
+
* create-or-join decision by conversation key:
|
|
10
|
+
*
|
|
11
|
+
* - chat: `chat:<roomId>[:<threadId>]` — a bound room is one client
|
|
12
|
+
* conversation; threads open distinct cases.
|
|
13
|
+
* - email: the RFC thread — a reply (`inReplyTo`) joins the case holding the
|
|
14
|
+
* referenced message; otherwise the message id starts a new thread key.
|
|
15
|
+
*
|
|
16
|
+
* Join semantics: open case → join; resolved case → reopen + join (the client
|
|
17
|
+
* replied to a "resolved" conversation); closed case → a fresh case.
|
|
18
|
+
*
|
|
19
|
+
* Intake never throws into the source package's save path — the opt-in
|
|
20
|
+
* interceptor (`registerSupportIntake`) swallows and logs intake errors.
|
|
21
|
+
*/
|
|
22
|
+
import type { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
23
|
+
import type { SupportCase } from '../models/support-case.js';
|
|
24
|
+
import { type SupportChannelBinding, SupportChannelBindingCollection } from '../models/support-channel-binding.js';
|
|
25
|
+
import type { SupportInteraction } from '../models/support-interaction.js';
|
|
5
26
|
import { SupportCaseService } from './support-case-service.js';
|
|
6
27
|
/** Qualified source types intake understands. */
|
|
7
28
|
export declare const CHAT_MESSAGE_SOURCE_TYPE = "@happyvertical/smrt-chat:ChatMessage";
|
|
@@ -1,7 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* SupportPlanAdminService — the permission-gated write surface for
|
|
3
|
+
* commercial terms: Managed Support Plans (client pricing/service terms) and
|
|
4
|
+
* Support Compensation Plans (provider earning terms).
|
|
5
|
+
*
|
|
6
|
+
* The `support.manage-plans` split is the gate (the
|
|
7
|
+
* `personas.activate-directive` idiom): the generated CRUD routes on both
|
|
8
|
+
* models are read-only, so every plan write flows through here, carries an
|
|
9
|
+
* accountable principal, and refuses cross-tenant acts. Plan history stays
|
|
10
|
+
* safe regardless — cases snapshot plan terms at apply time and settlements
|
|
11
|
+
* snapshot rates at approval time — but only holders of the split may shape
|
|
12
|
+
* future terms.
|
|
13
|
+
*/
|
|
14
|
+
import type { SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
15
|
+
import { type SupportCompensationPlan, SupportCompensationPlanCollection } from '../models/support-compensation-plan.js';
|
|
16
|
+
import { type SupportPlan, SupportPlanCollection } from '../models/support-plan.js';
|
|
17
|
+
import { type SupportPrincipal } from '../permissions.js';
|
|
5
18
|
/** Thrown when a plan write is attempted without the manage-plans split. */
|
|
6
19
|
export declare class PlanAdminDeniedError extends Error {
|
|
7
20
|
constructor(message: string);
|
|
@@ -1,8 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* SupportRoutingService — Project-qualified Support Case routing (FR-30).
|
|
3
|
+
*
|
|
4
|
+
* Ranks Support Specialists for a case with an **explainable** score: every
|
|
5
|
+
* hard eligibility check (active status, effective Project Support
|
|
6
|
+
* Qualification, workload cap, availability) is recorded as a factor on the
|
|
7
|
+
* ranked entry, so the queue UI can show *why* someone was or wasn't chosen.
|
|
8
|
+
* Ineligible specialists stay in the returned ranking (`eligible: false`)
|
|
9
|
+
* for that rationale display.
|
|
10
|
+
*
|
|
11
|
+
* `autoAssign` writes the assignment through {@link SupportCaseService} with
|
|
12
|
+
* the ranking rationale in the audit event; `reassign` is the manual
|
|
13
|
+
* override, gated by the `support.reassign-case` permission split and a
|
|
14
|
+
* cross-tenant guard.
|
|
15
|
+
*/
|
|
16
|
+
import type { SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
17
|
+
import type { SupportCase } from '../models/support-case.js';
|
|
3
18
|
import { SupportAvailabilityCollection, SupportQualificationCollection, SupportSpecialistCollection } from '../models/support-specialist.js';
|
|
4
|
-
import { SupportPrincipal } from '../permissions.js';
|
|
5
|
-
import { SupportActorKind } from '../types.js';
|
|
19
|
+
import { type SupportPrincipal } from '../permissions.js';
|
|
20
|
+
import type { SupportActorKind } from '../types.js';
|
|
6
21
|
import { SupportCaseService } from './support-case-service.js';
|
|
7
22
|
/**
|
|
8
23
|
* Named scoring weights, so the ranking is auditable against the code.
|
|
@@ -1,10 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* TimeEntryApprovalService — the approval gate for Service Time Entries and
|
|
3
|
+
* the ONLY writer of their commercial snapshots (FR-36/FR-32/FR-35, issue
|
|
4
|
+
* #1930).
|
|
5
|
+
*
|
|
6
|
+
* Approval paths come from the governing Managed Support Plan's
|
|
7
|
+
* `timeApprovalPolicy`: `automatic` (no principal needed under the
|
|
8
|
+
* thresholds), `threshold` (an over-threshold automatic entry needs an
|
|
9
|
+
* operator), `operator` (the `support.approve-time-entry` split), and
|
|
10
|
+
* `client` (the case's Client, with the operator split as override).
|
|
11
|
+
*
|
|
12
|
+
* On approval two deliberately separate rows derive per entry:
|
|
13
|
+
*
|
|
14
|
+
* - **SupportCharge** — client side, from the Managed Support Plan only:
|
|
15
|
+
* included time consumes first (per case; period windows arrive with usage
|
|
16
|
+
* pricing #1925), the remainder meters at the overage (or on-call) rate.
|
|
17
|
+
* Rate math uses the CASE's `planSnapshot` when present so later plan edits
|
|
18
|
+
* never change history.
|
|
19
|
+
* - **SupportCompensation** — provider side, from the effective-dated Support
|
|
20
|
+
* Compensation Plan only.
|
|
21
|
+
*
|
|
22
|
+
* Margin (charge − compensation) stays computable by readers and is NEVER
|
|
23
|
+
* stored; case-visible audit events carry the charge amount only, never the
|
|
24
|
+
* compensation. Approved entries freeze (model-enforced); disputes flow
|
|
25
|
+
* through {@link TimeEntryApprovalService.correct}, which supersedes the
|
|
26
|
+
* original and re-derives fresh snapshots from the correcting entry.
|
|
27
|
+
*/
|
|
28
|
+
import type { SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
29
|
+
import { type ServiceTimeEntry, ServiceTimeEntryCollection } from '../models/service-time-entry.js';
|
|
30
|
+
import type { SupportCase } from '../models/support-case.js';
|
|
4
31
|
import { SupportCompensationPlanCollection } from '../models/support-compensation-plan.js';
|
|
5
|
-
import { SupportCharge, SupportChargeCollection, SupportCompensation, SupportCompensationCollection } from '../models/support-settlement.js';
|
|
6
|
-
import { SupportPrincipal } from '../permissions.js';
|
|
7
|
-
import { TimeApprovalPolicy, TimeEntryApprovalPath, TimeEntryEvidence } from '../types.js';
|
|
32
|
+
import { type SupportCharge, SupportChargeCollection, type SupportCompensation, SupportCompensationCollection } from '../models/support-settlement.js';
|
|
33
|
+
import { type SupportPrincipal } from '../permissions.js';
|
|
34
|
+
import type { TimeApprovalPolicy, TimeEntryApprovalPath, TimeEntryEvidence } from '../types.js';
|
|
8
35
|
import { SupportCaseService } from './support-case-service.js';
|
|
9
36
|
/** Thrown when an approval-path or tenant gate refuses the acting principal. */
|
|
10
37
|
export declare class TimeEntryApprovalDeniedError extends Error {
|
package/dist/smrt-knowledge.json
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"sensitiveFieldsExcluded": true,
|
|
4
4
|
"generatedAt": "1970-01-01T00:00:00.000Z",
|
|
5
5
|
"packageName": "@happyvertical/smrt-support",
|
|
6
|
-
"packageVersion": "0.51.
|
|
6
|
+
"packageVersion": "0.51.33",
|
|
7
7
|
"sourceManifestPath": "dist/manifest.json",
|
|
8
8
|
"agentDocPath": "AGENTS.md",
|
|
9
9
|
"sourceHashes": {
|
|
10
|
-
"manifest": "
|
|
11
|
-
"packageJson": "
|
|
10
|
+
"manifest": "1af0eeaf5864a26df69b0d66be551e513e1b4f3cd508c03359b3a15db329446e",
|
|
11
|
+
"packageJson": "9a6b9a7d8aa643c1b2f073eab710d37a761a47e465f23fd672f804ef3a8e4445",
|
|
12
12
|
"agents": "57d75c4e48c549de0e7e50bfc16d739384cd37f4a0c66f0375d1985b24e6cbdd"
|
|
13
13
|
},
|
|
14
14
|
"exports": [
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@types/node": "24.13.6",
|
|
35
35
|
"svelte": "^5.57.1",
|
|
36
36
|
"svelte-check": "^4.7.6",
|
|
37
|
-
"typescript": "
|
|
37
|
+
"typescript": "6.0.3",
|
|
38
38
|
"vite": "8.1.4",
|
|
39
39
|
"vitest": "4.1.10"
|
|
40
40
|
},
|
|
@@ -1368,6 +1368,7 @@
|
|
|
1368
1368
|
}
|
|
1369
1369
|
],
|
|
1370
1370
|
"methods": [
|
|
1371
|
+
"attemptTriageDecision",
|
|
1371
1372
|
"getMetadata",
|
|
1372
1373
|
"getPlanSnapshot",
|
|
1373
1374
|
"initialize",
|
|
@@ -1378,6 +1379,14 @@
|
|
|
1378
1379
|
"updateMetadata"
|
|
1379
1380
|
],
|
|
1380
1381
|
"methodSignatures": [
|
|
1382
|
+
{
|
|
1383
|
+
"name": "attemptTriageDecision",
|
|
1384
|
+
"async": true,
|
|
1385
|
+
"params": [
|
|
1386
|
+
"request: DecisionRequest"
|
|
1387
|
+
],
|
|
1388
|
+
"returns": "Promise<DecisionResult | undefined>"
|
|
1389
|
+
},
|
|
1381
1390
|
{
|
|
1382
1391
|
"name": "getMetadata",
|
|
1383
1392
|
"returns": "Record<string, unknown>"
|
|
@@ -1475,6 +1484,13 @@
|
|
|
1475
1484
|
}
|
|
1476
1485
|
],
|
|
1477
1486
|
"withheldSurfaces": [
|
|
1487
|
+
{
|
|
1488
|
+
"kind": "api",
|
|
1489
|
+
"operation": "attemptTriageDecision",
|
|
1490
|
+
"code": "not-included",
|
|
1491
|
+
"reason": "not listed in api.include",
|
|
1492
|
+
"objectName": "@happyvertical/smrt-support:SupportCase"
|
|
1493
|
+
},
|
|
1478
1494
|
{
|
|
1479
1495
|
"kind": "api",
|
|
1480
1496
|
"operation": "getMetadata",
|
|
@@ -3078,6 +3094,12 @@
|
|
|
3078
3094
|
"required": false,
|
|
3079
3095
|
"columnType": "TEXT"
|
|
3080
3096
|
},
|
|
3097
|
+
{
|
|
3098
|
+
"name": "allowedCategories",
|
|
3099
|
+
"type": "text",
|
|
3100
|
+
"required": false,
|
|
3101
|
+
"columnType": "TEXT"
|
|
3102
|
+
},
|
|
3081
3103
|
{
|
|
3082
3104
|
"name": "allowedTools",
|
|
3083
3105
|
"type": "text",
|
|
@@ -3101,15 +3123,21 @@
|
|
|
3101
3123
|
}
|
|
3102
3124
|
],
|
|
3103
3125
|
"methods": [
|
|
3126
|
+
"getAllowedCategories",
|
|
3104
3127
|
"getAllowedTools",
|
|
3105
3128
|
"getMetadata",
|
|
3106
3129
|
"getSensitiveCategories",
|
|
3107
3130
|
"scopeRank",
|
|
3131
|
+
"setAllowedCategories",
|
|
3108
3132
|
"setAllowedTools",
|
|
3109
3133
|
"setMetadata",
|
|
3110
3134
|
"setSensitiveCategories"
|
|
3111
3135
|
],
|
|
3112
3136
|
"methodSignatures": [
|
|
3137
|
+
{
|
|
3138
|
+
"name": "getAllowedCategories",
|
|
3139
|
+
"returns": "string[]"
|
|
3140
|
+
},
|
|
3113
3141
|
{
|
|
3114
3142
|
"name": "getAllowedTools",
|
|
3115
3143
|
"returns": "string[]"
|
|
@@ -3126,6 +3154,13 @@
|
|
|
3126
3154
|
"name": "scopeRank",
|
|
3127
3155
|
"returns": "number"
|
|
3128
3156
|
},
|
|
3157
|
+
{
|
|
3158
|
+
"name": "setAllowedCategories",
|
|
3159
|
+
"params": [
|
|
3160
|
+
"categories: string[]"
|
|
3161
|
+
],
|
|
3162
|
+
"returns": "void"
|
|
3163
|
+
},
|
|
3129
3164
|
{
|
|
3130
3165
|
"name": "setAllowedTools",
|
|
3131
3166
|
"params": [
|
|
@@ -3224,6 +3259,13 @@
|
|
|
3224
3259
|
}
|
|
3225
3260
|
],
|
|
3226
3261
|
"withheldSurfaces": [
|
|
3262
|
+
{
|
|
3263
|
+
"kind": "api",
|
|
3264
|
+
"operation": "getAllowedCategories",
|
|
3265
|
+
"code": "not-included",
|
|
3266
|
+
"reason": "not listed in api.include",
|
|
3267
|
+
"objectName": "@happyvertical/smrt-support:SupportPolicy"
|
|
3268
|
+
},
|
|
3227
3269
|
{
|
|
3228
3270
|
"kind": "api",
|
|
3229
3271
|
"operation": "getAllowedTools",
|
|
@@ -3252,6 +3294,13 @@
|
|
|
3252
3294
|
"reason": "not listed in api.include",
|
|
3253
3295
|
"objectName": "@happyvertical/smrt-support:SupportPolicy"
|
|
3254
3296
|
},
|
|
3297
|
+
{
|
|
3298
|
+
"kind": "api",
|
|
3299
|
+
"operation": "setAllowedCategories",
|
|
3300
|
+
"code": "not-included",
|
|
3301
|
+
"reason": "not listed in api.include",
|
|
3302
|
+
"objectName": "@happyvertical/smrt-support:SupportPolicy"
|
|
3303
|
+
},
|
|
3255
3304
|
{
|
|
3256
3305
|
"kind": "api",
|
|
3257
3306
|
"operation": "setAllowedTools",
|
package/dist/types.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export type SupportAiRunPhase = 'acknowledge' | 'classify' | 'answer' | 'trouble
|
|
|
45
45
|
/** Terminal outcome of one AI workflow phase run. */
|
|
46
46
|
export type SupportAiRunOutcome = 'completed' | 'skipped' | 'failed' | 'handed_off';
|
|
47
47
|
/** What triggered a Human Handoff (FR-28b). */
|
|
48
|
-
export type HumanHandoffTrigger = 'client_request' | 'low_confidence' | 'high_severity' | 'sensitive' | 'failed_resolution' | 'target_risk' | 'policy' | 'manual';
|
|
48
|
+
export type HumanHandoffTrigger = 'client_request' | 'low_confidence' | 'ambiguous_classification' | 'high_severity' | 'sensitive' | 'failed_resolution' | 'target_risk' | 'policy' | 'manual';
|
|
49
49
|
/** Service Time Entry lifecycle (FR-36). */
|
|
50
50
|
export type ServiceTimeEntryStatus = 'draft' | 'submitted' | 'approved' | 'rejected' | 'corrected';
|
|
51
51
|
/**
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["/**\n * Shared types, enums, and lifecycle maps for `@happyvertical/smrt-support`.\n *\n * Domain language follows the HappyVertical support glossary: a **Support\n * Case** is the canonical record of a client support request; **Support\n * Interactions** are channel transports attached to it; **Service Targets**\n * are operational clocks (not contractual SLAs); a **Managed Support Plan**\n * carries the client-facing terms while a **Support Compensation Plan**\n * carries the provider-facing terms — the two are never merged.\n */\n\n/** Support Case lifecycle states (FR-29b). */\nexport type SupportCaseStatus =\n | 'new'\n | 'triaged'\n | 'assigned'\n | 'in_progress'\n | 'waiting_on_client'\n | 'escalated'\n | 'resolved'\n | 'closed';\n\n/**\n * Legal Support Case status transitions, enforced at save time by\n * {@link SupportCase} (S5 guarded-lifecycle idiom — raw mass-assignment on a\n * generated route cannot skip states). Reopening (`resolved`/`closed` back to\n * an active state) is legal here; the reopen bookkeeping (count, history\n * event) is layered by `SupportCaseService.reopen()`.\n */\nexport const SUPPORT_CASE_STATUS_TRANSITIONS: Record<\n SupportCaseStatus,\n SupportCaseStatus[]\n> = {\n new: [\n 'triaged',\n 'assigned',\n 'in_progress',\n 'waiting_on_client',\n 'escalated',\n 'resolved',\n 'closed',\n ],\n triaged: [\n 'assigned',\n 'in_progress',\n 'waiting_on_client',\n 'escalated',\n 'resolved',\n 'closed',\n ],\n assigned: [\n 'triaged',\n 'in_progress',\n 'waiting_on_client',\n 'escalated',\n 'resolved',\n 'closed',\n ],\n in_progress: [\n 'assigned',\n 'waiting_on_client',\n 'escalated',\n 'resolved',\n 'closed',\n ],\n waiting_on_client: [\n 'assigned',\n 'in_progress',\n 'escalated',\n 'resolved',\n 'closed',\n ],\n escalated: [\n 'assigned',\n 'in_progress',\n 'waiting_on_client',\n 'resolved',\n 'closed',\n ],\n resolved: ['closed', 'in_progress', 'triaged'],\n closed: ['triaged', 'in_progress'],\n};\n\n/** Case statuses considered \"open\" for create-or-join intake dedup. */\nexport const OPEN_SUPPORT_CASE_STATUSES: SupportCaseStatus[] = [\n 'new',\n 'triaged',\n 'assigned',\n 'in_progress',\n 'waiting_on_client',\n 'escalated',\n];\n\n/** Client-facing priority (ordering/urgency inside a queue). */\nexport type SupportCasePriority = 'low' | 'normal' | 'high' | 'urgent';\n\n/** Transport kind a Support Interaction arrived through. */\nexport type SupportChannelKind =\n | 'chat'\n | 'email'\n | 'phone'\n | 'voice'\n | 'web'\n | 'api';\n\n/** Direction of a Support Interaction relative to the Client. */\nexport type SupportInteractionDirection = 'inbound' | 'outbound' | 'internal';\n\n/** Who performed an interaction or case event. */\nexport type SupportActorKind = 'client' | 'specialist' | 'agent' | 'system';\n\n/** Append-only case audit event types. */\nexport type SupportCaseEventType =\n | 'created'\n | 'interaction'\n | 'transition'\n | 'assignment'\n | 'ai_run'\n | 'handoff'\n | 'human_requested'\n | 'escalation'\n | 'target_scheduled'\n | 'target_satisfied'\n | 'target_breached'\n | 'target_paused'\n | 'target_resumed'\n | 'work_linked'\n | 'reopened'\n | 'plan_applied'\n | 'time_recorded'\n | 'note';\n\n/** What kind of transport container a channel binding points at. */\nexport type SupportBindingKind = 'chat_room' | 'email_account';\n\n/** Operational Work Item link kinds carried by a {@link SupportWorkLink}. */\nexport type SupportWorkLinkKind = 'support_work_item' | 'development_work_item';\n\n/** Service Target clock types (FR-30/FR-31). */\nexport type ServiceTargetType =\n | 'acknowledgement'\n | 'response'\n | 'update'\n | 'resolution';\n\n/** Service Target clock states. */\nexport type ServiceTargetStatus =\n | 'pending'\n | 'paused'\n | 'satisfied'\n | 'breached'\n | 'cancelled';\n\n/** Why a case was escalated. */\nexport type SupportEscalationReason =\n | 'target_breach'\n | 'target_risk'\n | 'manual'\n | 'ai_trigger';\n\n/** AI support workflow phases (FR-28a). */\nexport type SupportAiRunPhase =\n | 'acknowledge'\n | 'classify'\n | 'answer'\n | 'troubleshoot'\n | 'resolve';\n\n/** Terminal outcome of one AI workflow phase run. */\nexport type SupportAiRunOutcome =\n | 'completed'\n | 'skipped'\n | 'failed'\n | 'handed_off';\n\n/** What triggered a Human Handoff (FR-28b). */\nexport type HumanHandoffTrigger =\n | 'client_request'\n | 'low_confidence'\n | 'high_severity'\n | 'sensitive'\n | 'failed_resolution'\n | 'target_risk'\n | 'policy'\n | 'manual';\n\n/** Service Time Entry lifecycle (FR-36). */\nexport type ServiceTimeEntryStatus =\n | 'draft'\n | 'submitted'\n | 'approved'\n | 'rejected'\n | 'corrected';\n\n/**\n * Legal Service Time Entry status transitions. `approved → corrected` is the\n * only exit from `approved` and is reachable exclusively through the explicit\n * correction path (the approved snapshot itself stays frozen).\n */\nexport const SERVICE_TIME_ENTRY_STATUS_TRANSITIONS: Record<\n ServiceTimeEntryStatus,\n ServiceTimeEntryStatus[]\n> = {\n draft: ['submitted', 'rejected'],\n submitted: ['approved', 'rejected', 'draft'],\n approved: ['corrected'],\n rejected: ['draft', 'submitted'],\n corrected: [],\n};\n\n/** How a Service Time Entry was produced (FR-40). */\nexport type ServiceTimeEntrySource = 'timer' | 'manual' | 'import' | 'agent';\n\n/** Who/what delivered the work behind a Service Time Entry. */\nexport type SupportParticipantKind = 'human' | 'agent';\n\n/** Which approval path accepted a Service Time Entry (FR-36). */\nexport type TimeEntryApprovalPath =\n | 'automatic'\n | 'operator'\n | 'client'\n | 'threshold';\n\n/** Derived commercial snapshot lifecycle (charges and compensation). */\nexport type SupportSettlementStatus =\n | 'pending'\n | 'final'\n | 'corrected'\n | 'voided';\n\n/** Support Specialist availability window kinds. */\nexport type SupportAvailabilityKind = 'weekly' | 'on_call' | 'time_off';\n\n/** Support Specialist activation state. */\nexport type SupportSpecialistStatus = 'active' | 'inactive';\n\n/** Project Support Qualification levels. */\nexport type SupportQualificationLevel = 'trainee' | 'qualified' | 'expert';\n\n/** A weekly coverage window in a plan's coverage calendar. */\nexport interface CoverageWindow {\n /** 0 = Sunday … 6 = Saturday (JS `Date#getDay` convention). */\n weekday: number;\n /** Minutes from midnight, inclusive start. */\n startMinute: number;\n /** Minutes from midnight, exclusive end. */\n endMinute: number;\n}\n\n/** Per-severity Service Target minutes; `null` disables that clock. */\nexport interface ServiceTargetMinutes {\n acknowledgementMinutes: number | null;\n responseMinutes: number | null;\n updateMinutes: number | null;\n resolutionMinutes: number | null;\n}\n\n/** One step of a plan's escalation policy, applied in `level` order. */\nexport interface EscalationStep {\n level: number;\n action: 'notify' | 'reassign';\n /** Profile ids to notify (recorded on the escalation; delivery is app-side). */\n notifyProfileIds?: string[];\n /** Minutes after the previous step before this one fires (0 = immediately). */\n delayMinutes?: number;\n}\n\n/** A severity definition entry in a plan (key → labels). */\nexport interface SeverityDefinition {\n label: string;\n description?: string;\n}\n\n/**\n * Default severity vocabulary used when a plan doesn't define its own.\n * `sev1` is the most severe.\n */\nexport const DEFAULT_SEVERITY_DEFINITIONS: Record<string, SeverityDefinition> =\n {\n sev1: { label: 'Critical', description: 'Service down or unusable' },\n sev2: { label: 'Major', description: 'Significant degradation' },\n sev3: { label: 'Minor', description: 'Limited impact' },\n sev4: { label: 'Question', description: 'Question or request' },\n };\n\n/** Time-entry approval policy carried by a Managed Support Plan (FR-36). */\nexport interface TimeApprovalPolicy {\n /** Base path when no threshold applies. */\n mode: 'automatic' | 'operator' | 'client';\n /** Entries longer than this require review even under `automatic`. */\n thresholdMinutes?: number;\n /**\n * Entries pricing above this amount require review even under `automatic`.\n * Integer minor units, matching `SupportCharge.amount` it is compared\n * against — `$19.99` is `1999` (#2401).\n */\n thresholdAmount?: number;\n}\n\n/** One piece of work evidence attached to a Service Time Entry. */\nexport interface TimeEntryEvidence {\n kind: string;\n ref: string;\n label?: string;\n}\n\n/**\n * Parse a JSON value stored as text, returning the fallback on malformed\n * input (never throws — stored JSON may predate schema changes). Accepts an\n * already-parsed value (e.g. a `type: 'json'` column that hydrated as an\n * object) and hands it back unchanged.\n */\nexport function parseJsonField<T>(raw: unknown, fallback: T): T {\n if (!raw) {\n return fallback;\n }\n // Text columns hydrate as strings; a non-string here means the caller\n // already holds a parsed value — hand it back rather than throwing.\n if (typeof raw !== 'string') {\n return raw as T;\n }\n try {\n const parsed = JSON.parse(raw);\n return (parsed ?? fallback) as T;\n } catch {\n return fallback;\n }\n}\n\n/** Parse a JSON array-of-strings field, tolerating malformed input. */\nexport function parseStringArrayField(\n raw: string | null | undefined,\n): string[] {\n const parsed = parseJsonField<unknown>(raw, []);\n return Array.isArray(parsed)\n ? parsed.filter((value): value is string => typeof value === 'string')\n : [];\n}\n"],"mappings":";AA6BO,IAAM,kCAGT;CACF,KAAK;EACH;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;CACF;CACA,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;CACF;CACA,aAAa;EACX;EACA;EACA;EACA;EACA;CACF;CACA,mBAAmB;EACjB;EACA;EACA;EACA;EACA;CACF;CACA,WAAW;EACT;EACA;EACA;EACA;EACA;CACF;CACA,UAAU;EAAC;EAAU;EAAe;CAAS;CAC7C,QAAQ,CAAC,WAAW,aAAa;AACnC;AAGO,IAAM,6BAAkD;CAC7D;CACA;CACA;CACA;CACA;CACA;AACF;AA4GO,IAAM,wCAGT;CACF,OAAO,CAAC,aAAa,UAAU;CAC/B,WAAW;EAAC;EAAY;EAAY;CAAO;CAC3C,UAAU,CAAC,WAAW;CACtB,UAAU,CAAC,SAAS,WAAW;CAC/B,WAAW,CAAC;AACd;AAqEO,IAAM,+BACX;CACE,MAAM;EAAE,OAAO;EAAY,aAAa;CAA2B;CACnE,MAAM;EAAE,OAAO;EAAS,aAAa;CAA0B;CAC/D,MAAM;EAAE,OAAO;EAAS,aAAa;CAAiB;CACtD,MAAM;EAAE,OAAO;EAAY,aAAa;CAAsB;AAChE;AA6BK,SAAS,eAAkB,KAAc,UAAgB;CAC9D,IAAI,CAAC,KACH,OAAO;CAIT,IAAI,OAAO,QAAQ,UACjB,OAAO;CAET,IAAI;EAEF,OADe,KAAK,MAAM,GAClB,KAAU;CACpB,QAAQ;EACN,OAAO;CACT;AACF;AAGO,SAAS,sBACd,KACU;CACV,MAAM,SAAS,eAAwB,KAAK,CAAC,CAAC;CAC9C,OAAO,MAAM,QAAQ,MAAM,IACvB,OAAO,QAAQ,UAA2B,OAAO,UAAU,QAAQ,IACnE,CAAC;AACP"}
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["/**\n * Shared types, enums, and lifecycle maps for `@happyvertical/smrt-support`.\n *\n * Domain language follows the HappyVertical support glossary: a **Support\n * Case** is the canonical record of a client support request; **Support\n * Interactions** are channel transports attached to it; **Service Targets**\n * are operational clocks (not contractual SLAs); a **Managed Support Plan**\n * carries the client-facing terms while a **Support Compensation Plan**\n * carries the provider-facing terms — the two are never merged.\n */\n\n/** Support Case lifecycle states (FR-29b). */\nexport type SupportCaseStatus =\n | 'new'\n | 'triaged'\n | 'assigned'\n | 'in_progress'\n | 'waiting_on_client'\n | 'escalated'\n | 'resolved'\n | 'closed';\n\n/**\n * Legal Support Case status transitions, enforced at save time by\n * {@link SupportCase} (S5 guarded-lifecycle idiom — raw mass-assignment on a\n * generated route cannot skip states). Reopening (`resolved`/`closed` back to\n * an active state) is legal here; the reopen bookkeeping (count, history\n * event) is layered by `SupportCaseService.reopen()`.\n */\nexport const SUPPORT_CASE_STATUS_TRANSITIONS: Record<\n SupportCaseStatus,\n SupportCaseStatus[]\n> = {\n new: [\n 'triaged',\n 'assigned',\n 'in_progress',\n 'waiting_on_client',\n 'escalated',\n 'resolved',\n 'closed',\n ],\n triaged: [\n 'assigned',\n 'in_progress',\n 'waiting_on_client',\n 'escalated',\n 'resolved',\n 'closed',\n ],\n assigned: [\n 'triaged',\n 'in_progress',\n 'waiting_on_client',\n 'escalated',\n 'resolved',\n 'closed',\n ],\n in_progress: [\n 'assigned',\n 'waiting_on_client',\n 'escalated',\n 'resolved',\n 'closed',\n ],\n waiting_on_client: [\n 'assigned',\n 'in_progress',\n 'escalated',\n 'resolved',\n 'closed',\n ],\n escalated: [\n 'assigned',\n 'in_progress',\n 'waiting_on_client',\n 'resolved',\n 'closed',\n ],\n resolved: ['closed', 'in_progress', 'triaged'],\n closed: ['triaged', 'in_progress'],\n};\n\n/** Case statuses considered \"open\" for create-or-join intake dedup. */\nexport const OPEN_SUPPORT_CASE_STATUSES: SupportCaseStatus[] = [\n 'new',\n 'triaged',\n 'assigned',\n 'in_progress',\n 'waiting_on_client',\n 'escalated',\n];\n\n/** Client-facing priority (ordering/urgency inside a queue). */\nexport type SupportCasePriority = 'low' | 'normal' | 'high' | 'urgent';\n\n/** Transport kind a Support Interaction arrived through. */\nexport type SupportChannelKind =\n | 'chat'\n | 'email'\n | 'phone'\n | 'voice'\n | 'web'\n | 'api';\n\n/** Direction of a Support Interaction relative to the Client. */\nexport type SupportInteractionDirection = 'inbound' | 'outbound' | 'internal';\n\n/** Who performed an interaction or case event. */\nexport type SupportActorKind = 'client' | 'specialist' | 'agent' | 'system';\n\n/** Append-only case audit event types. */\nexport type SupportCaseEventType =\n | 'created'\n | 'interaction'\n | 'transition'\n | 'assignment'\n | 'ai_run'\n | 'handoff'\n | 'human_requested'\n | 'escalation'\n | 'target_scheduled'\n | 'target_satisfied'\n | 'target_breached'\n | 'target_paused'\n | 'target_resumed'\n | 'work_linked'\n | 'reopened'\n | 'plan_applied'\n | 'time_recorded'\n | 'note';\n\n/** What kind of transport container a channel binding points at. */\nexport type SupportBindingKind = 'chat_room' | 'email_account';\n\n/** Operational Work Item link kinds carried by a {@link SupportWorkLink}. */\nexport type SupportWorkLinkKind = 'support_work_item' | 'development_work_item';\n\n/** Service Target clock types (FR-30/FR-31). */\nexport type ServiceTargetType =\n | 'acknowledgement'\n | 'response'\n | 'update'\n | 'resolution';\n\n/** Service Target clock states. */\nexport type ServiceTargetStatus =\n | 'pending'\n | 'paused'\n | 'satisfied'\n | 'breached'\n | 'cancelled';\n\n/** Why a case was escalated. */\nexport type SupportEscalationReason =\n | 'target_breach'\n | 'target_risk'\n | 'manual'\n | 'ai_trigger';\n\n/** AI support workflow phases (FR-28a). */\nexport type SupportAiRunPhase =\n | 'acknowledge'\n | 'classify'\n | 'answer'\n | 'troubleshoot'\n | 'resolve';\n\n/** Terminal outcome of one AI workflow phase run. */\nexport type SupportAiRunOutcome =\n | 'completed'\n | 'skipped'\n | 'failed'\n | 'handed_off';\n\n/** What triggered a Human Handoff (FR-28b). */\nexport type HumanHandoffTrigger =\n | 'client_request'\n | 'low_confidence'\n | 'ambiguous_classification'\n | 'high_severity'\n | 'sensitive'\n | 'failed_resolution'\n | 'target_risk'\n | 'policy'\n | 'manual';\n\n/** Service Time Entry lifecycle (FR-36). */\nexport type ServiceTimeEntryStatus =\n | 'draft'\n | 'submitted'\n | 'approved'\n | 'rejected'\n | 'corrected';\n\n/**\n * Legal Service Time Entry status transitions. `approved → corrected` is the\n * only exit from `approved` and is reachable exclusively through the explicit\n * correction path (the approved snapshot itself stays frozen).\n */\nexport const SERVICE_TIME_ENTRY_STATUS_TRANSITIONS: Record<\n ServiceTimeEntryStatus,\n ServiceTimeEntryStatus[]\n> = {\n draft: ['submitted', 'rejected'],\n submitted: ['approved', 'rejected', 'draft'],\n approved: ['corrected'],\n rejected: ['draft', 'submitted'],\n corrected: [],\n};\n\n/** How a Service Time Entry was produced (FR-40). */\nexport type ServiceTimeEntrySource = 'timer' | 'manual' | 'import' | 'agent';\n\n/** Who/what delivered the work behind a Service Time Entry. */\nexport type SupportParticipantKind = 'human' | 'agent';\n\n/** Which approval path accepted a Service Time Entry (FR-36). */\nexport type TimeEntryApprovalPath =\n | 'automatic'\n | 'operator'\n | 'client'\n | 'threshold';\n\n/** Derived commercial snapshot lifecycle (charges and compensation). */\nexport type SupportSettlementStatus =\n | 'pending'\n | 'final'\n | 'corrected'\n | 'voided';\n\n/** Support Specialist availability window kinds. */\nexport type SupportAvailabilityKind = 'weekly' | 'on_call' | 'time_off';\n\n/** Support Specialist activation state. */\nexport type SupportSpecialistStatus = 'active' | 'inactive';\n\n/** Project Support Qualification levels. */\nexport type SupportQualificationLevel = 'trainee' | 'qualified' | 'expert';\n\n/** A weekly coverage window in a plan's coverage calendar. */\nexport interface CoverageWindow {\n /** 0 = Sunday … 6 = Saturday (JS `Date#getDay` convention). */\n weekday: number;\n /** Minutes from midnight, inclusive start. */\n startMinute: number;\n /** Minutes from midnight, exclusive end. */\n endMinute: number;\n}\n\n/** Per-severity Service Target minutes; `null` disables that clock. */\nexport interface ServiceTargetMinutes {\n acknowledgementMinutes: number | null;\n responseMinutes: number | null;\n updateMinutes: number | null;\n resolutionMinutes: number | null;\n}\n\n/** One step of a plan's escalation policy, applied in `level` order. */\nexport interface EscalationStep {\n level: number;\n action: 'notify' | 'reassign';\n /** Profile ids to notify (recorded on the escalation; delivery is app-side). */\n notifyProfileIds?: string[];\n /** Minutes after the previous step before this one fires (0 = immediately). */\n delayMinutes?: number;\n}\n\n/** A severity definition entry in a plan (key → labels). */\nexport interface SeverityDefinition {\n label: string;\n description?: string;\n}\n\n/**\n * Default severity vocabulary used when a plan doesn't define its own.\n * `sev1` is the most severe.\n */\nexport const DEFAULT_SEVERITY_DEFINITIONS: Record<string, SeverityDefinition> =\n {\n sev1: { label: 'Critical', description: 'Service down or unusable' },\n sev2: { label: 'Major', description: 'Significant degradation' },\n sev3: { label: 'Minor', description: 'Limited impact' },\n sev4: { label: 'Question', description: 'Question or request' },\n };\n\n/** Time-entry approval policy carried by a Managed Support Plan (FR-36). */\nexport interface TimeApprovalPolicy {\n /** Base path when no threshold applies. */\n mode: 'automatic' | 'operator' | 'client';\n /** Entries longer than this require review even under `automatic`. */\n thresholdMinutes?: number;\n /**\n * Entries pricing above this amount require review even under `automatic`.\n * Integer minor units, matching `SupportCharge.amount` it is compared\n * against — `$19.99` is `1999` (#2401).\n */\n thresholdAmount?: number;\n}\n\n/** One piece of work evidence attached to a Service Time Entry. */\nexport interface TimeEntryEvidence {\n kind: string;\n ref: string;\n label?: string;\n}\n\n/**\n * Parse a JSON value stored as text, returning the fallback on malformed\n * input (never throws — stored JSON may predate schema changes). Accepts an\n * already-parsed value (e.g. a `type: 'json'` column that hydrated as an\n * object) and hands it back unchanged.\n */\nexport function parseJsonField<T>(raw: unknown, fallback: T): T {\n if (!raw) {\n return fallback;\n }\n // Text columns hydrate as strings; a non-string here means the caller\n // already holds a parsed value — hand it back rather than throwing.\n if (typeof raw !== 'string') {\n return raw as T;\n }\n try {\n const parsed = JSON.parse(raw);\n return (parsed ?? fallback) as T;\n } catch {\n return fallback;\n }\n}\n\n/** Parse a JSON array-of-strings field, tolerating malformed input. */\nexport function parseStringArrayField(\n raw: string | null | undefined,\n): string[] {\n const parsed = parseJsonField<unknown>(raw, []);\n return Array.isArray(parsed)\n ? parsed.filter((value): value is string => typeof value === 'string')\n : [];\n}\n"],"mappings":";AA6BO,IAAM,kCAGT;CACF,KAAK;EACH;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;CACF;CACA,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;CACF;CACA,aAAa;EACX;EACA;EACA;EACA;EACA;CACF;CACA,mBAAmB;EACjB;EACA;EACA;EACA;EACA;CACF;CACA,WAAW;EACT;EACA;EACA;EACA;EACA;CACF;CACA,UAAU;EAAC;EAAU;EAAe;CAAS;CAC7C,QAAQ,CAAC,WAAW,aAAa;AACnC;AAGO,IAAM,6BAAkD;CAC7D;CACA;CACA;CACA;CACA;CACA;AACF;AA6GO,IAAM,wCAGT;CACF,OAAO,CAAC,aAAa,UAAU;CAC/B,WAAW;EAAC;EAAY;EAAY;CAAO;CAC3C,UAAU,CAAC,WAAW;CACtB,UAAU,CAAC,SAAS,WAAW;CAC/B,WAAW,CAAC;AACd;AAqEO,IAAM,+BACX;CACE,MAAM;EAAE,OAAO;EAAY,aAAa;CAA2B;CACnE,MAAM;EAAE,OAAO;EAAS,aAAa;CAA0B;CAC/D,MAAM;EAAE,OAAO;EAAS,aAAa;CAAiB;CACtD,MAAM;EAAE,OAAO;EAAY,aAAa;CAAsB;AAChE;AA6BK,SAAS,eAAkB,KAAc,UAAgB;CAC9D,IAAI,CAAC,KACH,OAAO;CAIT,IAAI,OAAO,QAAQ,UACjB,OAAO;CAET,IAAI;EAEF,OADe,KAAK,MAAM,GAClB,KAAU;CACpB,QAAQ;EACN,OAAO;CACT;AACF;AAGO,SAAS,sBACd,KACU;CACV,MAAM,SAAS,eAAwB,KAAK,CAAC,CAAC;CAC9C,OAAO,MAAM,QAAQ,MAAM,IACvB,OAAO,QAAQ,UAA2B,OAAO,UAAU,QAAQ,IACnE,CAAC;AACP"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-support",
|
|
3
|
-
"version": "0.51.
|
|
3
|
+
"version": "0.51.33",
|
|
4
4
|
"smrtJsdoc": "strict",
|
|
5
5
|
"description": "AI-first Support Cases: channel-neutral intake, lifecycle, routing, service targets, and service time for the SMRT framework",
|
|
6
6
|
"type": "module",
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@happyvertical/logger": "^0.94.1",
|
|
30
|
-
"@happyvertical/smrt-chat": "0.51.
|
|
31
|
-
"@happyvertical/smrt-core": "0.51.
|
|
32
|
-
"@happyvertical/smrt-jobs": "0.51.
|
|
33
|
-
"@happyvertical/smrt-messages": "0.51.
|
|
34
|
-
"@happyvertical/smrt-projects": "0.51.
|
|
35
|
-
"@happyvertical/smrt-tenancy": "0.51.
|
|
36
|
-
"@happyvertical/smrt-ui": "0.51.
|
|
37
|
-
"@happyvertical/smrt-users": "0.51.
|
|
30
|
+
"@happyvertical/smrt-chat": "0.51.33",
|
|
31
|
+
"@happyvertical/smrt-core": "0.51.33",
|
|
32
|
+
"@happyvertical/smrt-jobs": "0.51.33",
|
|
33
|
+
"@happyvertical/smrt-messages": "0.51.33",
|
|
34
|
+
"@happyvertical/smrt-projects": "0.51.33",
|
|
35
|
+
"@happyvertical/smrt-tenancy": "0.51.33",
|
|
36
|
+
"@happyvertical/smrt-ui": "0.51.33",
|
|
37
|
+
"@happyvertical/smrt-users": "0.51.33",
|
|
38
38
|
"@happyvertical/sql": "^0.94.1"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
@@ -46,13 +46,13 @@
|
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@happyvertical/smrt-vitest": "0.51.
|
|
49
|
+
"@happyvertical/smrt-vitest": "0.51.33",
|
|
50
50
|
"@sveltejs/package": "^2.5.8",
|
|
51
51
|
"@sveltejs/vite-plugin-svelte": "^7.3.0",
|
|
52
52
|
"@types/node": "24.13.6",
|
|
53
53
|
"svelte": "^5.57.1",
|
|
54
54
|
"svelte-check": "^4.7.6",
|
|
55
|
-
"typescript": "
|
|
55
|
+
"typescript": "6.0.3",
|
|
56
56
|
"vite": "8.1.4",
|
|
57
57
|
"vitest": "4.1.10"
|
|
58
58
|
},
|