@talkpilot/core-db 1.3.1 → 1.3.4

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 (102) hide show
  1. package/.claude/settings.local.json +7 -0
  2. package/README.md +30 -0
  3. package/dist/municipal/tickets/index.d.ts +2 -1
  4. package/dist/municipal/tickets/index.d.ts.map +1 -1
  5. package/dist/municipal/tickets/index.js +1 -0
  6. package/dist/municipal/tickets/index.js.map +1 -1
  7. package/dist/municipal/tickets/tickets.constants.d.ts +7 -0
  8. package/dist/municipal/tickets/tickets.constants.d.ts.map +1 -0
  9. package/dist/municipal/tickets/tickets.constants.js +10 -0
  10. package/dist/municipal/tickets/tickets.constants.js.map +1 -0
  11. package/dist/municipal/tickets/tickets.deprecated.getters.d.ts +12 -0
  12. package/dist/municipal/tickets/tickets.deprecated.getters.d.ts.map +1 -0
  13. package/dist/municipal/tickets/tickets.deprecated.getters.js +131 -0
  14. package/dist/municipal/tickets/tickets.deprecated.getters.js.map +1 -0
  15. package/dist/municipal/tickets/tickets.getters.d.ts +0 -11
  16. package/dist/municipal/tickets/tickets.getters.d.ts.map +1 -1
  17. package/dist/municipal/tickets/tickets.getters.js +0 -128
  18. package/dist/municipal/tickets/tickets.getters.js.map +1 -1
  19. package/dist/municipal/tickets/tickets.statistics.aggregation.d.ts +35 -0
  20. package/dist/municipal/tickets/tickets.statistics.aggregation.d.ts.map +1 -0
  21. package/dist/municipal/tickets/tickets.statistics.aggregation.js +86 -0
  22. package/dist/municipal/tickets/tickets.statistics.aggregation.js.map +1 -0
  23. package/dist/municipal/tickets/tickets.statistics.dates.d.ts +7 -0
  24. package/dist/municipal/tickets/tickets.statistics.dates.d.ts.map +1 -0
  25. package/dist/municipal/tickets/tickets.statistics.dates.js +40 -0
  26. package/dist/municipal/tickets/tickets.statistics.dates.js.map +1 -0
  27. package/dist/municipal/tickets/tickets.statistics.getters.d.ts +8 -0
  28. package/dist/municipal/tickets/tickets.statistics.getters.d.ts.map +1 -0
  29. package/dist/municipal/tickets/tickets.statistics.getters.js +44 -0
  30. package/dist/municipal/tickets/tickets.statistics.getters.js.map +1 -0
  31. package/dist/municipal/tickets/tickets.statistics.pipeline.d.ts +53 -0
  32. package/dist/municipal/tickets/tickets.statistics.pipeline.d.ts.map +1 -0
  33. package/dist/municipal/tickets/tickets.statistics.pipeline.js +112 -0
  34. package/dist/municipal/tickets/tickets.statistics.pipeline.js.map +1 -0
  35. package/dist/municipal/tickets/tickets.statistics.utils.d.ts +7 -0
  36. package/dist/municipal/tickets/tickets.statistics.utils.d.ts.map +1 -0
  37. package/dist/municipal/tickets/tickets.statistics.utils.js +40 -0
  38. package/dist/municipal/tickets/tickets.statistics.utils.js.map +1 -0
  39. package/dist/municipal/tickets/tickets.types.d.ts +14 -5
  40. package/dist/municipal/tickets/tickets.types.d.ts.map +1 -1
  41. package/dist/talkpilot/calls/calls.constants.d.ts +17 -0
  42. package/dist/talkpilot/calls/calls.constants.d.ts.map +1 -0
  43. package/dist/talkpilot/calls/calls.constants.js +20 -0
  44. package/dist/talkpilot/calls/calls.constants.js.map +1 -0
  45. package/dist/talkpilot/calls/calls.statistics.getters.d.ts +28 -0
  46. package/dist/talkpilot/calls/calls.statistics.getters.d.ts.map +1 -0
  47. package/dist/talkpilot/calls/calls.statistics.getters.js +424 -0
  48. package/dist/talkpilot/calls/calls.statistics.getters.js.map +1 -0
  49. package/dist/talkpilot/calls/calls.statistics.ticketScope.d.ts +12 -0
  50. package/dist/talkpilot/calls/calls.statistics.ticketScope.d.ts.map +1 -0
  51. package/dist/talkpilot/calls/calls.statistics.ticketScope.js +37 -0
  52. package/dist/talkpilot/calls/calls.statistics.ticketScope.js.map +1 -0
  53. package/dist/talkpilot/calls/calls.statistics.tickets.d.ts +17 -0
  54. package/dist/talkpilot/calls/calls.statistics.tickets.d.ts.map +1 -0
  55. package/dist/talkpilot/calls/calls.statistics.tickets.js +33 -0
  56. package/dist/talkpilot/calls/calls.statistics.tickets.js.map +1 -0
  57. package/dist/talkpilot/calls/calls.statistics.types.d.ts +39 -0
  58. package/dist/talkpilot/calls/calls.statistics.types.d.ts.map +1 -0
  59. package/dist/talkpilot/calls/calls.statistics.types.js +3 -0
  60. package/dist/talkpilot/calls/calls.statistics.types.js.map +1 -0
  61. package/dist/talkpilot/calls/calls.types.d.ts +1 -2
  62. package/dist/talkpilot/calls/calls.types.d.ts.map +1 -1
  63. package/dist/talkpilot/calls/calls.types.js +0 -3
  64. package/dist/talkpilot/calls/calls.types.js.map +1 -1
  65. package/dist/talkpilot/calls/dashboard/calls.dashboard.d.ts +33 -1
  66. package/dist/talkpilot/calls/dashboard/calls.dashboard.d.ts.map +1 -1
  67. package/dist/talkpilot/calls/dashboard/calls.dashboard.js +131 -146
  68. package/dist/talkpilot/calls/dashboard/calls.dashboard.js.map +1 -1
  69. package/dist/talkpilot/calls/dashboard/calls.dashboard.types.d.ts +27 -6
  70. package/dist/talkpilot/calls/dashboard/calls.dashboard.types.d.ts.map +1 -1
  71. package/dist/talkpilot/calls/index.d.ts +3 -0
  72. package/dist/talkpilot/calls/index.d.ts.map +1 -1
  73. package/dist/talkpilot/calls/index.js +3 -0
  74. package/dist/talkpilot/calls/index.js.map +1 -1
  75. package/dist/utils/date.utils.d.ts +49 -0
  76. package/dist/utils/date.utils.d.ts.map +1 -0
  77. package/dist/utils/date.utils.js +103 -0
  78. package/dist/utils/date.utils.js.map +1 -0
  79. package/dist/utils/statistics.aggregation.d.ts +20 -0
  80. package/dist/utils/statistics.aggregation.d.ts.map +1 -0
  81. package/dist/utils/statistics.aggregation.js +43 -0
  82. package/dist/utils/statistics.aggregation.js.map +1 -0
  83. package/package.json +1 -1
  84. package/src/municipal/tickets/__tests__/tickets.getters.spec.ts +1 -37
  85. package/src/municipal/tickets/__tests__/tickets.statistics.spec.ts +51 -0
  86. package/src/municipal/tickets/index.ts +2 -1
  87. package/src/municipal/tickets/tickets.constants.ts +8 -0
  88. package/src/municipal/tickets/tickets.getters.ts +0 -140
  89. package/src/municipal/tickets/tickets.statistics.aggregation.ts +96 -0
  90. package/src/municipal/tickets/tickets.statistics.getters.ts +71 -0
  91. package/src/municipal/tickets/tickets.types.ts +19 -9
  92. package/src/talkpilot/calls/__tests__/calls.dashboard.spec.ts +8 -111
  93. package/src/talkpilot/calls/__tests__/calls.statistics.spec.ts +344 -0
  94. package/src/talkpilot/calls/calls.constants.ts +20 -0
  95. package/src/talkpilot/calls/calls.statistics.getters.ts +587 -0
  96. package/src/talkpilot/calls/calls.statistics.types.ts +44 -0
  97. package/src/talkpilot/calls/calls.types.ts +4 -2
  98. package/src/talkpilot/calls/dashboard/calls.dashboard.ts +148 -197
  99. package/src/talkpilot/calls/dashboard/calls.dashboard.types.ts +25 -12
  100. package/src/talkpilot/calls/index.ts +3 -0
  101. package/src/talkpilot/clientsConfig/__tests__/clientsConfig.spec.ts +7 -0
  102. package/src/utils/date.utils.ts +116 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npx jest *)"
