orbitx-core-models 11.178.0 → 11.180.0
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/dist/activity/recorder.d.ts +2 -2
- package/dist/activity/recorder.d.ts.map +1 -1
- package/dist/activity/recorder.js +4 -7
- package/dist/constants/ticketCategories.d.ts +41 -20
- package/dist/constants/ticketCategories.d.ts.map +1 -1
- package/dist/constants/ticketCategories.js +212 -53
- package/dist/helpers/chatAttachments.d.ts +4 -3
- package/dist/helpers/chatAttachments.d.ts.map +1 -1
- package/dist/helpers/chatAttachments.js +7 -7
- package/dist/helpers/emailTemplates.d.ts.map +1 -1
- package/dist/helpers/emailTemplates.js +4 -5
- package/dist/helpers/ownTickets.d.ts +3 -1
- package/dist/helpers/ownTickets.d.ts.map +1 -1
- package/dist/helpers/ownTickets.js +30 -11
- package/dist/helpers/privateFiles.d.ts +14 -0
- package/dist/helpers/privateFiles.d.ts.map +1 -0
- package/dist/helpers/privateFiles.js +45 -0
- package/dist/helpers/requestInfo.d.ts +47 -0
- package/dist/helpers/requestInfo.d.ts.map +1 -0
- package/dist/helpers/requestInfo.js +156 -0
- package/dist/helpers/s3Storage.d.ts +24 -2
- package/dist/helpers/s3Storage.d.ts.map +1 -1
- package/dist/helpers/s3Storage.js +73 -5
- package/dist/helpers/sessions.d.ts +51 -3
- package/dist/helpers/sessions.d.ts.map +1 -1
- package/dist/helpers/sessions.js +144 -11
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -2
- package/dist/interfaces/company.interface.d.ts +2 -0
- package/dist/interfaces/company.interface.d.ts.map +1 -1
- package/dist/interfaces/session.interface.d.ts +2 -0
- package/dist/interfaces/session.interface.d.ts.map +1 -1
- package/dist/interfaces/subscription.interface.d.ts +2 -0
- package/dist/interfaces/subscription.interface.d.ts.map +1 -1
- package/dist/interfaces/ticket.interface.d.ts +30 -26
- package/dist/interfaces/ticket.interface.d.ts.map +1 -1
- package/dist/interfaces/ticket.interface.js +28 -4
- package/dist/interfaces/user.interface.d.ts +4 -0
- package/dist/interfaces/user.interface.d.ts.map +1 -1
- package/dist/interfaces/vertical.interface.d.ts +1 -1
- package/dist/interfaces/vertical.interface.d.ts.map +1 -1
- package/dist/models/company.model.d.ts.map +1 -1
- package/dist/models/company.model.js +3 -0
- package/dist/models/session.model.d.ts.map +1 -1
- package/dist/models/session.model.js +4 -0
- package/dist/models/subscription.model.d.ts.map +1 -1
- package/dist/models/subscription.model.js +4 -0
- package/dist/models/ticket.model.d.ts.map +1 -1
- package/dist/models/ticket.model.js +24 -38
- package/dist/models/user.model.d.ts.map +1 -1
- package/dist/models/user.model.js +7 -0
- package/dist/models/vertical.model.js +1 -1
- package/dist/routing/ticketRouting.d.ts +11 -1
- package/dist/routing/ticketRouting.d.ts.map +1 -1
- package/dist/routing/ticketRouting.js +82 -33
- package/dist/utils/ticketSanitize.d.ts.map +1 -1
- package/dist/utils/ticketSanitize.js +4 -0
- package/package.json +1 -1
|
@@ -19,6 +19,10 @@ export interface IUser extends mongoose.Document {
|
|
|
19
19
|
groupIds?: mongoose.Types.ObjectId[];
|
|
20
20
|
/** Support Agent/Manager: cap on open tickets, used by the routing engine's fewest-open pick. */
|
|
21
21
|
maxOpenTickets?: number;
|
|
22
|
+
/** Ops login: the ticket teams this person works ("billing" / "scripting" / "general"). The
|
|
23
|
+
* routing engine sends each team's tickets to its members; a Support Agent/Manager with none
|
|
24
|
+
* set counts as General Support. */
|
|
25
|
+
ticketTeams?: ("billing" | "scripting" | "general")[];
|
|
22
26
|
/** Support Agent/Manager: their manager, for the Support Manager's team roll-up. */
|
|
23
27
|
reportsTo?: mongoose.Types.ObjectId;
|
|
24
28
|
currentStatus?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/user.interface.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"user.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/user.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vertical.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/vertical.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;AAE7E,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"vertical.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/vertical.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;AAE7E,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"company.model.d.ts","sourceRoot":"","sources":["../../src/models/company.model.ts"],"names":[],"mappings":"AAAA,OAAO,QAA2B,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"company.model.d.ts","sourceRoot":"","sources":["../../src/models/company.model.ts"],"names":[],"mappings":"AAAA,OAAO,QAA2B,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AA+Q3D,eAAO,MAAM,OAAO;;;;OAAqD,CAAC;AAC1E,eAAe,OAAO,CAAC"}
|
|
@@ -42,6 +42,9 @@ const companySchema = new mongoose_1.Schema({
|
|
|
42
42
|
clientInstructionEnabled: { type: Boolean, default: false },
|
|
43
43
|
// Ops-controlled: the client can see its own company's Activity log (given on request).
|
|
44
44
|
activityLogAccess: { type: Boolean, default: false },
|
|
45
|
+
// The month ("2026-09") whose summary email was last sent to the company's main contact; set before
|
|
46
|
+
// sending (an atomic claim), so a restart or a second run never sends the same month twice.
|
|
47
|
+
monthlySummarySentFor: { type: String },
|
|
45
48
|
// The script folders Ops picked for this company (Account > Script > Insert Vertical), in the
|
|
46
49
|
// order they were arranged. Agents see exactly these, in this order, when the company's chat
|
|
47
50
|
// lands, and so does the lead page's View Script panel.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.model.d.ts","sourceRoot":"","sources":["../../src/models/session.model.ts"],"names":[],"mappings":"AAAA,OAAO,QAAoB,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"session.model.d.ts","sourceRoot":"","sources":["../../src/models/session.model.ts"],"names":[],"mappings":"AAAA,OAAO,QAAoB,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAuB3D,eAAO,MAAM,OAAO;;;;OAAqD,CAAC"}
|
|
@@ -43,6 +43,10 @@ const sessionSchema = new mongoose_1.Schema({
|
|
|
43
43
|
browser: { type: String },
|
|
44
44
|
os: { type: String },
|
|
45
45
|
ipAddress: { type: String },
|
|
46
|
+
// "Lahore, Pakistan" from Cloudflare's visitor-location headers, when the request had them.
|
|
47
|
+
location: { type: String },
|
|
48
|
+
// The name the person gave this device ("Tahir's HP laptop"); carried over to later sign-ins from the same device.
|
|
49
|
+
customName: { type: String, trim: true, maxlength: 40 },
|
|
46
50
|
userAgent: { type: String },
|
|
47
51
|
isRevoked: { type: Boolean, default: false },
|
|
48
52
|
lastActiveAt: { type: Date, default: Date.now },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscription.model.d.ts","sourceRoot":"","sources":["../../src/models/subscription.model.ts"],"names":[],"mappings":"AAAA,OAAO,QAAoB,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"subscription.model.d.ts","sourceRoot":"","sources":["../../src/models/subscription.model.ts"],"names":[],"mappings":"AAAA,OAAO,QAAoB,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAiMrE,eAAO,MAAM,YAAY;;;;OAGxB,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -85,6 +85,10 @@ const subscriptionSchema = new mongoose_1.Schema({
|
|
|
85
85
|
stripeSubscriptionItemId: { type: String },
|
|
86
86
|
stripePriceId: { type: String },
|
|
87
87
|
quantity: { type: Number, default: 1, min: 1 },
|
|
88
|
+
// Set when the client removed the add-on on a paid plan: it stays on until this date (the end of the
|
|
89
|
+
// period already paid for) and is taken off then, with no refund. Copied from the Stripe item's
|
|
90
|
+
// metadata on every sync, so the wholesale rebuild of `addons` keeps it.
|
|
91
|
+
removeAt: { type: Date },
|
|
88
92
|
},
|
|
89
93
|
],
|
|
90
94
|
// Ops-controlled pause list. Kept outside `addons` on purpose: the Stripe sync rebuilds
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ticket.model.d.ts","sourceRoot":"","sources":["../../src/models/ticket.model.ts"],"names":[],"mappings":"AAAA,OAAO,QAAoB,MAAM,UAAU,CAAC;AAE5C,OAAO,EACL,OAAO,
|
|
1
|
+
{"version":3,"file":"ticket.model.d.ts","sourceRoot":"","sources":["../../src/models/ticket.model.ts"],"names":[],"mappings":"AAAA,OAAO,QAAoB,MAAM,UAAU,CAAC;AAE5C,OAAO,EACL,OAAO,EASR,MAAM,gCAAgC,CAAC;AAuPxC,eAAO,MAAM,MAAM;;;;OAAkD,CAAC;AACtE,eAAe,MAAM,CAAC"}
|
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.Ticket = void 0;
|
|
37
37
|
const mongoose_1 = __importStar(require("mongoose"));
|
|
38
38
|
const counter_model_1 = require("./counter.model");
|
|
39
|
+
const ticket_interface_1 = require("../interfaces/ticket.interface");
|
|
39
40
|
const ticketAttachmentSchema = new mongoose_1.Schema({
|
|
40
41
|
url: { type: String, required: true, trim: true },
|
|
41
42
|
s3Key: { type: String, required: true, trim: true },
|
|
@@ -111,24 +112,15 @@ const ticketSchema = new mongoose_1.Schema({
|
|
|
111
112
|
},
|
|
112
113
|
category: {
|
|
113
114
|
type: String,
|
|
115
|
+
// Every value that can appear on a ticket: the current Client/Partner lists plus the legacy
|
|
116
|
+
// values old tickets were filed under (never offered on a new ticket).
|
|
114
117
|
enum: [
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
"chat-dispute",
|
|
122
|
-
// Partner -- current taxonomy
|
|
123
|
-
"failed-withdrawal",
|
|
124
|
-
"failed-transfer",
|
|
125
|
-
// "technical-support"/"account-support" above are shared with Client
|
|
126
|
-
// Partner -- legacy, kept valid for old tickets only
|
|
127
|
-
"dashboard-technical-issue",
|
|
128
|
-
"payout-issue",
|
|
129
|
-
"referral-issue",
|
|
130
|
-
"review-submission-issue",
|
|
131
|
-
"other",
|
|
118
|
+
...new Set([
|
|
119
|
+
...ticket_interface_1.CLIENT_TICKET_CATEGORIES,
|
|
120
|
+
...ticket_interface_1.CLIENT_TICKET_CATEGORIES_LEGACY,
|
|
121
|
+
...ticket_interface_1.PARTNER_TICKET_CATEGORIES,
|
|
122
|
+
...ticket_interface_1.PARTNER_TICKET_CATEGORIES_LEGACY,
|
|
123
|
+
]),
|
|
132
124
|
],
|
|
133
125
|
index: true,
|
|
134
126
|
},
|
|
@@ -161,6 +153,13 @@ const ticketSchema = new mongoose_1.Schema({
|
|
|
161
153
|
default: "open",
|
|
162
154
|
index: true,
|
|
163
155
|
},
|
|
156
|
+
// Which team handles it (billing / scripting / account-manager / general), from its category
|
|
157
|
+
// and sub-category -- see ticketTeamFor in constants/ticketCategories.ts.
|
|
158
|
+
team: {
|
|
159
|
+
type: String,
|
|
160
|
+
enum: ticket_interface_1.TICKET_TEAMS,
|
|
161
|
+
index: true,
|
|
162
|
+
},
|
|
164
163
|
priority: {
|
|
165
164
|
type: String,
|
|
166
165
|
enum: ["urgent", "high", "normal", "low"],
|
|
@@ -196,32 +195,19 @@ const ticketSchema = new mongoose_1.Schema({
|
|
|
196
195
|
},
|
|
197
196
|
resolvedAt: Date,
|
|
198
197
|
isSpam: { type: Boolean, default: false, index: true },
|
|
198
|
+
// Ops team email alerts (ops-dashboard services/ticketAlerts.service.js): when the new-ticket
|
|
199
|
+
// alert and the 24-hour no-reply escalation went out. Each is sent once per ticket.
|
|
200
|
+
teamAlertSentAt: Date,
|
|
201
|
+
slaEscalatedAt: Date,
|
|
199
202
|
}, {
|
|
200
203
|
timestamps: true,
|
|
201
204
|
toJSON: { virtuals: true },
|
|
202
205
|
toObject: { virtuals: true },
|
|
203
206
|
});
|
|
204
|
-
//
|
|
205
|
-
//
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
"dispute-billable-lead",
|
|
209
|
-
"chat-dispute",
|
|
210
|
-
"invoice-dispute",
|
|
211
|
-
"technical-support",
|
|
212
|
-
"account-support",
|
|
213
|
-
];
|
|
214
|
-
const PARTNER_ONLY_CATEGORIES = [
|
|
215
|
-
"failed-withdrawal",
|
|
216
|
-
"failed-transfer",
|
|
217
|
-
"technical-support",
|
|
218
|
-
"account-support",
|
|
219
|
-
"dashboard-technical-issue",
|
|
220
|
-
"payout-issue",
|
|
221
|
-
"referral-issue",
|
|
222
|
-
"review-submission-issue",
|
|
223
|
-
"other",
|
|
224
|
-
];
|
|
207
|
+
// Every category each ownerType may use (current + legacy). Some values -- "dashboard", "account",
|
|
208
|
+
// "something-else" and the legacy "technical-support"/"account-support" -- are valid on both.
|
|
209
|
+
const CLIENT_ONLY_CATEGORIES = [...ticket_interface_1.CLIENT_TICKET_CATEGORIES, ...ticket_interface_1.CLIENT_TICKET_CATEGORIES_LEGACY];
|
|
210
|
+
const PARTNER_ONLY_CATEGORIES = [...ticket_interface_1.PARTNER_TICKET_CATEGORIES, ...ticket_interface_1.PARTNER_TICKET_CATEGORIES_LEGACY];
|
|
225
211
|
ticketSchema.pre("validate", function () {
|
|
226
212
|
if (this.source === "dashboard") {
|
|
227
213
|
if (!this.ownerType || !this.ownerId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.model.d.ts","sourceRoot":"","sources":["../../src/models/user.model.ts"],"names":[],"mappings":"AAAA,OAAO,QAAoB,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"user.model.d.ts","sourceRoot":"","sources":["../../src/models/user.model.ts"],"names":[],"mappings":"AAAA,OAAO,QAAoB,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AA0SrD,eAAO,MAAM,IAAI;;;;OAA4C,CAAC"}
|
|
@@ -177,6 +177,13 @@ const userSchema = new mongoose_1.Schema({
|
|
|
177
177
|
type: Number,
|
|
178
178
|
default: 15,
|
|
179
179
|
},
|
|
180
|
+
// Ticket teams this Ops login works (Billing / Scripting / General Support) -- the routing
|
|
181
|
+
// engine (routing/ticketRouting.ts) sends each team's tickets to its members. A Support
|
|
182
|
+
// Agent/Manager with none set counts as General Support.
|
|
183
|
+
ticketTeams: {
|
|
184
|
+
type: [{ type: String, enum: ["billing", "scripting", "general"] }],
|
|
185
|
+
default: undefined,
|
|
186
|
+
},
|
|
180
187
|
reportsTo: {
|
|
181
188
|
type: mongoose_1.Schema.Types.ObjectId,
|
|
182
189
|
ref: "User",
|
|
@@ -46,9 +46,9 @@ const verticalSchema = new mongoose_1.Schema({
|
|
|
46
46
|
enum: ["General", "IndustrySpecific", "ClientSpecific"],
|
|
47
47
|
required: [true, "Vertical type is required"],
|
|
48
48
|
},
|
|
49
|
+
// No longer asked for (Oct 2026); old folders keep their value, nothing reads it.
|
|
49
50
|
host: {
|
|
50
51
|
type: String,
|
|
51
|
-
required: [true, "Host (creator/owner) is required"],
|
|
52
52
|
},
|
|
53
53
|
industry: {
|
|
54
54
|
type: String,
|
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
import { Types } from "mongoose";
|
|
2
|
-
import { TicketOwnerType, TicketCategory } from "../interfaces/ticket.interface";
|
|
2
|
+
import { TicketOwnerType, TicketCategory, TicketTeam } from "../interfaces/ticket.interface";
|
|
3
3
|
export declare const OPEN_TICKET_STATUSES: readonly ["open", "in_progress", "awaiting_client", "awaiting_internal"];
|
|
4
4
|
export interface TicketRoutingInput {
|
|
5
5
|
ownerType: TicketOwnerType;
|
|
6
6
|
ownerId: Types.ObjectId | string;
|
|
7
7
|
category?: TicketCategory;
|
|
8
|
+
subCategory?: string;
|
|
8
9
|
}
|
|
9
10
|
export interface TicketRoutingResult {
|
|
10
11
|
assigneeId?: Types.ObjectId;
|
|
11
12
|
followerIds: Types.ObjectId[];
|
|
13
|
+
/** The team the ticket's category belongs to (undefined while it has no category). */
|
|
14
|
+
team?: TicketTeam;
|
|
12
15
|
}
|
|
13
16
|
export declare function pickFromGroup(groupId: Types.ObjectId | string): Promise<Types.ObjectId | undefined>;
|
|
17
|
+
/** Ops logins on a ticket team (General also takes any Support Agent/Manager with no team set). */
|
|
18
|
+
export declare function ticketTeamMembers(team: Exclude<TicketTeam, "account-manager">): Promise<(import("mongoose").FlattenMaps<import("..").IUser> & Required<{
|
|
19
|
+
_id: import("mongoose").FlattenMaps<unknown>;
|
|
20
|
+
}> & {
|
|
21
|
+
__v: number;
|
|
22
|
+
})[]>;
|
|
23
|
+
export declare function pickFromTicketTeam(team: Exclude<TicketTeam, "account-manager">, preferGroupId?: Types.ObjectId | string): Promise<Types.ObjectId | undefined>;
|
|
14
24
|
export declare function resolveTicketRouting(ticket: TicketRoutingInput): Promise<TicketRoutingResult>;
|
|
15
25
|
//# sourceMappingURL=ticketRouting.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ticketRouting.d.ts","sourceRoot":"","sources":["../../src/routing/ticketRouting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"ticketRouting.d.ts","sourceRoot":"","sources":["../../src/routing/ticketRouting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAOjC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAsB7F,eAAO,MAAM,oBAAoB,0EAKvB,CAAC;AAIX,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,eAAe,CAAC;IAC3B,OAAO,EAAE,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC;IAC5B,WAAW,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC9B,sFAAsF;IACtF,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAoCD,wBAAsB,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,SAAS,CAAC,CAKzG;AAED,mGAAmG;AACnG,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,iBAAiB,CAAC;;;;MAkBnF;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,iBAAiB,CAAC,EAC5C,aAAa,CAAC,EAAE,KAAK,CAAC,QAAQ,GAAG,MAAM,GACtC,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,SAAS,CAAC,CAErC;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA+CnG"}
|
|
@@ -2,40 +2,45 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.OPEN_TICKET_STATUSES = void 0;
|
|
4
4
|
exports.pickFromGroup = pickFromGroup;
|
|
5
|
+
exports.ticketTeamMembers = ticketTeamMembers;
|
|
6
|
+
exports.pickFromTicketTeam = pickFromTicketTeam;
|
|
5
7
|
exports.resolveTicketRouting = resolveTicketRouting;
|
|
6
8
|
const company_model_1 = require("../models/company.model");
|
|
7
9
|
const partner_model_1 = require("../models/partner.model");
|
|
8
10
|
const group_model_1 = require("../models/group.model");
|
|
9
11
|
const user_model_1 = require("../models/user.model");
|
|
12
|
+
const role_model_1 = require("../models/role.model");
|
|
10
13
|
const ticket_model_1 = require("../models/ticket.model");
|
|
11
|
-
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
14
|
+
const ticketCategories_1 = require("../constants/ticketCategories");
|
|
15
|
+
// Resolves who a ticket should go to. Every category (or sub-category) names the team that handles
|
|
16
|
+
// it (constants/ticketCategories.ts -> ticketTeamFor):
|
|
17
|
+
// billing / scripting / general -- the Ops logins on that Ticket Team (User.ticketTeams; a
|
|
18
|
+
// Support Agent/Manager with no team set counts as General)
|
|
19
|
+
// account-manager -- the ticket owner's own Account Manager
|
|
17
20
|
// Order:
|
|
18
|
-
// 1. The ticket
|
|
19
|
-
// 2.
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
21
|
+
// 1. The ticket's team. Within a team, people already scoped to the owner's Group are preferred.
|
|
22
|
+
// 2. Nobody available there (no Account Manager on the account, nobody on the team, or everyone
|
|
23
|
+
// at their open-ticket limit) -> General Support.
|
|
24
|
+
// 3. Still nobody -> the older Group rules: the owner's own Group, then a Group that handles this
|
|
25
|
+
// category (Group.handlesTicketCategories).
|
|
26
|
+
// 4. Otherwise unassigned -- the new-ticket alert email then goes to every Support Manager.
|
|
27
|
+
// Whoever is picked from a team is the member with the fewest open tickets, among those still under
|
|
28
|
+
// their own maxOpenTickets. A Company's or Partner's Account Manager is always added as a follower.
|
|
24
29
|
//
|
|
25
|
-
// Shared by every backend that creates or re-
|
|
26
|
-
// apply the exact same rule
|
|
27
|
-
//
|
|
30
|
+
// Shared by every backend that creates or re-routes a Ticket (Ops, Client, Partner) so all three
|
|
31
|
+
// apply the exact same rule -- Ops's `POST /:id/auto-assign` and its re-route when a ticket's
|
|
32
|
+
// category changes call this too.
|
|
28
33
|
exports.OPEN_TICKET_STATUSES = [
|
|
29
34
|
"open",
|
|
30
35
|
"in_progress",
|
|
31
36
|
"awaiting_client",
|
|
32
37
|
"awaiting_internal",
|
|
33
38
|
];
|
|
34
|
-
|
|
39
|
+
const GENERAL_SUPPORT_ROLE_KEYS = ["support-agent", "support-manager"];
|
|
40
|
+
// The member with the fewest open tickets who is still under their limit; members already scoped
|
|
41
|
+
// to `preferGroupId` win ties first.
|
|
42
|
+
async function pickLeastBusy(members, preferGroupId) {
|
|
35
43
|
var _a;
|
|
36
|
-
const members = await user_model_1.User.find({ groupIds: groupId, lockedOut: { $ne: true } })
|
|
37
|
-
.select("_id maxOpenTickets")
|
|
38
|
-
.lean();
|
|
39
44
|
if (members.length === 0)
|
|
40
45
|
return undefined;
|
|
41
46
|
const counts = await ticket_model_1.Ticket.aggregate([
|
|
@@ -48,6 +53,7 @@ async function pickFromGroup(groupId) {
|
|
|
48
53
|
{ $group: { _id: "$assigneeId", count: { $sum: 1 } } },
|
|
49
54
|
]);
|
|
50
55
|
const openByUser = new Map(counts.map((c) => [String(c._id), c.count]));
|
|
56
|
+
const inGroup = (m) => preferGroupId ? (m.groupIds || []).some((g) => String(g) === String(preferGroupId)) : false;
|
|
51
57
|
const eligible = members
|
|
52
58
|
.map((m) => {
|
|
53
59
|
var _a;
|
|
@@ -55,12 +61,42 @@ async function pickFromGroup(groupId) {
|
|
|
55
61
|
id: m._id,
|
|
56
62
|
open: openByUser.get(String(m._id)) || 0,
|
|
57
63
|
limit: (_a = m.maxOpenTickets) !== null && _a !== void 0 ? _a : 15,
|
|
64
|
+
preferred: inGroup(m),
|
|
58
65
|
});
|
|
59
66
|
})
|
|
60
67
|
.filter((m) => m.open < m.limit)
|
|
61
|
-
.sort((a, b) => a.open - b.open);
|
|
68
|
+
.sort((a, b) => Number(b.preferred) - Number(a.preferred) || a.open - b.open);
|
|
62
69
|
return (_a = eligible[0]) === null || _a === void 0 ? void 0 : _a.id;
|
|
63
70
|
}
|
|
71
|
+
async function pickFromGroup(groupId) {
|
|
72
|
+
const members = await user_model_1.User.find({ groupIds: groupId, lockedOut: { $ne: true } })
|
|
73
|
+
.select("_id maxOpenTickets groupIds")
|
|
74
|
+
.lean();
|
|
75
|
+
return pickLeastBusy(members);
|
|
76
|
+
}
|
|
77
|
+
/** Ops logins on a ticket team (General also takes any Support Agent/Manager with no team set). */
|
|
78
|
+
async function ticketTeamMembers(team) {
|
|
79
|
+
const base = { ownerType: "ORBITXPRO", lockedOut: { $ne: true } };
|
|
80
|
+
if (team !== "general") {
|
|
81
|
+
return user_model_1.User.find({ ...base, ticketTeams: team }).select("_id name email maxOpenTickets groupIds").lean();
|
|
82
|
+
}
|
|
83
|
+
const supportRoles = await role_model_1.Role.find({ key: { $in: GENERAL_SUPPORT_ROLE_KEYS } }).select("_id").lean();
|
|
84
|
+
return user_model_1.User.find({
|
|
85
|
+
...base,
|
|
86
|
+
$or: [
|
|
87
|
+
{ ticketTeams: "general" },
|
|
88
|
+
{
|
|
89
|
+
roleId: { $in: supportRoles.map((r) => r._id) },
|
|
90
|
+
$and: [{ $or: [{ ticketTeams: { $exists: false } }, { ticketTeams: { $size: 0 } }] }],
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
})
|
|
94
|
+
.select("_id name email maxOpenTickets groupIds")
|
|
95
|
+
.lean();
|
|
96
|
+
}
|
|
97
|
+
async function pickFromTicketTeam(team, preferGroupId) {
|
|
98
|
+
return pickLeastBusy((await ticketTeamMembers(team)), preferGroupId);
|
|
99
|
+
}
|
|
64
100
|
async function resolveTicketRouting(ticket) {
|
|
65
101
|
var _a, _b;
|
|
66
102
|
const followerIds = [];
|
|
@@ -68,30 +104,43 @@ async function resolveTicketRouting(ticket) {
|
|
|
68
104
|
// `any` here deliberately -- Company and Partner are two distinct Mongoose models with
|
|
69
105
|
// differently-typed findById overloads that TS can't unify through a variable holding either.
|
|
70
106
|
const Owner = ticket.ownerType === "Partner" ? partner_model_1.Partner : company_model_1.Company;
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
// accountInfo.accountManager) -- the Account Manager has never actually been auto-added as a
|
|
74
|
-
// ticket follower, on any ticket, since this was built, despite the model's own comment saying
|
|
75
|
-
// they always are.
|
|
107
|
+
// Company's Account Manager is nested at basicInfo.accountManager, Partner's at
|
|
108
|
+
// accountInfo.accountManager.
|
|
76
109
|
const owner = await Owner.findById(ticket.ownerId)
|
|
77
110
|
.select("groupId basicInfo.accountManager accountInfo.accountManager")
|
|
78
111
|
.lean();
|
|
79
112
|
const accountManagerId = ticket.ownerType === "Partner" ? (_a = owner === null || owner === void 0 ? void 0 : owner.accountInfo) === null || _a === void 0 ? void 0 : _a.accountManager : (_b = owner === null || owner === void 0 ? void 0 : owner.basicInfo) === null || _b === void 0 ? void 0 : _b.accountManager;
|
|
80
113
|
if (accountManagerId)
|
|
81
114
|
followerIds.push(accountManagerId);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
115
|
+
const team = (0, ticketCategories_1.ticketTeamFor)(ticket.ownerType, ticket.category, ticket.subCategory);
|
|
116
|
+
const preferGroupId = ticket.ownerType === "Company" ? owner === null || owner === void 0 ? void 0 : owner.groupId : undefined;
|
|
117
|
+
// 1. The ticket's own team.
|
|
118
|
+
if (team === "account-manager") {
|
|
119
|
+
if (accountManagerId) {
|
|
120
|
+
const manager = await user_model_1.User.findOne({ _id: accountManagerId, lockedOut: { $ne: true } }).select("_id").lean();
|
|
121
|
+
if (manager)
|
|
122
|
+
assigneeId = manager._id;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else if (team) {
|
|
126
|
+
assigneeId = await pickFromTicketTeam(team, preferGroupId);
|
|
127
|
+
}
|
|
128
|
+
// 2. General Support picks up anything its own team couldn't take.
|
|
129
|
+
if (!assigneeId && team && team !== "general") {
|
|
130
|
+
assigneeId = await pickFromTicketTeam("general", preferGroupId);
|
|
131
|
+
}
|
|
132
|
+
// 3. The older Group rules.
|
|
133
|
+
if (!assigneeId && preferGroupId) {
|
|
134
|
+
const group = await group_model_1.Group.findOne({ _id: preferGroupId, isActive: true }).select("_id").lean();
|
|
85
135
|
if (group)
|
|
86
136
|
assigneeId = await pickFromGroup(group._id);
|
|
87
137
|
}
|
|
88
|
-
// Rule 2: a group that specifically handles this ticket's category.
|
|
89
138
|
if (!assigneeId && ticket.category) {
|
|
90
|
-
const
|
|
139
|
+
const handlingGroup = await group_model_1.Group.findOne({ isActive: true, handlesTicketCategories: ticket.category })
|
|
91
140
|
.select("_id")
|
|
92
141
|
.lean();
|
|
93
|
-
if (
|
|
94
|
-
assigneeId = await pickFromGroup(
|
|
142
|
+
if (handlingGroup)
|
|
143
|
+
assigneeId = await pickFromGroup(handlingGroup._id);
|
|
95
144
|
}
|
|
96
|
-
return { assigneeId, followerIds };
|
|
145
|
+
return { assigneeId, followerIds, team };
|
|
97
146
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ticketSanitize.d.ts","sourceRoot":"","sources":["../../src/utils/ticketSanitize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEzE;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,OAAO,CAAC,OAAO,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAA;CAAE,EACrG,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,GAC3B,CAAC,GAAG,IAAI,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"ticketSanitize.d.ts","sourceRoot":"","sources":["../../src/utils/ticketSanitize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEzE;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,OAAO,CAAC,OAAO,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAA;CAAE,EACrG,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,GAC3B,CAAC,GAAG,IAAI,GAAG,SAAS,CAsBtB"}
|
|
@@ -29,5 +29,9 @@ function sanitizeTicketForRequester(ticket) {
|
|
|
29
29
|
delete ticket.followerIds;
|
|
30
30
|
delete ticket.assigneeId;
|
|
31
31
|
delete ticket.priority;
|
|
32
|
+
// Internal routing and alert bookkeeping.
|
|
33
|
+
delete ticket.team;
|
|
34
|
+
delete ticket.teamAlertSentAt;
|
|
35
|
+
delete ticket.slaEscalatedAt;
|
|
32
36
|
return ticket;
|
|
33
37
|
}
|