@talkpilot/core-db 1.3.23 → 1.3.24

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.
Files changed (208) hide show
  1. package/.cursor/rules/development.mdc +65 -65
  2. package/DEVELOPMENT.md +141 -141
  3. package/README.md +495 -532
  4. package/dist/talkpilot/calls/calls.constants.d.ts +0 -14
  5. package/dist/talkpilot/calls/calls.constants.d.ts.map +1 -1
  6. package/dist/talkpilot/calls/calls.constants.js +1 -15
  7. package/dist/talkpilot/calls/calls.constants.js.map +1 -1
  8. package/dist/talkpilot/calls/calls.getters.d.ts +0 -3
  9. package/dist/talkpilot/calls/calls.getters.d.ts.map +1 -1
  10. package/dist/talkpilot/calls/calls.getters.js +1 -12
  11. package/dist/talkpilot/calls/calls.getters.js.map +1 -1
  12. package/dist/talkpilot/calls/calls.types.d.ts +2 -11
  13. package/dist/talkpilot/calls/calls.types.d.ts.map +1 -1
  14. package/dist/talkpilot/clientsConfig/clientsConfig.types.d.ts +0 -1
  15. package/dist/talkpilot/clientsConfig/clientsConfig.types.d.ts.map +1 -1
  16. package/dist/talkpilot/flows/flows.setter.d.ts +13 -0
  17. package/dist/talkpilot/flows/flows.setter.d.ts.map +1 -0
  18. package/dist/talkpilot/flows/flows.setter.js +90 -0
  19. package/dist/talkpilot/flows/flows.setter.js.map +1 -0
  20. package/dist/talkpilot/phone_numbers/phone_numbers.getter.d.ts +1 -0
  21. package/dist/talkpilot/phone_numbers/phone_numbers.getter.d.ts.map +1 -1
  22. package/dist/talkpilot/phone_numbers/phone_numbers.getter.js +6 -1
  23. package/dist/talkpilot/phone_numbers/phone_numbers.getter.js.map +1 -1
  24. package/dist/websitalk/websitalk.setup.d.ts +3 -0
  25. package/dist/websitalk/websitalk.setup.d.ts.map +1 -0
  26. package/dist/websitalk/websitalk.setup.js +34 -0
  27. package/dist/websitalk/websitalk.setup.js.map +1 -0
  28. package/dist/websitalk/websiteUrls/websiteUrls.constants.d.ts +2 -0
  29. package/dist/websitalk/websiteUrls/websiteUrls.constants.d.ts.map +1 -0
  30. package/dist/websitalk/websiteUrls/websiteUrls.constants.js +5 -0
  31. package/dist/websitalk/websiteUrls/websiteUrls.constants.js.map +1 -0
  32. package/dist/websitalk/websiteUrls/websiteUrls.context.d.ts +11 -0
  33. package/dist/websitalk/websiteUrls/websiteUrls.context.d.ts.map +1 -0
  34. package/dist/websitalk/websiteUrls/websiteUrls.context.js +35 -0
  35. package/dist/websitalk/websiteUrls/websiteUrls.context.js.map +1 -0
  36. package/dist/websitalk/websiteUrls/websiteUrls.setters.d.ts +7 -0
  37. package/dist/websitalk/websiteUrls/websiteUrls.setters.d.ts.map +1 -0
  38. package/dist/websitalk/websiteUrls/websiteUrls.setters.js +29 -0
  39. package/dist/websitalk/websiteUrls/websiteUrls.setters.js.map +1 -0
  40. package/jest.config.js +20 -20
  41. package/package.json +46 -46
  42. package/src/__tests__/setup.ts +20 -20
  43. package/src/connection.ts +54 -54
  44. package/src/index.ts +27 -27
  45. package/src/municipal/__tests__/validation.spec.ts +62 -62
  46. package/src/municipal/cities/cities.getters.ts +50 -50
  47. package/src/municipal/cities/cities.types.ts +11 -11
  48. package/src/municipal/cities/index.ts +2 -2
  49. package/src/municipal/departmentsSubjects/departmentsSubjects.getters.ts +282 -282
  50. package/src/municipal/departmentsSubjects/departmentsSubjects.types.ts +72 -72
  51. package/src/municipal/departmentsSubjects/index.ts +9 -9
  52. package/src/municipal/index.ts +22 -22
  53. package/src/municipal/mongodb-client.ts +61 -61
  54. package/src/municipal/muniIssues/__tests__/muniIssues.setters.spec.ts +94 -94
  55. package/src/municipal/muniIssues/__tests__/muniIssues.setup.spec.ts +92 -92
  56. package/src/municipal/muniIssues/index.ts +17 -17
  57. package/src/municipal/muniIssues/muniIssues.constants.ts +18 -18
  58. package/src/municipal/muniIssues/muniIssues.getters.ts +24 -24
  59. package/src/municipal/muniIssues/muniIssues.schema.ts +66 -66
  60. package/src/municipal/muniIssues/muniIssues.setters.ts +24 -24
  61. package/src/municipal/muniIssues/muniIssues.setup.ts +65 -65
  62. package/src/municipal/muniIssues/muniIssues.types.ts +37 -37
  63. package/src/municipal/streets/index.ts +2 -2
  64. package/src/municipal/streets/streets.getters.ts +125 -125
  65. package/src/municipal/streets/streets.types.ts +18 -18
  66. package/src/municipal/systemInstructions/__tests__/getters.spec.ts +113 -113
  67. package/src/municipal/systemInstructions/__tests__/setters.spec.ts +274 -274
  68. package/src/municipal/systemInstructions/index.ts +7 -7
  69. package/src/municipal/systemInstructions/instructions.getters.ts +57 -57
  70. package/src/municipal/systemInstructions/instructions.setters.ts +119 -119
  71. package/src/municipal/systemInstructions/instructions.types.ts +30 -30
  72. package/src/municipal/tickets/__tests__/tickets.getters.spec.ts +30 -30
  73. package/src/municipal/tickets/__tests__/tickets.statistics.spec.ts +99 -99
  74. package/src/municipal/tickets/index.ts +9 -9
  75. package/src/municipal/tickets/tickets.constants.ts +8 -8
  76. package/src/municipal/tickets/tickets.getters.ts +121 -121
  77. package/src/municipal/tickets/tickets.statistics.aggregation.ts +110 -110
  78. package/src/municipal/tickets/tickets.statistics.getters.ts +145 -145
  79. package/src/municipal/tickets/tickets.types.ts +54 -54
  80. package/src/municipal/utils/types.ts +11 -11
  81. package/src/talkpilot/__tests__/db.spec.ts +38 -38
  82. package/src/talkpilot/__tests__/mongodb-client.spec.ts +18 -18
  83. package/src/talkpilot/__tests__/validation.spec.ts +68 -68
  84. package/src/talkpilot/agents/__tests__/agents.getters.spec.ts +29 -29
  85. package/src/talkpilot/agents/agents.getters.ts +34 -34
  86. package/src/talkpilot/agents/agents.types.ts +14 -14
  87. package/src/talkpilot/agents/index.ts +2 -2
  88. package/src/talkpilot/backgroundToolResults/__tests__/backgroundToolResults.getters.spec.ts +147 -147
  89. package/src/talkpilot/backgroundToolResults/backgroundToolResults.getters.ts +65 -65
  90. package/src/talkpilot/backgroundToolResults/backgroundToolResults.types.ts +23 -23
  91. package/src/talkpilot/backgroundToolResults/index.ts +2 -2
  92. package/src/talkpilot/calls/__tests__/callStats.utils.spec.ts +128 -128
  93. package/src/talkpilot/calls/__tests__/calls.dashboard.spec.ts +229 -229
  94. package/src/talkpilot/calls/__tests__/calls.spec.ts +283 -471
  95. package/src/talkpilot/calls/__tests__/calls.statistics.spec.ts +483 -483
  96. package/src/talkpilot/calls/calls.constants.ts +32 -49
  97. package/src/talkpilot/calls/calls.getters.ts +258 -277
  98. package/src/talkpilot/calls/calls.statistics.getters.ts +668 -668
  99. package/src/talkpilot/calls/calls.statistics.types.ts +48 -48
  100. package/src/talkpilot/calls/calls.types.ts +130 -133
  101. package/src/talkpilot/calls/dashboard/calls.dashboard.ts +295 -295
  102. package/src/talkpilot/calls/dashboard/calls.dashboard.types.ts +57 -57
  103. package/src/talkpilot/calls/index.ts +6 -6
  104. package/src/talkpilot/clientAudioBuffers/__tests__/clientAudioBuffer.getters.spec.ts +160 -160
  105. package/src/talkpilot/clientAudioBuffers/clientAudioBuffer.getters.ts +117 -117
  106. package/src/talkpilot/clientAudioBuffers/clientsAudioBuffers.types.ts +25 -25
  107. package/src/talkpilot/clientAudioBuffers/index.ts +2 -2
  108. package/src/talkpilot/clients/clients.getters.ts +16 -16
  109. package/src/talkpilot/clients/clients.types.ts +14 -14
  110. package/src/talkpilot/clients/index.ts +2 -2
  111. package/src/talkpilot/clientsConfig/__tests__/clientsConfig.getters.spec.ts +105 -105
  112. package/src/talkpilot/clientsConfig/__tests__/clientsConfig.spec.ts +186 -186
  113. package/src/talkpilot/clientsConfig/clientsConfig.getters.ts +79 -79
  114. package/src/talkpilot/clientsConfig/clientsConfig.types.ts +126 -127
  115. package/src/talkpilot/clientsConfig/index.ts +2 -2
  116. package/src/talkpilot/contextNotes/__tests__/contextNotes.getters.spec.ts +217 -217
  117. package/src/talkpilot/contextNotes/contextNotes.getters.ts +85 -85
  118. package/src/talkpilot/contextNotes/contextNotes.types.ts +20 -20
  119. package/src/talkpilot/contextNotes/index.ts +2 -2
  120. package/src/talkpilot/flows/__tests__/flows.schema.spec.ts +99 -99
  121. package/src/talkpilot/flows/flows.getter.ts +14 -14
  122. package/src/talkpilot/flows/flows.schema.ts +155 -155
  123. package/src/talkpilot/flows/flows.types.ts +189 -189
  124. package/src/talkpilot/flows/index.ts +2 -2
  125. package/src/talkpilot/groups/__tests__/groups.spec.ts +90 -90
  126. package/src/talkpilot/groups/__tests__/phone.utils.spec.ts +32 -32
  127. package/src/talkpilot/groups/groups.getters.ts +30 -30
  128. package/src/talkpilot/groups/groups.types.ts +29 -29
  129. package/src/talkpilot/groups/index.ts +3 -3
  130. package/src/talkpilot/groups/phone.utils.ts +46 -46
  131. package/src/talkpilot/index.ts +31 -31
  132. package/src/talkpilot/leads/index.ts +2 -2
  133. package/src/talkpilot/leads/leads.getter.ts +6 -6
  134. package/src/talkpilot/leads/leads.schema.ts +33 -33
  135. package/src/talkpilot/leads/leads.types.ts +20 -20
  136. package/src/talkpilot/mongodb-client.ts +78 -78
  137. package/src/talkpilot/phone_numbers/__tests__/phone_numbers.spec.ts +282 -252
  138. package/src/talkpilot/phone_numbers/index.ts +2 -2
  139. package/src/talkpilot/phone_numbers/phone_numbers.getter.ts +176 -171
  140. package/src/talkpilot/phone_numbers/phone_numbers.schema.ts +17 -17
  141. package/src/talkpilot/phone_numbers/phone_numbers.types.ts +30 -30
  142. package/src/talkpilot/plans/__tests__/plans.spec.ts +70 -70
  143. package/src/talkpilot/plans/index.ts +2 -2
  144. package/src/talkpilot/plans/plans.getters.ts +132 -132
  145. package/src/talkpilot/plans/plans.types.ts +89 -89
  146. package/src/talkpilot/products/__tests__/products.getters.spec.ts +44 -44
  147. package/src/talkpilot/products/index.ts +2 -2
  148. package/src/talkpilot/products/products.getters.ts +12 -12
  149. package/src/talkpilot/products/products.types.ts +9 -9
  150. package/src/talkpilot/results/index.ts +7 -7
  151. package/src/talkpilot/results/results.getter.ts +39 -39
  152. package/src/talkpilot/results/results.schema.ts +25 -25
  153. package/src/talkpilot/results/results.types.ts +34 -34
  154. package/src/talkpilot/retry_analyze/__tests__/retryAnalyze.getters.spec.ts +156 -156
  155. package/src/talkpilot/retry_analyze/index.ts +2 -2
  156. package/src/talkpilot/retry_analyze/retryAnalyze.getters.ts +84 -84
  157. package/src/talkpilot/retry_analyze/retryAnalyze.types.ts +13 -13
  158. package/src/talkpilot/sessions/__tests__/sessions.spec.ts +147 -147
  159. package/src/talkpilot/sessions/index.ts +2 -2
  160. package/src/talkpilot/sessions/sessions.getter.ts +92 -92
  161. package/src/talkpilot/sessions/sessions.schema.ts +34 -34
  162. package/src/talkpilot/sessions/sessions.types.ts +30 -30
  163. package/src/talkpilot/subscriptions/__tests__/subscriptions.getters.utils.spec.ts +45 -45
  164. package/src/talkpilot/subscriptions/index.ts +3 -3
  165. package/src/talkpilot/subscriptions/subscriptions.getters.ts +146 -146
  166. package/src/talkpilot/subscriptions/subscriptions.getters.utils.ts +33 -33
  167. package/src/talkpilot/subscriptions/subscriptions.types.ts +66 -66
  168. package/src/talkpilot/utils/__tests__/query.utils.spec.ts +49 -49
  169. package/src/talkpilot/utils/query.utils.ts +21 -21
  170. package/src/test-utils/db-utils.ts +26 -26
  171. package/src/test-utils/factories/index.ts +16 -16
  172. package/src/test-utils/factories/municipal/cities.ts +16 -16
  173. package/src/test-utils/factories/municipal/departmentsSubjects.ts +37 -37
  174. package/src/test-utils/factories/municipal/muniIssues.ts +32 -32
  175. package/src/test-utils/factories/municipal/streets.ts +22 -22
  176. package/src/test-utils/factories/municipal/tickets.ts +39 -39
  177. package/src/test-utils/factories/talkpilot/agents.ts +19 -19
  178. package/src/test-utils/factories/talkpilot/calls.ts +37 -37
  179. package/src/test-utils/factories/talkpilot/clientAudioBuffers.ts +20 -20
  180. package/src/test-utils/factories/talkpilot/clientsConfig.ts +18 -18
  181. package/src/test-utils/factories/talkpilot/contextNotes.ts +40 -40
  182. package/src/test-utils/factories/talkpilot/flows.ts +33 -33
  183. package/src/test-utils/factories/talkpilot/groups.ts +33 -33
  184. package/src/test-utils/factories/talkpilot/phone_numbers.ts +22 -22
  185. package/src/test-utils/factories/talkpilot/sessions.ts +35 -35
  186. package/src/test-utils/factories/websitalk/scans.ts +24 -24
  187. package/src/test-utils/factories/websitalk/websiteUrls.ts +17 -17
  188. package/src/utils/date.utils.ts +126 -126
  189. package/src/utils/shared.types.ts +4 -4
  190. package/src/utils/validation.ts +23 -23
  191. package/src/websitalk/index.ts +16 -16
  192. package/src/websitalk/mongodb-client.ts +61 -61
  193. package/src/websitalk/scans/__tests__/scans.spec.ts +313 -313
  194. package/src/websitalk/scans/index.ts +4 -4
  195. package/src/websitalk/scans/scans.constants.ts +15 -15
  196. package/src/websitalk/scans/scans.getters.ts +160 -160
  197. package/src/websitalk/scans/scans.types.ts +45 -45
  198. package/src/websitalk/scans/scans.utils.ts +5 -5
  199. package/src/websitalk/websiteUrls/__tests__/websiteUrls.spec.ts +77 -77
  200. package/src/websitalk/websiteUrls/index.ts +2 -2
  201. package/src/websitalk/websiteUrls/websiteUrls.getters.ts +65 -65
  202. package/src/websitalk/websiteUrls/websiteUrls.types.ts +13 -13
  203. package/tsconfig.json +23 -23
  204. package/.claude/settings.local.json +0 -13
  205. package/dist/talkpilot/leads/leads.setter.d.ts +0 -4
  206. package/dist/talkpilot/leads/leads.setter.d.ts.map +0 -1
  207. package/dist/talkpilot/leads/leads.setter.js +0 -16
  208. package/dist/talkpilot/leads/leads.setter.js.map +0 -1