5
+ ]
6
+ }
7
+ }
package/README.md CHANGED
@@ -127,6 +127,36 @@ Refer to `DEVELOPMENT.md` for the full walkthrough, token instructions, and fact
127
127
  - After publishing, downstream repos (`CIS`, `MIS`, `TalkPilot Server`, etc.) should run `npm update @talkpilot/core-db` so they receive the latest helpers/bug fixes.
128
128
  - Cloud Build & Cloud Run jobs that depend on this package pick up the new version the next time they rebuild their container; the services pull the compiled `dist/` output and type definitions when installing the dependency.
129
129
 
130
+
131
+
132
+ | Version | Note |
133
+ | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
134
+ | 1.1.9 | Maintenance release (build, test, format). |
135
+ | 1.3.4 | Added new statistics getters for call & ticket dashboards (CP-149): summary, trend, hourly, and routing for calls, plus open/draft/subject ticket stats. **Removed** the legacy getters `getTicketsCountByCityAndDateRange` and `getTicketsSubjectStats`. |
136
+
137
+
138
+ ### 1.1.9
139
+
140
+ 1. `npm run build`.
141
+ 2. `npm run test`.
142
+ 3. `npm run format`.
143
+
144
+ ### 1.3.4 — Call & ticket statistics (CP-149)
145
+
146
+ New call statistics getters for dashboards (summary, trend, hourly, routing) and ticket statistics scoped to the same date range (open tickets, draft tickets, subject breakdowns).
147
+
148
+ **Removed**
149
+
150
+ | Removed | Replacement |
151
+ | --- | --- |
152
+ | `getTicketsCountByCityAndDateRange` | `aggregateCallsSummary` + `findCallSidsWithTicketsByCity` |
153
+ | `getTicketsSubjectStats` | `findSubjectsByCityAndDateRange` |
154
+ | `SubjectStatsItem` | `SubjectItem` |
155
+
156
+ **Do I need to update my app?**
157
+
158
+ Yes — if you used any of the removed functions above.
159
+
130
160
  ## 🛠 CI/CD & deployment
