@talkpilot/core-db 1.3.0 → 1.3.1
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 +0 -30
- package/dist/municipal/tickets/index.d.ts +1 -2
- package/dist/municipal/tickets/index.d.ts.map +1 -1
- package/dist/municipal/tickets/index.js +0 -1
- package/dist/municipal/tickets/index.js.map +1 -1
- package/dist/municipal/tickets/tickets.getters.d.ts +11 -0
- package/dist/municipal/tickets/tickets.getters.d.ts.map +1 -1
- package/dist/municipal/tickets/tickets.getters.js +128 -0
- package/dist/municipal/tickets/tickets.getters.js.map +1 -1
- package/dist/municipal/tickets/tickets.types.d.ts +5 -10
- package/dist/municipal/tickets/tickets.types.d.ts.map +1 -1
- package/dist/talkpilot/calls/calls.types.d.ts +2 -1
- package/dist/talkpilot/calls/calls.types.d.ts.map +1 -1
- package/dist/talkpilot/calls/calls.types.js +3 -0
- package/dist/talkpilot/calls/calls.types.js.map +1 -1
- package/dist/talkpilot/calls/dashboard/calls.dashboard.d.ts +1 -33
- package/dist/talkpilot/calls/dashboard/calls.dashboard.d.ts.map +1 -1
- package/dist/talkpilot/calls/dashboard/calls.dashboard.js +146 -131
- package/dist/talkpilot/calls/dashboard/calls.dashboard.js.map +1 -1
- package/dist/talkpilot/calls/dashboard/calls.dashboard.types.d.ts +6 -27
- package/dist/talkpilot/calls/dashboard/calls.dashboard.types.d.ts.map +1 -1
- package/dist/talkpilot/calls/index.d.ts +0 -3
- package/dist/talkpilot/calls/index.d.ts.map +1 -1
- package/dist/talkpilot/calls/index.js +0 -3
- package/dist/talkpilot/calls/index.js.map +1 -1
- package/package.json +1 -1
- package/src/municipal/tickets/__tests__/tickets.getters.spec.ts +37 -1
- package/src/municipal/tickets/index.ts +1 -2
- package/src/municipal/tickets/tickets.getters.ts +140 -0
- package/src/municipal/tickets/tickets.types.ts +9 -14
- package/src/talkpilot/calls/__tests__/calls.dashboard.spec.ts +111 -8
- package/src/talkpilot/calls/calls.types.ts +2 -4
- package/src/talkpilot/calls/dashboard/calls.dashboard.ts +197 -148
- package/src/talkpilot/calls/dashboard/calls.dashboard.types.ts +12 -25
- package/src/talkpilot/calls/index.ts +0 -3
- package/src/talkpilot/clientsConfig/__tests__/clientsConfig.spec.ts +0 -7
- package/dist/municipal/tickets/tickets.constants.d.ts +0 -7
- package/dist/municipal/tickets/tickets.constants.d.ts.map +0 -1
- package/dist/municipal/tickets/tickets.constants.js +0 -10
- package/dist/municipal/tickets/tickets.constants.js.map +0 -1
- package/dist/municipal/tickets/tickets.deprecated.getters.d.ts +0 -12
- package/dist/municipal/tickets/tickets.deprecated.getters.d.ts.map +0 -1
- package/dist/municipal/tickets/tickets.deprecated.getters.js +0 -131
- package/dist/municipal/tickets/tickets.deprecated.getters.js.map +0 -1
- package/dist/municipal/tickets/tickets.statistics.aggregation.d.ts +0 -45
- package/dist/municipal/tickets/tickets.statistics.aggregation.d.ts.map +0 -1
- package/dist/municipal/tickets/tickets.statistics.aggregation.js +0 -98
- package/dist/municipal/tickets/tickets.statistics.aggregation.js.map +0 -1
- package/dist/municipal/tickets/tickets.statistics.dates.d.ts +0 -7
- package/dist/municipal/tickets/tickets.statistics.dates.d.ts.map +0 -1
- package/dist/municipal/tickets/tickets.statistics.dates.js +0 -40
- package/dist/municipal/tickets/tickets.statistics.dates.js.map +0 -1
- package/dist/municipal/tickets/tickets.statistics.getters.d.ts +0 -9
- package/dist/municipal/tickets/tickets.statistics.getters.d.ts.map +0 -1
- package/dist/municipal/tickets/tickets.statistics.getters.js +0 -55
- package/dist/municipal/tickets/tickets.statistics.getters.js.map +0 -1
- package/dist/municipal/tickets/tickets.statistics.pipeline.d.ts +0 -53
- package/dist/municipal/tickets/tickets.statistics.pipeline.d.ts.map +0 -1
- package/dist/municipal/tickets/tickets.statistics.pipeline.js +0 -112
- package/dist/municipal/tickets/tickets.statistics.pipeline.js.map +0 -1
- package/dist/municipal/tickets/tickets.statistics.utils.d.ts +0 -7
- package/dist/municipal/tickets/tickets.statistics.utils.d.ts.map +0 -1
- package/dist/municipal/tickets/tickets.statistics.utils.js +0 -40
- package/dist/municipal/tickets/tickets.statistics.utils.js.map +0 -1
- package/dist/talkpilot/calls/calls.constants.d.ts +0 -17
- package/dist/talkpilot/calls/calls.constants.d.ts.map +0 -1
- package/dist/talkpilot/calls/calls.constants.js +0 -20
- package/dist/talkpilot/calls/calls.constants.js.map +0 -1
- package/dist/talkpilot/calls/calls.statistics.getters.d.ts +0 -19
- package/dist/talkpilot/calls/calls.statistics.getters.d.ts.map +0 -1
- package/dist/talkpilot/calls/calls.statistics.getters.js +0 -375
- package/dist/talkpilot/calls/calls.statistics.getters.js.map +0 -1
- package/dist/talkpilot/calls/calls.statistics.ticketScope.d.ts +0 -12
- package/dist/talkpilot/calls/calls.statistics.ticketScope.d.ts.map +0 -1
- package/dist/talkpilot/calls/calls.statistics.ticketScope.js +0 -37
- package/dist/talkpilot/calls/calls.statistics.ticketScope.js.map +0 -1
- package/dist/talkpilot/calls/calls.statistics.tickets.d.ts +0 -17
- package/dist/talkpilot/calls/calls.statistics.tickets.d.ts.map +0 -1
- package/dist/talkpilot/calls/calls.statistics.tickets.js +0 -33
- package/dist/talkpilot/calls/calls.statistics.tickets.js.map +0 -1
- package/dist/talkpilot/calls/calls.statistics.types.d.ts +0 -39
- package/dist/talkpilot/calls/calls.statistics.types.d.ts.map +0 -1
- package/dist/talkpilot/calls/calls.statistics.types.js +0 -3
- package/dist/talkpilot/calls/calls.statistics.types.js.map +0 -1
- package/dist/utils/date.utils.d.ts +0 -49
- package/dist/utils/date.utils.d.ts.map +0 -1
- package/dist/utils/date.utils.js +0 -103
- package/dist/utils/date.utils.js.map +0 -1
- package/dist/utils/statistics.aggregation.d.ts +0 -20
- package/dist/utils/statistics.aggregation.d.ts.map +0 -1
- package/dist/utils/statistics.aggregation.js +0 -43
- package/dist/utils/statistics.aggregation.js.map +0 -1
- package/src/municipal/tickets/__tests__/tickets.statistics.spec.ts +0 -104
- package/src/municipal/tickets/tickets.constants.ts +0 -8
- package/src/municipal/tickets/tickets.statistics.aggregation.ts +0 -113
- package/src/municipal/tickets/tickets.statistics.getters.ts +0 -93
- package/src/talkpilot/calls/__tests__/calls.statistics.spec.ts +0 -281
- package/src/talkpilot/calls/calls.constants.ts +0 -20
- package/src/talkpilot/calls/calls.statistics.getters.ts +0 -525
- package/src/talkpilot/calls/calls.statistics.types.ts +0 -44
- package/src/utils/date.utils.ts +0 -116
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CityName, getDb, ObjectId, Ticket } from "../index";
|
|
2
|
+
import type { SubjectStatsItem } from "./tickets.types";
|
|
2
3
|
import { Collection, Filter, ObjectId as MongoObjectId } from "mongodb";
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -67,6 +68,145 @@ export const deleteTicket = async (ticketId: string): Promise<boolean> => {
|
|
|
67
68
|
return result.deletedCount > 0;
|
|
68
69
|
};
|
|
69
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Count tickets by city and date range (createdAt converted to given timezone).
|
|
73
|
+
* Used as "open" tickets count when status is not available.
|
|
74
|
+
*/
|
|
75
|
+
export async function getTicketsCountByCityAndDateRange(
|
|
76
|
+
cityName: string,
|
|
77
|
+
startStr: string,
|
|
78
|
+
endStr: string,
|
|
79
|
+
timezone: string,
|
|
80
|
+
): Promise<number> {
|
|
81
|
+
const doc = await getTicketsCollection()
|
|
82
|
+
.aggregate<{ n: number }>([
|
|
83
|
+
{ $match: { cityName, callSid: { $exists: true, $nin: [null, ""] } } },
|
|
84
|
+
{
|
|
85
|
+
$addFields: {
|
|
86
|
+
dateLocal: {
|
|
87
|
+
$dateToString: { format: "%Y-%m-%d", date: "$createdAt", timezone },
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{ $match: { dateLocal: { $gte: startStr, $lte: endStr } } },
|
|
92
|
+
{ $count: "n" },
|
|
93
|
+
])
|
|
94
|
+
.next();
|
|
95
|
+
return doc?.n ?? 0;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Count of tickets by department (subject) from departmentsSubjects. Different departments (subject_id) are grouped, and sub-subjects are unified under their department.
|
|
100
|
+
* Date filter: createdAt in [startStr, endStr] (in the given timezone). Fallback to "Unclassified" when no match is found in the lookup.
|
|
101
|
+
*/
|
|
102
|
+
export async function getTicketsSubjectStats(
|
|
103
|
+
cityName: string,
|
|
104
|
+
startStr: string,
|
|
105
|
+
endStr: string,
|
|
106
|
+
timezone: string,
|
|
107
|
+
): Promise<SubjectStatsItem[]> {
|
|
108
|
+
const coll = getTicketsCollection();
|
|
109
|
+
const rows = await coll
|
|
110
|
+
.aggregate<{ _id: string; subject: string; count: number }>([
|
|
111
|
+
{ $match: { cityName } },
|
|
112
|
+
{
|
|
113
|
+
$addFields: {
|
|
114
|
+
dateLocal: {
|
|
115
|
+
$dateToString: { format: "%Y-%m-%d", date: "$createdAt", timezone },
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
{ $match: { dateLocal: { $gte: startStr, $lte: endStr } } },
|
|
120
|
+
{
|
|
121
|
+
$addFields: {
|
|
122
|
+
effectiveSubjectId: {
|
|
123
|
+
$ifNull: [
|
|
124
|
+
"$externalCallFields.event_subject_id",
|
|
125
|
+
{
|
|
126
|
+
$ifNull: [
|
|
127
|
+
"$externalCallFields.event_sub_subject_id",
|
|
128
|
+
"$externalCallFields.event_sub_subject_id2",
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
$lookup: {
|
|
137
|
+
from: "departmentsSubjects",
|
|
138
|
+
let: { sid: "$effectiveSubjectId", c: cityName },
|
|
139
|
+
pipeline: [
|
|
140
|
+
{
|
|
141
|
+
$match: {
|
|
142
|
+
$expr: {
|
|
143
|
+
$and: [
|
|
144
|
+
{ $eq: ["$cityName", "$$c"] },
|
|
145
|
+
{
|
|
146
|
+
$or: [
|
|
147
|
+
{ $eq: ["$subject_id", { $ifNull: ["$$sid", ""] }] },
|
|
148
|
+
{
|
|
149
|
+
$eq: ["$sub_subject_id", { $ifNull: ["$$sid", ""] }],
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
$eq: ["$sub_subject_id2", { $ifNull: ["$$sid", ""] }],
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
{ $limit: 1 },
|
|
161
|
+
],
|
|
162
|
+
as: "subj",
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
$addFields: {
|
|
167
|
+
subject_id: {
|
|
168
|
+
$cond: {
|
|
169
|
+
if: { $gt: [{ $size: "$subj" }, 0] },
|
|
170
|
+
then: {
|
|
171
|
+
$ifNull: [{ $arrayElemAt: ["$subj.subject_id", 0] }, ""],
|
|
172
|
+
},
|
|
173
|
+
else: "",
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
subject: {
|
|
177
|
+
$cond: {
|
|
178
|
+
if: { $gt: [{ $size: "$subj" }, 0] },
|
|
179
|
+
then: {
|
|
180
|
+
$ifNull: [
|
|
181
|
+
{ $arrayElemAt: ["$subj.subjectName", 0] },
|
|
182
|
+
"Unclassified",
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
else: "Unclassified",
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
$group: {
|
|
192
|
+
_id: "$subject_id",
|
|
193
|
+
subject: { $first: "$subject" },
|
|
194
|
+
count: { $sum: 1 },
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
{ $sort: { count: -1 } },
|
|
198
|
+
])
|
|
199
|
+
.toArray();
|
|
200
|
+
|
|
201
|
+
const total = rows.reduce((s: number, r: any) => s + r.count, 0);
|
|
202
|
+
return rows.map((r: any) => ({
|
|
203
|
+
subject_name: r.subject,
|
|
204
|
+
subject_id: r._id,
|
|
205
|
+
count: r.count,
|
|
206
|
+
percentage: total > 0 ? Math.round((r.count / total) * 100) : 0,
|
|
207
|
+
}));
|
|
208
|
+
}
|
|
209
|
+
|
|
70
210
|
export const findTicketByQuery = async (query: Partial<Ticket>) => {
|
|
71
211
|
return await getTicketsCollection().findOne(query);
|
|
72
212
|
};
|
|
@@ -9,6 +9,7 @@ export type Ticket = {
|
|
|
9
9
|
callSid?: string;
|
|
10
10
|
cityName: CityName;
|
|
11
11
|
externalCallFields: {
|
|
12
|
+
// Request fields
|
|
12
13
|
first_name?: string;
|
|
13
14
|
last_name?: string;
|
|
14
15
|
event_description?: string;
|
|
@@ -17,9 +18,10 @@ export type Ticket = {
|
|
|
17
18
|
event_subject_id?: string;
|
|
18
19
|
event_sub_subject_id?: string;
|
|
19
20
|
event_sub_subject_id2?: string | null;
|
|
21
|
+
// Response fields (only if external call was successful)
|
|
20
22
|
call_number?: string;
|
|
21
|
-
status?: number;
|
|
22
|
-
error?: string;
|
|
23
|
+
status?: number; // Response status from Bina API (1 = success)
|
|
24
|
+
error?: string; // Error message from Bina API if any
|
|
23
25
|
image1?: string;
|
|
24
26
|
image2?: string;
|
|
25
27
|
image3?: string;
|
|
@@ -32,17 +34,10 @@ export type Ticket = {
|
|
|
32
34
|
|
|
33
35
|
export type TicketDoc = WithId<Ticket>;
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
/** Call count by department (subject). */
|
|
38
|
+
export type SubjectStatsItem = {
|
|
39
|
+
subject_name: string;
|
|
40
|
+
subject_id: string;
|
|
37
41
|
count: number;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
export type TicketStatsDateScope = {
|
|
41
|
-
from?: Date;
|
|
42
|
-
to?: Date;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export type TicketStatsDateRange = {
|
|
46
|
-
from: Date;
|
|
47
|
-
to: Date;
|
|
42
|
+
percentage: number;
|
|
48
43
|
};
|
|
@@ -25,8 +25,8 @@ describe("getDashboardStats", () => {
|
|
|
25
25
|
|
|
26
26
|
const params = {
|
|
27
27
|
clientId,
|
|
28
|
-
startDate: "2026-05-
|
|
29
|
-
endDate: "2026-05-
|
|
28
|
+
startDate: "2026-05-01T00:00:00.000Z",
|
|
29
|
+
endDate: "2026-05-31T23:59:59.999Z",
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
const result = await getDashboardStats(params);
|
|
@@ -35,12 +35,115 @@ describe("getDashboardStats", () => {
|
|
|
35
35
|
expect(result.kpis.totalCalls).toBe(0);
|
|
36
36
|
expect(result.kpis.completedCount).toBe(0);
|
|
37
37
|
expect(result.kpis.avgDurationSeconds).toBe(0);
|
|
38
|
-
expect(result.
|
|
39
|
-
expect(result.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
expect(result.kpis.busyCount).toBe(0);
|
|
39
|
+
expect(result.kpis.timeSavedMinutes).toBe(0);
|
|
40
|
+
// ~30 day range -> daily buckets, gap-filled with zeros across the whole range
|
|
41
|
+
expect(result.charts.volumeGranularity).toBe("day");
|
|
42
|
+
expect(result.charts.volumeData.length).toBeGreaterThan(0);
|
|
43
|
+
expect(result.charts.volumeData.every((d) => d.completed === 0)).toBe(true);
|
|
44
|
+
expect(result.charts.volumeData[0].date).toBe("2026-05-01");
|
|
45
|
+
expect(
|
|
46
|
+
result.charts.volumeData[result.charts.volumeData.length - 1].date,
|
|
47
|
+
).toBe("2026-05-31");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("should pick a bucket size that keeps the volume chart readable across range lengths", async () => {
|
|
51
|
+
const clientId = "client-dash-456";
|
|
52
|
+
|
|
53
|
+
await getClientsConfigCollection().insertOne({
|
|
54
|
+
clientId,
|
|
55
|
+
timezone: "UTC",
|
|
56
|
+
products: {},
|
|
57
|
+
} as any);
|
|
58
|
+
|
|
59
|
+
const oneDay = await getDashboardStats({
|
|
60
|
+
clientId,
|
|
61
|
+
startDate: "2026-05-01T00:00:00.000Z",
|
|
62
|
+
endDate: "2026-05-01T23:59:59.999Z",
|
|
63
|
+
});
|
|
64
|
+
expect(oneDay.charts.volumeGranularity).toBe("hour");
|
|
65
|
+
|
|
66
|
+
const threeWeeks = await getDashboardStats({
|
|
67
|
+
clientId,
|
|
68
|
+
startDate: "2026-05-01T00:00:00.000Z",
|
|
69
|
+
endDate: "2026-05-21T23:59:59.999Z",
|
|
70
|
+
});
|
|
71
|
+
expect(threeWeeks.charts.volumeGranularity).toBe("day");
|
|
72
|
+
|
|
73
|
+
const fourMonths = await getDashboardStats({
|
|
74
|
+
clientId,
|
|
75
|
+
startDate: "2026-01-01T00:00:00.000Z",
|
|
76
|
+
endDate: "2026-04-30T23:59:59.999Z",
|
|
77
|
+
});
|
|
78
|
+
expect(fourMonths.charts.volumeGranularity).toBe("week");
|
|
79
|
+
|
|
80
|
+
const eighteenMonths = await getDashboardStats({
|
|
81
|
+
clientId,
|
|
82
|
+
startDate: "2025-01-01T00:00:00.000Z",
|
|
83
|
+
endDate: "2026-06-30T23:59:59.999Z",
|
|
84
|
+
});
|
|
85
|
+
expect(eighteenMonths.charts.volumeGranularity).toBe("month");
|
|
86
|
+
|
|
87
|
+
const threeYears = await getDashboardStats({
|
|
88
|
+
clientId,
|
|
89
|
+
startDate: "2023-01-01T00:00:00.000Z",
|
|
90
|
+
endDate: "2026-01-01T23:59:59.999Z",
|
|
91
|
+
});
|
|
92
|
+
expect(threeYears.charts.volumeGranularity).toBe("quarter");
|
|
93
|
+
|
|
94
|
+
const fiveYears = await getDashboardStats({
|
|
95
|
+
clientId,
|
|
96
|
+
startDate: "2021-01-01T00:00:00.000Z",
|
|
97
|
+
endDate: "2026-01-01T23:59:59.999Z",
|
|
98
|
+
});
|
|
99
|
+
expect(fiveYears.charts.volumeGranularity).toBe("year");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("should fill gaps with zero-count buckets so the chart has no missing points", async () => {
|
|
103
|
+
const clientId = "client-dash-789";
|
|
104
|
+
|
|
105
|
+
await getClientsConfigCollection().insertOne({
|
|
106
|
+
clientId,
|
|
107
|
+
timezone: "UTC",
|
|
108
|
+
products: {},
|
|
109
|
+
} as any);
|
|
110
|
+
|
|
111
|
+
// Sparse data: only two of the day's hours have calls.
|
|
112
|
+
await getCallsCollection().insertMany([
|
|
113
|
+
{
|
|
114
|
+
clientId,
|
|
115
|
+
status: "completed",
|
|
116
|
+
callLength: 60,
|
|
117
|
+
createdAt: new Date("2026-05-01T09:15:00Z"),
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
clientId,
|
|
121
|
+
status: "completed",
|
|
122
|
+
callLength: 90,
|
|
123
|
+
createdAt: new Date("2026-05-01T18:45:00Z"),
|
|
124
|
+
},
|
|
125
|
+
] as any);
|
|
126
|
+
|
|
127
|
+
const result = await getDashboardStats({
|
|
128
|
+
clientId,
|
|
129
|
+
startDate: "2026-05-01T00:00:00.000Z",
|
|
130
|
+
endDate: "2026-05-01T23:59:59.999Z",
|
|
44
131
|
});
|
|
132
|
+
|
|
133
|
+
expect(result.charts.volumeGranularity).toBe("hour");
|
|
134
|
+
// A full day of hourly buckets, with no gaps, sorted chronologically.
|
|
135
|
+
expect(result.charts.volumeData).toHaveLength(24);
|
|
136
|
+
expect(result.charts.volumeData[0].date).toBe("2026-05-01T00:00");
|
|
137
|
+
expect(result.charts.volumeData[23].date).toBe("2026-05-01T23:00");
|
|
138
|
+
|
|
139
|
+
const populated = result.charts.volumeData.filter((d) => d.completed > 0);
|
|
140
|
+
expect(populated).toHaveLength(2);
|
|
141
|
+
expect(populated.map((d) => d.date)).toEqual([
|
|
142
|
+
"2026-05-01T09:00",
|
|
143
|
+
"2026-05-01T18:00",
|
|
144
|
+
]);
|
|
145
|
+
|
|
146
|
+
const empty = result.charts.volumeData.filter((d) => d.completed === 0);
|
|
147
|
+
expect(empty).toHaveLength(22);
|
|
45
148
|
});
|
|
46
149
|
});
|
|
@@ -2,10 +2,8 @@ import { ObjectId, Sort, WithId } from "mongodb";
|
|
|
2
2
|
import { TranscriptionSegment } from "../results";
|
|
3
3
|
import { LeadProperty } from "../leads";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
CONFERENCE_ROLE_SUPERVISOR,
|
|
8
|
-
} from "./calls.constants";
|
|
5
|
+
export const CONFERENCE_ROLE_CUSTOMER = "customer" as const;
|
|
6
|
+
export const CONFERENCE_ROLE_SUPERVISOR = "supervisor" as const;
|
|
9
7
|
|
|
10
8
|
export type ConferenceRole =
|
|
11
9
|
| typeof CONFERENCE_ROLE_CUSTOMER
|