@@ -1,57 +1,57 @@
1
- export type DashboardHeatmapMetric = {
2
- hour: number;
3
- calls: number;
4
- };
5
-
6
- export type DashboardDailyTrendMetric = {
7
- date: string;
8
- completed: number;
9
- };
10
-
11
- export type DashboardVolumeGranularity =
12
- | "hour"
13
- | "day"
14
- | "week"
15
- | "month"
16
- | "quarter"
17
- | "year";
18
-
19
- export type DashboardSummaryMetrics = {
20
- totalCalls: number;
21
- avgDurationSeconds: number;
22
- timeSavedMinutes: number;
23
- completedCount: number;
24
- inCallCount: number;
25
- };
26
-
27
- export type DashboardVisualData = {
28
- volumeData: DashboardDailyTrendMetric[];
29
- volumeGranularity: DashboardVolumeGranularity;
30
- };
31
-
32
- export type DashboardReportQuery = {
33
- clientId: string;
34
- startDate: string;
35
- endDate: string;
36
- granularity?: DashboardVolumeGranularity;
37
- };
38
-
39
- export type DashboardReportResponse = {
40
- kpis: DashboardSummaryMetrics;
41
- charts: DashboardVisualData;
42
- };
43
- type RawKpiResult = {
44
- completedCount: number;
45
- inCallCount: number;
46
- answeredDuration: number | null;
47
- };
48
-
49
- export type RawVolumeAggregationResult = {
50
- _id: string;
51
- completed: number;
52
- };
53
-
54
- export interface DashboardAggregationResult {
55
- kpis: RawKpiResult[];
56
- volumeData: RawVolumeAggregationResult[];
57
- }
1
+ export type DashboardHeatmapMetric = {
2
+ hour: number;
3
+ calls: number;
4
+ };
5
+
6
+ export type DashboardDailyTrendMetric = {
7
+ date: string;
8
+ completed: number;
9
+ };
10
+
11
+ export type DashboardVolumeGranularity =
12
+ | "hour"
13
+ | "day"
14
+ | "week"
15
+ | "month"
16
+ | "quarter"
17
+ | "year";
18
+
19
+ export type DashboardSummaryMetrics = {
20
+ totalCalls: number;
21
+ avgDurationSeconds: number;
22
+ timeSavedMinutes: number;
23
+ completedCount: number;
24
+ inCallCount: number;
25
+ };
26
+
27
+ export type DashboardVisualData = {
28
+ volumeData: DashboardDailyTrendMetric[];
29
+ volumeGranularity: DashboardVolumeGranularity;
30
+ };
31
+
32
+ export type DashboardReportQuery = {
33
+ clientId: string;
34
+ startDate: string;
35
+ endDate: string;
36
+ granularity?: DashboardVolumeGranularity;
37
+ };
38
+
39
+ export type DashboardReportResponse = {
40
+ kpis: DashboardSummaryMetrics;
41
+ charts: DashboardVisualData;
42
+ };
43
+ type RawKpiResult = {
44
+ completedCount: number;
45
+ inCallCount: number;
46
+ answeredDuration: number | null;
47
+ };
48
+
49
+ export type RawVolumeAggregationResult = {
50
+ _id: string;
51
+ completed: number;
52
+ };
53
+
54
+ export interface DashboardAggregationResult {
55
+ kpis: RawKpiResult[];
56
+ volumeData: RawVolumeAggregationResult[];
57
+ }
@@ -1,6 +1,6 @@
1
- export * from "./calls.constants";
2
- export * from "./calls.types";
3
- export * from "./calls.getters";
4
- export * from "./calls.statistics.types";
5
- export * from "./calls.statistics.getters";
6
- export * from "./dashboard/calls.dashboard";
1
+ export * from "./calls.constants";
2
+ export * from "./calls.types";
3
+ export * from "./calls.getters";
4
+ export * from "./calls.statistics.types";
5
+ export * from "./calls.statistics.getters";
6
+ export * from "./dashboard/calls.dashboard";
@@ -1,160 +1,160 @@
1
- import {
2
- getClientAudioBuffersCollection,
3
- insertClientAudioBuffer,
4
- findClientAudioBuffersByCallSidAndRange,
5
- getMergedAudioByCallSid,
6
- getAudioChunksByCallSid,
7
- } from "../clientAudioBuffer.getters";
8
- import { ObjectId } from "../../index";
9
- import { createAudioBufferInput } from "../../../test-utils/factories";
10
-
11
- describe("clientAudioBuffers getters", () => {
12
- it('should return the "clientAudioBuffers" collection', () => {
13
- const collection = getClientAudioBuffersCollection();
14
- expect(collection.collectionName).toBe("clientAudioBuffers");
15
- });
16
-
17
- it("should insert a client audio buffer and return insertedId", async () => {
18
- const inputToCheck = createAudioBufferInput();
19
- const result = await insertClientAudioBuffer(inputToCheck);
20
- expect(result.insertedId).toBeInstanceOf(ObjectId);
21
-
22
- const savedDoc = await getClientAudioBuffersCollection().findOne({
23
- _id: result.insertedId,
24
- });
25
- expect(savedDoc).toBeDefined();
26
- expect(savedDoc?.createdAt).toBeInstanceOf(Date);
27
- expect(savedDoc?.expiresAt).toBeInstanceOf(Date);
28
- });
29
-
30
- it("should return only buffers in the specified bucketStartMs range", async () => {
31
- const callSid = "CA1234567890abcdef1234567890abcdef";
32
- await insertClientAudioBuffer(
33
- createAudioBufferInput({ callSid, bucketStartMs: 500 }),
34
- );
35
- await insertClientAudioBuffer(
36
- createAudioBufferInput({ callSid, bucketStartMs: 1000 }),
37
- );
38
- await insertClientAudioBuffer(
39
- createAudioBufferInput({ callSid, bucketStartMs: 3000 }),
40
- );
41
- await insertClientAudioBuffer(
42
- createAudioBufferInput({ callSid, bucketStartMs: 6000 }),
43
- );
44
-
45
- const result = await findClientAudioBuffersByCallSidAndRange(
46
- callSid,
47
- 500,
48
- 3000,
49
- );
50
- expect(result).toHaveLength(3);
51
- const bucketStartValues = result.map((doc) => doc.bucketStartMs);
52
- const bucketStartsSorted = bucketStartValues.sort((a, b) => a - b);
53
- expect(bucketStartsSorted).toEqual([500, 1000, 3000]);
54
- });
55
-
56
- it("should return all buffers when no range is provided", async () => {
57
- const callSid = "CA1234567890abcdef1234567890abcdeg";
58
- await insertClientAudioBuffer(
59
- createAudioBufferInput({ callSid, bucketStartMs: 500 }),
60
- );
61
- await insertClientAudioBuffer(
62
- createAudioBufferInput({ callSid, bucketStartMs: 1000 }),
63
- );
64
- await insertClientAudioBuffer(
65
- createAudioBufferInput({ callSid, bucketStartMs: 3000 }),
66
- );
67
-
68
- const result = await findClientAudioBuffersByCallSidAndRange(callSid);
69
- expect(result).toHaveLength(3);
70
- const bucketStartValues = result.map((doc) => doc.bucketStartMs);
71
- const bucketStartsSorted = bucketStartValues.sort((a, b) => a - b);
72
- expect(bucketStartsSorted).toEqual([500, 1000, 3000]);
73
- });
74
-
75
- it("should merge audio buffers by callSid in chronological order", async () => {
76
- const callSid = "CA1234567890abcdef1234567890abcdeh";
77
-
78
- const firstBuffer = Buffer.from([1, 2]);
79
- const secondBuffer = Buffer.from([3]);
80
- const thirdBuffer = Buffer.from([4, 5]);
81
-
82
- await insertClientAudioBuffer(
83
- createAudioBufferInput({
84
- callSid,
85
- bucketStartMs: 1000,
86
- data: secondBuffer,
87
- }),
88
- );
89
- await insertClientAudioBuffer(
90
- createAudioBufferInput({
91
- callSid,
92
- bucketStartMs: 500,
93
- data: firstBuffer,
94
- }),
95
- );
96
- await insertClientAudioBuffer(
97
- createAudioBufferInput({
98
- callSid,
99
- bucketStartMs: 3000,
100
- data: thirdBuffer,
101
- }),
102
- );
103
-
104
- const merged = await getMergedAudioByCallSid(callSid, 10);
105
- const expected = Buffer.concat([firstBuffer, secondBuffer, thirdBuffer]);
106
-
107
- expect(merged).toBeInstanceOf(Buffer);
108
- expect(merged.length).toBe(expected.length);
109
- expect(merged.equals(expected)).toBe(true);
110
- });
111
-
112
- it("should return all audio chunks when less than or equal to limit buffers exist", async () => {
113
- const callSid = "CA1234567890abcdef1234567890abclt";
114
-
115
- const limit = 30;
116
- const buffers: Buffer[] = [];
117
- for (let i = 0; i < limit; i++) {
118
- const buf = Buffer.from([i]);
119
- buffers.push(buf);
120
- await insertClientAudioBuffer(
121
- createAudioBufferInput({
122
- callSid,
123
- bucketStartMs: 1000 + i * 1000,
124
- data: buf,
125
- }),
126
- );
127
- }
128
-
129
- const chunks = await getAudioChunksByCallSid(callSid, limit);
130
-
131
- expect(chunks).toHaveLength(buffers.length);
132
- expect(chunks.every((chunk) => chunk instanceof Buffer)).toBe(true);
133
- expect(Buffer.concat(chunks).equals(Buffer.concat(buffers))).toBe(true);
134
- });
135
-
136
- it("should return only the last N audio chunks when more than limit buffers exist", async () => {
137
- const callSid = "CA1234567890abcdef1234567890abclm";
138
-
139
- const limit = 30;
140
- const buffers: Buffer[] = [];
141
- for (let i = 0; i < 35; i++) {
142
- const buf = Buffer.from([i]);
143
- buffers.push(buf);
144
- await insertClientAudioBuffer(
145
- createAudioBufferInput({
146
- callSid,
147
- bucketStartMs: 1000 + i * 1000,
148
- data: buf,
149
- }),
150
- );
151
- }
152
-
153
- const chunks = await getAudioChunksByCallSid(callSid, limit);
154
- const expectedBuffers = buffers.slice(-limit);
155
- expect(chunks).toHaveLength(expectedBuffers.length);
156
- expect(Buffer.concat(chunks).equals(Buffer.concat(expectedBuffers))).toBe(
157
- true,
158
- );
159
- });
160
- });
1
+ import {
2
+ getClientAudioBuffersCollection,
3
+ insertClientAudioBuffer,
4
+ findClientAudioBuffersByCallSidAndRange,
5
+ getMergedAudioByCallSid,
6
+ getAudioChunksByCallSid,
7
+ } from "../clientAudioBuffer.getters";
8
+ import { ObjectId } from "../../index";
9
+ import { createAudioBufferInput } from "../../../test-utils/factories";
10
+
11
+ describe("clientAudioBuffers getters", () => {
12
+ it('should return the "clientAudioBuffers" collection', () => {
13
+ const collection = getClientAudioBuffersCollection();
14
+ expect(collection.collectionName).toBe("clientAudioBuffers");
15
+ });
16
+
17
+ it("should insert a client audio buffer and return insertedId", async () => {
18
+ const inputToCheck = createAudioBufferInput();
19
+ const result = await insertClientAudioBuffer(inputToCheck);
20
+ expect(result.insertedId).toBeInstanceOf(ObjectId);
21
+
22
+ const savedDoc = await getClientAudioBuffersCollection().findOne({
23
+ _id: result.insertedId,
24
+ });
25
+ expect(savedDoc).toBeDefined();
26
+ expect(savedDoc?.createdAt).toBeInstanceOf(Date);
27
+ expect(savedDoc?.expiresAt).toBeInstanceOf(Date);
28
+ });
29
+
30
+ it("should return only buffers in the specified bucketStartMs range", async () => {
31
+ const callSid = "CA1234567890abcdef1234567890abcdef";
32
+ await insertClientAudioBuffer(
33
+ createAudioBufferInput({ callSid, bucketStartMs: 500 }),
34
+ );
35
+ await insertClientAudioBuffer(
36
+ createAudioBufferInput({ callSid, bucketStartMs: 1000 }),
37
+ );
38
+ await insertClientAudioBuffer(
39
+ createAudioBufferInput({ callSid, bucketStartMs: 3000 }),
40
+ );
41
+ await insertClientAudioBuffer(
42
+ createAudioBufferInput({ callSid, bucketStartMs: 6000 }),
43
+ );
44
+
45
+ const result = await findClientAudioBuffersByCallSidAndRange(
46
+ callSid,
47
+ 500,
48
+ 3000,
49
+ );
50
+ expect(result).toHaveLength(3);
51
+ const bucketStartValues = result.map((doc) => doc.bucketStartMs);
52
+ const bucketStartsSorted = bucketStartValues.sort((a, b) => a - b);
53
+ expect(bucketStartsSorted).toEqual([500, 1000, 3000]);
54
+ });
55
+
56
+ it("should return all buffers when no range is provided", async () => {
57
+ const callSid = "CA1234567890abcdef1234567890abcdeg";
58
+ await insertClientAudioBuffer(
59
+ createAudioBufferInput({ callSid, bucketStartMs: 500 }),
60
+ );
61
+ await insertClientAudioBuffer(
62
+ createAudioBufferInput({ callSid, bucketStartMs: 1000 }),
63
+ );
64
+ await insertClientAudioBuffer(
65
+ createAudioBufferInput({ callSid, bucketStartMs: 3000 }),
66
+ );
67
+
68
+ const result = await findClientAudioBuffersByCallSidAndRange(callSid);
69
+ expect(result).toHaveLength(3);
70
+ const bucketStartValues = result.map((doc) => doc.bucketStartMs);
71
+ const bucketStartsSorted = bucketStartValues.sort((a, b) => a - b);
72
+ expect(bucketStartsSorted).toEqual([500, 1000, 3000]);
73
+ });
74
+
75
+ it("should merge audio buffers by callSid in chronological order", async () => {
76
+ const callSid = "CA1234567890abcdef1234567890abcdeh";
77
+
78
+ const firstBuffer = Buffer.from([1, 2]);
79
+ const secondBuffer = Buffer.from([3]);
80
+ const thirdBuffer = Buffer.from([4, 5]);
81
+
82
+ await insertClientAudioBuffer(
83
+ createAudioBufferInput({
84
+ callSid,
85
+ bucketStartMs: 1000,
86
+ data: secondBuffer,
87
+ }),
88
+ );
89
+ await insertClientAudioBuffer(
90
+ createAudioBufferInput({
91
+ callSid,
92
+ bucketStartMs: 500,
93
+ data: firstBuffer,
94
+ }),
95
+ );
96
+ await insertClientAudioBuffer(
97
+ createAudioBufferInput({
98
+ callSid,
99
+ bucketStartMs: 3000,
100
+ data: thirdBuffer,
101
+ }),
102
+ );
103
+
104
+ const merged = await getMergedAudioByCallSid(callSid, 10);
105
+ const expected = Buffer.concat([firstBuffer, secondBuffer, thirdBuffer]);
106
+
107
+ expect(merged).toBeInstanceOf(Buffer);
108
+ expect(merged.length).toBe(expected.length);
109
+ expect(merged.equals(expected)).toBe(true);
110
+ });
111
+
112
+ it("should return all audio chunks when less than or equal to limit buffers exist", async () => {
113
+ const callSid = "CA1234567890abcdef1234567890abclt";
114
+
115
+ const limit = 30;
116
+ const buffers: Buffer[] = [];
117
+ for (let i = 0; i < limit; i++) {
118
+ const buf = Buffer.from([i]);
119
+ buffers.push(buf);
120
+ await insertClientAudioBuffer(
121
+ createAudioBufferInput({
122
+ callSid,
123
+ bucketStartMs: 1000 + i * 1000,
124
+ data: buf,
125
+ }),
126
+ );
127
+ }
128
+
129
+ const chunks = await getAudioChunksByCallSid(callSid, limit);
130
+
131
+ expect(chunks).toHaveLength(buffers.length);
132
+ expect(chunks.every((chunk) => chunk instanceof Buffer)).toBe(true);
133
+ expect(Buffer.concat(chunks).equals(Buffer.concat(buffers))).toBe(true);
134
+ });
135
+
136
+ it("should return only the last N audio chunks when more than limit buffers exist", async () => {
137
+ const callSid = "CA1234567890abcdef1234567890abclm";
138
+
139
+ const limit = 30;
140
+ const buffers: Buffer[] = [];
141
+ for (let i = 0; i < 35; i++) {
142
+ const buf = Buffer.from([i]);
143
+ buffers.push(buf);
144
+ await insertClientAudioBuffer(
145
+ createAudioBufferInput({
146
+ callSid,
147
+ bucketStartMs: 1000 + i * 1000,
148
+ data: buf,
149
+ }),
150
+ );
151
+ }
152
+
153
+ const chunks = await getAudioChunksByCallSid(callSid, limit);
154
+ const expectedBuffers = buffers.slice(-limit);
155
+ expect(chunks).toHaveLength(expectedBuffers.length);
156
+ expect(Buffer.concat(chunks).equals(Buffer.concat(expectedBuffers))).toBe(
157
+ true,
158
+ );
159
+ });
160
+ });