131
161
 
132
162
  - This package is consumed by Cloud Build-based services (TalkPilot Server, MIS, CIS) as a dependency when Docker images are built. Keep `dist/` in sync with your builds because the compiled artifact is what downstream services install.
@@ -1,3 +1,4 @@
1
1
  export * from "./tickets.getters";
2
- export type { Ticket, TicketDoc, SubjectStatsItem } from "./tickets.types";
2
+ export * from "./tickets.statistics.getters";
3
+ export type { Ticket, TicketDoc, SubjectItem, TicketStatsDateScope, TicketSubjectRow } from "./tickets.types";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/municipal/tickets/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/municipal/tickets/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,8BAA8B,CAAC;AAC7C,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -15,4 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./tickets.getters"), exports);
18
+ __exportStar(require("./tickets.statistics.getters"), exports);
18
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/municipal/tickets/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAkC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/municipal/tickets/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAkC;AAClC,+DAA6C"}
@@ -0,0 +1,7 @@
1
+ /** Label used when a ticket has no resolvable department/subject. */
2
+ export declare const UNCLASSIFIED = "\u05DC\u05DC\u05D0 \u05DE\u05D7\u05DC\u05E7\u05D4";
3
+ /** Max execution time (ms) for ticket statistics aggregations. */
4
+ export declare const STATS_MAX_TIME_MS = 30000;
5
+ /** Default look-back window (days) for ticket statistics date ranges. */
6
+ export declare const DEFAULT_LOOKBACK_DAYS = 30;
7
+ //# sourceMappingURL=tickets.constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tickets.constants.d.ts","sourceRoot":"","sources":["../../../src/municipal/tickets/tickets.constants.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,eAAO,MAAM,YAAY,sDAAc,CAAC;AAExC,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC,yEAAyE;AACzE,eAAO,MAAM,qBAAqB,KAAK,CAAC"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_LOOKBACK_DAYS = exports.STATS_MAX_TIME_MS = exports.UNCLASSIFIED = void 0;
4
+ /** Label used when a ticket has no resolvable department/subject. */
5
+ exports.UNCLASSIFIED = "ללא מחלקה";
6
+ /** Max execution time (ms) for ticket statistics aggregations. */
7
+ exports.STATS_MAX_TIME_MS = 30_000;
8
+ /** Default look-back window (days) for ticket statistics date ranges. */
9
+ exports.DEFAULT_LOOKBACK_DAYS = 30;
10
+ //# sourceMappingURL=tickets.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tickets.constants.js","sourceRoot":"","sources":["../../../src/municipal/tickets/tickets.constants.ts"],"names":[],"mappings":";;;AAAA,qEAAqE;AACxD,QAAA,YAAY,GAAG,WAAW,CAAC;AAExC,kEAAkE;AACrD,QAAA,iBAAiB,GAAG,MAAM,CAAC;AAExC,yEAAyE;AAC5D,QAAA,qBAAqB,GAAG,EAAE,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { SubjectStatsItem } from "./tickets.types";
2
+ /**
3
+ * @deprecated Use `findCallSidsWithTicketsByCity` with `ticketStatsDateScopeFromYmd` instead.
4
+ * Will be removed in 3.0.0.
5
+ */
6
+ export declare function getTicketsCountByCityAndDateRange(cityName: string, startStr: string, endStr: string, timezone: string): Promise<number>;
7
+ /**
8
+ * @deprecated Use `findFilteredCallSids` + `findSubjectsByCallSids` instead.
9
+ * Will be removed in 3.0.0.
10
+ */
11
+ export declare function getTicketsSubjectStats(cityName: string, startStr: string, endStr: string, timezone: string): Promise<SubjectStatsItem[]>;
12
+ //# sourceMappingURL=tickets.deprecated.getters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tickets.deprecated.getters.d.ts","sourceRoot":"","sources":["../../../src/municipal/tickets/tickets.deprecated.getters.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD;;;GAGG;AACH,wBAAsB,iCAAiC,CACrD,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAoG7B"}
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTicketsCountByCityAndDateRange = getTicketsCountByCityAndDateRange;
4
+ exports.getTicketsSubjectStats = getTicketsSubjectStats;
5
+ const tickets_getters_1 = require("./tickets.getters");
6
+ /**
7
+ * @deprecated Use `findCallSidsWithTicketsByCity` with `ticketStatsDateScopeFromYmd` instead.
8
+ * Will be removed in 3.0.0.
9
+ */
10
+ async function getTicketsCountByCityAndDateRange(cityName, startStr, endStr, timezone) {
11
+ const doc = await (0, tickets_getters_1.getTicketsCollection)()
12
+ .aggregate([
13
+ { $match: { cityName, callSid: { $exists: true, $nin: [null, ""] } } },
14
+ {
15
+ $addFields: {
16
+ dateLocal: {
17
+ $dateToString: { format: "%Y-%m-%d", date: "$createdAt", timezone },
18
+ },
19
+ },
20
+ },
21
+ { $match: { dateLocal: { $gte: startStr, $lte: endStr } } },
22
+ { $count: "n" },
23
+ ])
24
+ .next();
25
+ return doc?.n ?? 0;
26
+ }
27
+ /**
28
+ * @deprecated Use `findFilteredCallSids` + `findSubjectsByCallSids` instead.
29
+ * Will be removed in 3.0.0.
30
+ */
31
+ async function getTicketsSubjectStats(cityName, startStr, endStr, timezone) {
32
+ const rows = await (0, tickets_getters_1.getTicketsCollection)()
33
+ .aggregate([
34
+ { $match: { cityName } },
35
+ {
36
+ $addFields: {
37
+ dateLocal: {
38
+ $dateToString: { format: "%Y-%m-%d", date: "$createdAt", timezone },
39
+ },
40
+ },
41
+ },
42
+ { $match: { dateLocal: { $gte: startStr, $lte: endStr } } },
43
+ {
44
+ $addFields: {
45
+ effectiveSubjectId: {
46
+ $ifNull: [
47
+ "$externalCallFields.event_subject_id",
48
+ {
49
+ $ifNull: [
50
+ "$externalCallFields.event_sub_subject_id",
51
+ "$externalCallFields.event_sub_subject_id2",
52
+ ],
53
+ },
54
+ ],
55
+ },
56
+ },
57
+ },
58
+ {
59
+ $lookup: {
60
+ from: "departmentsSubjects",
61
+ let: { sid: "$effectiveSubjectId", c: cityName },
62
+ pipeline: [
63
+ {
64
+ $match: {
65
+ $expr: {
66
+ $and: [
67
+ { $eq: ["$cityName", "$$c"] },
68
+ {
69
+ $or: [
70
+ { $eq: ["$subject_id", { $ifNull: ["$$sid", ""] }] },
71
+ {
72
+ $eq: ["$sub_subject_id", { $ifNull: ["$$sid", ""] }],
73
+ },
74
+ {
75
+ $eq: ["$sub_subject_id2", { $ifNull: ["$$sid", ""] }],
76
+ },
77
+ ],
78
+ },
79
+ ],
80
+ },
81
+ },
82
+ },
83
+ { $limit: 1 },
84
+ ],
85
+ as: "subj",
86
+ },
87
+ },
88
+ {
89
+ $addFields: {
90
+ subject_id: {
91
+ $cond: {
92
+ if: { $gt: [{ $size: "$subj" }, 0] },
93
+ then: {
94
+ $ifNull: [{ $arrayElemAt: ["$subj.subject_id", 0] }, ""],
95
+ },
96
+ else: "",
97
+ },
98
+ },
99
+ subject: {
100
+ $cond: {
101
+ if: { $gt: [{ $size: "$subj" }, 0] },
102
+ then: {
103
+ $ifNull: [
104
+ { $arrayElemAt: ["$subj.subjectName", 0] },
105
+ "Unclassified",
106
+ ],
107
+ },
108
+ else: "Unclassified",
109
+ },
110
+ },
111
+ },
112
+ },
113
+ {
114
+ $group: {
115
+ _id: "$subject_id",
116
+ subject: { $first: "$subject" },
117
+ count: { $sum: 1 },
118
+ },
119
+ },
120
+ { $sort: { count: -1 } },
121
+ ])
122
+ .toArray();
123
+ const total = rows.reduce((sum, row) => sum + row.count, 0);
124
+ return rows.map((row) => ({
125
+ subject_name: row.subject,
126
+ subject_id: row._id,
127
+ count: row.count,
128
+ percentage: total > 0 ? Math.round((row.count / total) * 100) : 0,
129
+ }));
130
+ }
131
+ //# sourceMappingURL=tickets.deprecated.getters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tickets.deprecated.getters.js","sourceRoot":"","sources":["../../../src/municipal/tickets/tickets.deprecated.getters.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  import { CityName, Ticket } from "../index";
2
- import type { SubjectStatsItem } from "./tickets.types";
3
2
  import { Collection, Filter, ObjectId as MongoObjectId } from "mongodb";
4
3
  /**
5
4
  * Generate a new ticket ID as a string
@@ -13,16 +12,6 @@ export declare const getTicketById: (ticketId: string) => Promise<Ticket | null>
13
12
  export declare const createTicket: (ticketData: Omit<Ticket, "_id" | "createdAt" | "updatedAt">, ticketId?: string) => Promise<MongoObjectId>;
14
13
  export declare const updateTicket: (ticketId: string, data: Partial<Omit<Ticket, "_id" | "createdAt" | "updatedAt">>) => Promise<Ticket | null>;
15
14
  export declare const deleteTicket: (ticketId: string) => Promise<boolean>;
16
- /**
17
- * Count tickets by city and date range (createdAt converted to given timezone).
18
- * Used as "open" tickets count when status is not available.
19
- */
20
- export declare function getTicketsCountByCityAndDateRange(cityName: string, startStr: string, endStr: string, timezone: string): Promise<number>;
21
- /**
22
- * Count of tickets by department (subject) from departmentsSubjects. Different departments (subject_id) are grouped, and sub-subjects are unified under their department.
23
- * Date filter: createdAt in [startStr, endStr] (in the given timezone). Fallback to "Unclassified" when no match is found in the lookup.
24
- */
25
- export declare function getTicketsSubjectStats(cityName: string, startStr: string, endStr: string, timezone: string): Promise<SubjectStatsItem[]>;
26
15
  export declare const findTicketByQuery: (query: Partial<Ticket>) => Promise<import("mongodb").WithId<Ticket> | null>;
27
16
  /**
28
17
  * Update ticket files by external call number
@@ -1 +1 @@
1
- {"version":3,"file":"tickets.getters.d.ts","sourceRoot":"","sources":["../../../src/municipal/tickets/tickets.getters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAmB,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,SAAS,CAAC;AAExE;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAO,MAEnC,CAAC;AAEF,eAAO,MAAM,oBAAoB,QAAO,UAAU,CAAC,MAAM,CAExD,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,SAAQ,MAAM,CAAC,MAAM,CAAM,KAC1B,OAAO,CAAC,MAAM,EAAE,CAElB,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,SAAS,MAAM,KACd,OAAO,CAAC,MAAM,EAAE,CAElB,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,UAAU,MAAM,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAKvB,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,YAAY,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,WAAW,GAAG,WAAW,CAAC,EAC3D,WAAW,MAAM,KAChB,OAAO,CAAC,aAAa,CASvB,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,UAAU,MAAM,EAChB,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC,KAC7D,OAAO,CAAC,MAAM,GAAG,IAAI,CAOvB,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,OAAO,CAKpE,CAAC;AAEF;;;GAGG;AACH,wBAAsB,iCAAiC,CACrD,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAqG7B;AAED,eAAO,MAAM,iBAAiB,GAAU,OAAO,OAAO,CAAC,MAAM,CAAC,qDAE7D,CAAC;AACF;;GAEG;AACH,eAAO,MAAM,6BAA6B,GAAU,QAAQ;IAC1D,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,KAAG,OAAO,CAAC,OAAO,CAsBlB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,GAAU,QAAQ;IACtD,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,KAAG,OAAO,CAAC,OAAO,CASlB,CAAC"}
1
+ {"version":3,"file":"tickets.getters.d.ts","sourceRoot":"","sources":["../../../src/municipal/tickets/tickets.getters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAmB,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,SAAS,CAAC;AAExE;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAO,MAEnC,CAAC;AAEF,eAAO,MAAM,oBAAoB,QAAO,UAAU,CAAC,MAAM,CAExD,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,SAAQ,MAAM,CAAC,MAAM,CAAM,KAC1B,OAAO,CAAC,MAAM,EAAE,CAElB,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,SAAS,MAAM,KACd,OAAO,CAAC,MAAM,EAAE,CAElB,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,UAAU,MAAM,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAKvB,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,YAAY,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,WAAW,GAAG,WAAW,CAAC,EAC3D,WAAW,MAAM,KAChB,OAAO,CAAC,aAAa,CASvB,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,UAAU,MAAM,EAChB,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC,KAC7D,OAAO,CAAC,MAAM,GAAG,IAAI,CAOvB,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,OAAO,CAKpE,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,OAAO,OAAO,CAAC,MAAM,CAAC,qDAE7D,CAAC;AACF;;GAEG;AACH,eAAO,MAAM,6BAA6B,GAAU,QAAQ;IAC1D,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,KAAG,OAAO,CAAC,OAAO,CAsBlB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,GAAU,QAAQ;IACtD,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,KAAG,OAAO,CAAC,OAAO,CASlB,CAAC"}
@@ -1,8 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.clearGuestJwtByCallNumber = exports.updateTicketFilesByCallNumber = exports.findTicketByQuery = exports.deleteTicket = exports.updateTicket = exports.createTicket = exports.getTicketById = exports.findTicketsByCallSid = exports.findTickets = exports.getTicketsCollection = exports.generateTicketId = void 0;
4
- exports.getTicketsCountByCityAndDateRange = getTicketsCountByCityAndDateRange;
5
- exports.getTicketsSubjectStats = getTicketsSubjectStats;
6
4
  const index_1 = require("../index");
7
5
  /**
8
6
  * Generate a new ticket ID as a string
@@ -54,132 +52,6 @@ const deleteTicket = async (ticketId) => {
54
52
  return result.deletedCount > 0;
55
53
  };
56
54
  exports.deleteTicket = deleteTicket;
57
- /**
58
- * Count tickets by city and date range (createdAt converted to given timezone).
59
- * Used as "open" tickets count when status is not available.
60
- */
61
- async function getTicketsCountByCityAndDateRange(cityName, startStr, endStr, timezone) {
62
- const doc = await (0, exports.getTicketsCollection)()
63
- .aggregate([
64
- { $match: { cityName, callSid: { $exists: true, $nin: [null, ""] } } },
65
- {
66
- $addFields: {
67
- dateLocal: {
68
- $dateToString: { format: "%Y-%m-%d", date: "$createdAt", timezone },
69
- },
70
- },
71
- },
72
- { $match: { dateLocal: { $gte: startStr, $lte: endStr } } },
73
- { $count: "n" },
74
- ])
75
- .next();
76
- return doc?.n ?? 0;
77
- }
78
- /**
79
- * Count of tickets by department (subject) from departmentsSubjects. Different departments (subject_id) are grouped, and sub-subjects are unified under their department.
80
- * Date filter: createdAt in [startStr, endStr] (in the given timezone). Fallback to "Unclassified" when no match is found in the lookup.
81
- */
82
- async function getTicketsSubjectStats(cityName, startStr, endStr, timezone) {
83
- const coll = (0, exports.getTicketsCollection)();
84
- const rows = await coll
85
- .aggregate([
86
- { $match: { cityName } },
87
- {
88
- $addFields: {
89
- dateLocal: {
90
- $dateToString: { format: "%Y-%m-%d", date: "$createdAt", timezone },
91
- },
92
- },
93
- },
94
- { $match: { dateLocal: { $gte: startStr, $lte: endStr } } },
95
- {
96
- $addFields: {
97
- effectiveSubjectId: {
98
- $ifNull: [
99
- "$externalCallFields.event_subject_id",
100
- {
101
- $ifNull: [
102
- "$externalCallFields.event_sub_subject_id",
103
- "$externalCallFields.event_sub_subject_id2",
104
- ],
105
- },
106
- ],
107
- },
108
- },
109
- },
110
- {
111
- $lookup: {
112
- from: "departmentsSubjects",
113
- let: { sid: "$effectiveSubjectId", c: cityName },
114
- pipeline: [
115
- {
116
- $match: {
117
- $expr: {
118
- $and: [
119
- { $eq: ["$cityName", "$$c"] },
120
- {
121
- $or: [
122
- { $eq: ["$subject_id", { $ifNull: ["$$sid", ""] }] },
123
- {
124
- $eq: ["$sub_subject_id", { $ifNull: ["$$sid", ""] }],
125
- },
126
- {
127
- $eq: ["$sub_subject_id2", { $ifNull: ["$$sid", ""] }],
128
- },
129
- ],
130
- },
131
- ],
132
- },
133
- },
134
- },
135
- { $limit: 1 },
136
- ],
137
- as: "subj",
138
- },
139
- },
140
- {
141
- $addFields: {
142
- subject_id: {
143
- $cond: {
144
- if: { $gt: [{ $size: "$subj" }, 0] },
145
- then: {
146
- $ifNull: [{ $arrayElemAt: ["$subj.subject_id", 0] }, ""],
147
- },
148
- else: "",
149
- },
150
- },
151
- subject: {
152
- $cond: {
153
- if: { $gt: [{ $size: "$subj" }, 0] },
154
- then: {
155
- $ifNull: [
156
- { $arrayElemAt: ["$subj.subjectName", 0] },
157
- "Unclassified",
158
- ],
159
- },
160
- else: "Unclassified",
161
- },
162
- },
163
- },
164
- },
165
- {
166
- $group: {
167
- _id: "$subject_id",
168
- subject: { $first: "$subject" },
169
- count: { $sum: 1 },
170
- },
171
- },
172
- { $sort: { count: -1 } },
173
- ])
174
- .toArray();
175
- const total = rows.reduce((s, r) => s + r.count, 0);
176
- return rows.map((r) => ({
177
- subject_name: r.subject,
178
- subject_id: r._id,
179
- count: r.count,
180
- percentage: total > 0 ? Math.round((r.count / total) * 100) : 0,
181
- }));
182
- }
183
55
  const findTicketByQuery = async (query) => {
184
56
  return await (0, exports.getTicketsCollection)().findOne(query);
185
57
  };
@@ -1 +1 @@
1
- {"version":3,"file":"tickets.getters.js","sourceRoot":"","sources":["../../../src/municipal/tickets/tickets.getters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tickets.getters.js","sourceRoot":"","sources":["../../../src/municipal/tickets/tickets.getters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { CityName } from "../utils/types";
2
+ import type { TicketStatsDateRange } from "./tickets.types";
3
+ export declare const isDraftSubjectIdExpr: {
4
+ $or: ({
5
+ $eq: (string | {
6
+ $type: string;
7
+ })[];
8
+ $regexMatch?: undefined;
9
+ } | {
10
+ $eq: (string | null)[];
11
+ $regexMatch?: undefined;
12
+ } | {
13
+ $regexMatch: {
14
+ input: {
15
+ $ifNull: string[];
16
+ };
17
+ regex: RegExp;
18
+ };
19
+ $eq?: undefined;
20
+ })[];
21
+ };
22
+ export declare const ticketsWithCallSidMatch: (cityName: CityName, dateRange: TicketStatsDateRange) => {
23
+ createdAt: {
24
+ $gte: Date;
25
+ $lte: Date;
26
+ };
27
+ cityName: string;
28
+ callSid: {
29
+ $exists: boolean;
30
+ $nin: (string | null)[];
31
+ };
32
+ };
33
+ export declare const subjectResolutionStages: (cityName: CityName) => Record<string, unknown>[];
34
+ export declare const runTicketStatsAggregate: <T>(pipeline: Record<string, unknown>[]) => Promise<T[]>;
35
+ //# sourceMappingURL=tickets.statistics.aggregation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tickets.statistics.aggregation.d.ts","sourceRoot":"","sources":["../../../src/municipal/tickets/tickets.statistics.aggregation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAuD5D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;CAWhC,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,UAAU,QAAQ,EAClB,WAAW,oBAAoB;;;;;;;;;;CAK/B,CAAC;AAEH,eAAO,MAAM,uBAAuB,GAClC,UAAU,QAAQ,KACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAIzB,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAU,CAAC,EAC7C,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAClC,OAAO,CAAC,CAAC,EAAE,CAKb,CAAC"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runTicketStatsAggregate = exports.subjectResolutionStages = exports.ticketsWithCallSidMatch = exports.isDraftSubjectIdExpr = void 0;
4
+ const tickets_constants_1 = require("./tickets.constants");
5
+ const tickets_getters_1 = require("./tickets.getters");
6
+ const effectiveSubjectIdExpr = {
7
+ $ifNull: [
8
+ "$externalCallFields.event_subject_id",
9
+ {
10
+ $ifNull: [
11
+ "$externalCallFields.event_sub_subject_id",
12
+ "$externalCallFields.event_sub_subject_id2",
13
+ ],
14
+ },
15
+ ],
16
+ };
17
+ const departmentsSubjectsLookup = (cityName) => ({
18
+ $lookup: {
19
+ from: "departmentsSubjects",
20
+ let: { sid: "$effectiveSubjectId", c: cityName },
21
+ pipeline: [
22
+ {
23
+ $match: {
24
+ $expr: {
25
+ $and: [
26
+ { $eq: ["$cityName", "$$c"] },
27
+ {
28
+ $or: [
29
+ { $eq: ["$subject_id", { $ifNull: ["$$sid", ""] }] },
30
+ { $eq: ["$sub_subject_id", { $ifNull: ["$$sid", ""] }] },
31
+ { $eq: ["$sub_subject_id2", { $ifNull: ["$$sid", ""] }] },
32
+ ],
33
+ },
34
+ ],
35
+ },
36
+ },
37
+ },
38
+ { $limit: 1 },
39
+ ],
40
+ as: "subj",
41
+ },
42
+ });
43
+ const subjectLabelExpr = {
44
+ $cond: {
45
+ if: { $gt: [{ $size: "$subj" }, 0] },
46
+ then: {
47
+ $ifNull: [{ $arrayElemAt: ["$subj.subjectName", 0] }, tickets_constants_1.UNCLASSIFIED],
48
+ },
49
+ else: tickets_constants_1.UNCLASSIFIED,
50
+ },
51
+ };
52
+ const ticketDateMatch = (dateRange) => ({
53
+ createdAt: { $gte: dateRange.from, $lte: dateRange.to },
54
+ });
55
+ exports.isDraftSubjectIdExpr = {
56
+ $or: [
57
+ { $eq: [{ $type: "$externalCallFields.event_subject_id" }, "missing"] },
58
+ { $eq: ["$externalCallFields.event_subject_id", null] },
59
+ {
60
+ $regexMatch: {
61
+ input: { $ifNull: ["$externalCallFields.event_subject_id", ""] },
62
+ regex: /^\s*$/,
63
+ },
64
+ },
65
+ ],
66
+ };
67
+ const ticketsWithCallSidMatch = (cityName, dateRange) => ({
68
+ cityName,
69
+ callSid: { $exists: true, $nin: [null, ""] },
70
+ ...ticketDateMatch(dateRange),
71
+ });
72
+ exports.ticketsWithCallSidMatch = ticketsWithCallSidMatch;
73
+ const subjectResolutionStages = (cityName) => [
74
+ { $addFields: { effectiveSubjectId: effectiveSubjectIdExpr } },
75
+ departmentsSubjectsLookup(cityName),
76
+ { $addFields: { subject: subjectLabelExpr } },
77
+ ];
78
+ exports.subjectResolutionStages = subjectResolutionStages;
79
+ const runTicketStatsAggregate = async (pipeline) => {
80
+ const rows = await (0, tickets_getters_1.getTicketsCollection)()
81
+ .aggregate(pipeline, { maxTimeMS: tickets_constants_1.STATS_MAX_TIME_MS })
82
+ .toArray();
83
+ return rows;
84
+ };
85
+ exports.runTicketStatsAggregate = runTicketStatsAggregate;
86
+ //# sourceMappingURL=tickets.statistics.aggregation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tickets.statistics.aggregation.js","sourceRoot":"","sources":["../../../src/municipal/tickets/tickets.statistics.aggregation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { TicketStatsDateScope } from "./tickets.types";
2
+ export declare const resolveTicketStatsDateRange: (dateScope?: TicketStatsDateScope) => {
3
+ from: Date;
4
+ to: Date;
5
+ };
6
+ export declare const ticketStatsDateScopeFromYmd: (startStr: string, endStr: string, timezone: string) => TicketStatsDateScope;
7
+ //# sourceMappingURL=tickets.statistics.dates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tickets.statistics.dates.d.ts","sourceRoot":"","sources":["../../../src/municipal/tickets/tickets.statistics.dates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAiC5D,eAAO,MAAM,2BAA2B,GACtC,YAAY,oBAAoB,KAC/B;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,IAAI,CAAA;CAKxB,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,UAAU,MAAM,EAChB,QAAQ,MAAM,EACd,UAAU,MAAM,KACf,oBAGD,CAAC"}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ticketStatsDateScopeFromYmd = exports.resolveTicketStatsDateRange = void 0;
4
+ const DEFAULT_LOOKBACK_DAYS = 30;
5
+ const DAY_MS = 24 * 60 * 60 * 1000;
6
+ const formatYmdInTz = (date, timezone) => new Intl.DateTimeFormat("en-CA", { timeZone: timezone }).format(date);
7
+ const dateAtNoonUtc = (dateStr) => {
8
+ const [y, m, d] = dateStr.split("-").map(Number);
9
+ return new Date(Date.UTC(y, m - 1, d, 12, 0, 0));
10
+ };
11
+ const startOfCalendarDayInTz = (dateStr, timezone) => {
12
+ const anchor = dateAtNoonUtc(dateStr).getTime();
13
+ let low = anchor - 2 * DAY_MS;
14
+ let high = anchor + DAY_MS;
15
+ while (high - low > 1) {
16
+ const mid = Math.floor((low + high) / 2);
17
+ if (formatYmdInTz(new Date(mid), timezone) >= dateStr)
18
+ high = mid;
19
+ else
20
+ low = mid;
21
+ }
22
+ return new Date(high);
23
+ };
24
+ const endOfCalendarDayInTz = (dateStr, timezone) => {
25
+ const [y, m, d] = dateStr.split("-").map(Number);
26
+ const nextDay = new Date(Date.UTC(y, m - 1, d + 1)).toISOString().slice(0, 10);
27
+ return new Date(startOfCalendarDayInTz(nextDay, timezone).getTime() - 1);
28
+ };
29
+ const resolveTicketStatsDateRange = (dateScope) => {
30
+ const to = dateScope?.to ?? new Date();
31
+ const from = dateScope?.from ?? new Date(to.getTime() - DEFAULT_LOOKBACK_DAYS * DAY_MS);
32
+ return { from, to };
33
+ };
34
+ exports.resolveTicketStatsDateRange = resolveTicketStatsDateRange;
35
+ const ticketStatsDateScopeFromYmd = (startStr, endStr, timezone) => ({
36
+ from: startOfCalendarDayInTz(startStr, timezone),
37
+ to: endOfCalendarDayInTz(endStr, timezone),
38
+ });
39
+ exports.ticketStatsDateScopeFromYmd = ticketStatsDateScopeFromYmd;
40
+ //# sourceMappingURL=tickets.statistics.dates.js.map