@talkpilot/core-db 1.3.55 → 1.3.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/configuration/models/models.seed.d.ts +5 -0
- package/dist/configuration/models/models.seed.d.ts.map +1 -0
- package/dist/configuration/models/models.seed.js +16 -0
- package/dist/configuration/models/models.seed.js.map +1 -0
- package/dist/configuration/models/realtimeUiFields.constants.d.ts +4 -0
- package/dist/configuration/models/realtimeUiFields.constants.d.ts.map +1 -0
- package/dist/configuration/models/realtimeUiFields.constants.js +80 -0
- package/dist/configuration/models/realtimeUiFields.constants.js.map +1 -0
- package/dist/configuration/models/uiFields.types.d.ts +29 -0
- package/dist/configuration/models/uiFields.types.d.ts.map +1 -0
- package/dist/configuration/models/uiFields.types.js +12 -0
- package/dist/configuration/models/uiFields.types.js.map +1 -0
- package/dist/talkpilot/clients/clients.getters.d.ts +1 -0
- package/dist/talkpilot/clients/clients.getters.d.ts.map +1 -1
- package/dist/talkpilot/clients/clients.getters.js +3 -1
- package/dist/talkpilot/clients/clients.getters.js.map +1 -1
- package/dist/talkpilot/phone_numbers/phone_numbers.getter.d.ts +6 -0
- package/dist/talkpilot/phone_numbers/phone_numbers.getter.d.ts.map +1 -1
- package/dist/talkpilot/phone_numbers/phone_numbers.getter.js +32 -1
- package/dist/talkpilot/phone_numbers/phone_numbers.getter.js.map +1 -1
- package/dist/talkpilot/phone_numbers/phone_numbers.utils.d.ts +6 -0
- package/dist/talkpilot/phone_numbers/phone_numbers.utils.d.ts.map +1 -0
- package/dist/talkpilot/phone_numbers/phone_numbers.utils.js +11 -0
- package/dist/talkpilot/phone_numbers/phone_numbers.utils.js.map +1 -0
- package/package.json +1 -1
- package/src/talkpilot/clients/clients.getters.ts +3 -0
- package/src/talkpilot/phone_numbers/__tests__/phone_numbers.spec.ts +249 -1
- package/src/talkpilot/phone_numbers/phone_numbers.getter.ts +64 -0
- package/src/talkpilot/phone_numbers/phone_numbers.utils.ts +9 -0
- package/dist/talkpilot/clients/clients.quota.constants.d.ts +0 -2
- package/dist/talkpilot/clients/clients.quota.constants.d.ts.map +0 -1
- package/dist/talkpilot/clients/clients.quota.constants.js +0 -5
- package/dist/talkpilot/clients/clients.quota.constants.js.map +0 -1
- package/dist/talkpilot/clients/clients.quota.utils.d.ts +0 -8
- package/dist/talkpilot/clients/clients.quota.utils.d.ts.map +0 -1
- package/dist/talkpilot/clients/clients.quota.utils.js +0 -45
- package/dist/talkpilot/clients/clients.quota.utils.js.map +0 -1
package/README.md
CHANGED
|
@@ -178,6 +178,7 @@ Refer to `DEVELOPMENT.md` for the full walkthrough, token instructions, and fact
|
|
|
178
178
|
| 1.3.47 | Added optional `accountOwnerEmail` field to `WebsiteTalkProduct` (CP-1715): the recipient for the end-of-call summary email, set once from the client's login email and editable in Settings. |
|
|
179
179
|
| 1.3.48 | Fixed `getScanPages` search (CP-1726): user search input was passed unescaped into MongoDB's `$regex`, so a URL/title containing regex-special characters (e.g. `?`) failed to match even when the document existed. Added `escapeRegex()` and applied it before building the `url`/`title` `$regex` filter. No API changes. |
|
|
180
180
|
| 1.3.49 | Internal tools configuration on flows (CP-1723): `Flow.internalTools` keyed by tool name (`enabled`, optional `maxCalls`, per-parameter `description`/`value` overrides) with matching `$jsonSchema` validator, plus `createFlow` / `updateFlowById` mutators and the `FlowUpdateParams` type so consumers stop writing to the `flows` collection directly. |
|
|
181
|
+
| 1.3.57 | Phone-number bind getters: list by client, exclusive flow assign, unbind, and `flow_id` match for ObjectId or leftover string. `getClientByClientId`. |
|
|
181
182
|
|
|
182
183
|
### 1.1.9
|
|
183
184
|
|
|
@@ -766,6 +767,26 @@ No — purely additive.
|
|
|
766
767
|
|
|
767
768
|
No API changes. **WTIS** (the only current consumer of `getScanPages`) should upgrade to 1.3.48 or later to pick up the fix.
|
|
768
769
|
|
|
770
|
+
### 1.3.57 — Phone-number bind getters
|
|
771
|
+
|
|
772
|
+
TalkPilot can bind any owned number to a flow without querying Mongo in the service layer. `flow_id` is matched as ObjectId or as a leftover string.
|
|
773
|
+
|
|
774
|
+
**Added**
|
|
775
|
+
|
|
776
|
+
| Export | Purpose |
|
|
777
|
+
| --- | --- |
|
|
778
|
+
| `getClientByClientId(clientId)` | Fetch a client by `clientId`. |
|
|
779
|
+
| `findPhoneNumbersByClientId(clientId)` | All `phone_numbers` for a client. |
|
|
780
|
+
| `getOwnedPhoneNumber(clientId, phoneNumber)` | One number that belongs to the client, or `null`. |
|
|
781
|
+
| `getPhoneNumberByClientAndFlow(clientId, flowId)` | Number bound to that flow for that client. |
|
|
782
|
+
| `clearPhoneNumberFlow(clientId, phoneNumber)` | Unset `flow_id` on one number. |
|
|
783
|
+
| `assignExclusiveFlow(clientId, phoneNumber, flowId)` | Bind the number and clear the same flow on the client's other numbers. |
|
|
784
|
+
| `unbindFlowFromClientNumbers(clientId, flowId)` | Unset `flow_id` on every number of that client pointing at the flow. |
|
|
785
|
+
|
|
786
|
+
**Do I need to update my app?**
|
|
787
|
+
|
|
788
|
+
No — purely additive. **TalkPilot Server** should upgrade to **1.3.57** for multi-number bind/list.
|
|
789
|
+
|
|
769
790
|
## 🛠 CI/CD & deployment
|
|
770
791
|
|
|
771
792
|
- 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.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.seed.d.ts","sourceRoot":"","sources":["../../../src/configuration/models/models.seed.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,oBAAoB,QAAa,OAAO,CAAC;IACpD,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB,CAcA,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.seedRealtimeUiFields = void 0;
|
|
4
|
+
const models_getters_1 = require("./models.getters");
|
|
5
|
+
const realtimeUiFields_constants_1 = require("./realtimeUiFields.constants");
|
|
6
|
+
const seedRealtimeUiFields = async () => {
|
|
7
|
+
const now = new Date();
|
|
8
|
+
const openai = await (0, models_getters_1.getModelsCollection)().updateMany({ type: "realtime", provider: "openai" }, { $set: { uiFields: realtimeUiFields_constants_1.OPENAI_REALTIME_UI_FIELDS, updatedAt: now } });
|
|
9
|
+
const gemini = await (0, models_getters_1.getModelsCollection)().updateMany({ type: "realtime", provider: "gemini" }, { $set: { uiFields: realtimeUiFields_constants_1.GEMINI_REALTIME_UI_FIELDS, updatedAt: now } });
|
|
10
|
+
return {
|
|
11
|
+
openaiMatched: openai.matchedCount,
|
|
12
|
+
geminiMatched: gemini.matchedCount,
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
exports.seedRealtimeUiFields = seedRealtimeUiFields;
|
|
16
|
+
//# sourceMappingURL=models.seed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.seed.js","sourceRoot":"","sources":["../../../src/configuration/models/models.seed.ts"],"names":[],"mappings":";;;AAEA,qDAAuD;AAEvD,6EAGsC;AAE/B,MAAM,oBAAoB,GAAG,KAAK,IAGtC,EAAE;IACH,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,MAAM,IAAA,oCAAmB,GAAE,CAAC,UAAU,CACnD,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAsB,EAC5D,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,sDAAyB,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,CAClE,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,IAAA,oCAAmB,GAAE,CAAC,UAAU,CACnD,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAsB,EAC5D,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,sDAAyB,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,CAClE,CAAC;IACF,OAAO;QACL,aAAa,EAAE,MAAM,CAAC,YAAY;QAClC,aAAa,EAAE,MAAM,CAAC,YAAY;KACnC,CAAC;AACJ,CAAC,CAAC;AAjBW,QAAA,oBAAoB,wBAiB/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtimeUiFields.constants.d.ts","sourceRoot":"","sources":["../../../src/configuration/models/realtimeUiFields.constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AA0B3C,eAAO,MAAM,yBAAyB,EAAE,OAAO,EAyC9C,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,OAAO,EAW9C,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GEMINI_REALTIME_UI_FIELDS = exports.OPENAI_REALTIME_UI_FIELDS = void 0;
|
|
4
|
+
const DEFAULT_SERVER_VAD = {
|
|
5
|
+
type: "server_vad",
|
|
6
|
+
threshold: 0.7,
|
|
7
|
+
silence_duration_ms: 600,
|
|
8
|
+
prefix_padding_ms: 300,
|
|
9
|
+
};
|
|
10
|
+
const SHARED_REALTIME_UI_FIELDS = [
|
|
11
|
+
{
|
|
12
|
+
key: "disableInterrupt",
|
|
13
|
+
type: "switch",
|
|
14
|
+
label: "אפשר לקטוע את הבוט בזמן שהוא מדבר",
|
|
15
|
+
default: false,
|
|
16
|
+
invert: true,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
key: "ignoreUserAudioUntilFirstTurnDone",
|
|
20
|
+
type: "switch",
|
|
21
|
+
label: "התעלמות מדיבור המשתמש עד לסיום משפט הפתיחה של הבוט",
|
|
22
|
+
default: true,
|
|
23
|
+
visibleWhen: { key: "disableInterrupt", equals: false },
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
exports.OPENAI_REALTIME_UI_FIELDS = [
|
|
27
|
+
{
|
|
28
|
+
key: "reasoningEffort",
|
|
29
|
+
type: "select",
|
|
30
|
+
label: "רמת חשיבה (Reasoning)",
|
|
31
|
+
default: "",
|
|
32
|
+
options: [
|
|
33
|
+
{ value: "", label: "none" },
|
|
34
|
+
{ value: "minimal", label: "Minimal (לטנציה נמוכה)" },
|
|
35
|
+
{ value: "low", label: "Low (מומלץ)" },
|
|
36
|
+
{ value: "medium", label: "Medium" },
|
|
37
|
+
{ value: "high", label: "High" },
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
key: "speed",
|
|
42
|
+
type: "slider",
|
|
43
|
+
label: "מהירות דיבור",
|
|
44
|
+
default: 0.375,
|
|
45
|
+
min: 0,
|
|
46
|
+
max: 1,
|
|
47
|
+
step: 0.01,
|
|
48
|
+
marks: [
|
|
49
|
+
{ value: 0, label: "איטי" },
|
|
50
|
+
{ value: 1, label: "מהיר" },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
key: "enableUserAudioBuckets",
|
|
55
|
+
type: "checkbox",
|
|
56
|
+
label: "שמירת אודיו של המשתמש במאגר",
|
|
57
|
+
default: false,
|
|
58
|
+
},
|
|
59
|
+
...SHARED_REALTIME_UI_FIELDS,
|
|
60
|
+
{
|
|
61
|
+
key: "turn_detection",
|
|
62
|
+
type: "turnDetection",
|
|
63
|
+
label: "הגדרות",
|
|
64
|
+
default: DEFAULT_SERVER_VAD,
|
|
65
|
+
visibleWhen: { key: "disableInterrupt", equals: false },
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
exports.GEMINI_REALTIME_UI_FIELDS = [
|
|
69
|
+
{
|
|
70
|
+
key: "temperature",
|
|
71
|
+
type: "number",
|
|
72
|
+
label: "Temperature",
|
|
73
|
+
default: 0.7,
|
|
74
|
+
min: 0,
|
|
75
|
+
max: 2,
|
|
76
|
+
step: 0.1,
|
|
77
|
+
},
|
|
78
|
+
...SHARED_REALTIME_UI_FIELDS,
|
|
79
|
+
];
|
|
80
|
+
//# sourceMappingURL=realtimeUiFields.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtimeUiFields.constants.js","sourceRoot":"","sources":["../../../src/configuration/models/realtimeUiFields.constants.ts"],"names":[],"mappings":";;;AAEA,MAAM,kBAAkB,GAAG;IACzB,IAAI,EAAE,YAAY;IAClB,SAAS,EAAE,GAAG;IACd,mBAAmB,EAAE,GAAG;IACxB,iBAAiB,EAAE,GAAG;CACvB,CAAC;AAEF,MAAM,yBAAyB,GAAc;IAC3C;QACE,GAAG,EAAE,kBAAkB;QACvB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,mCAAmC;QAC1C,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,IAAI;KACb;IACD;QACE,GAAG,EAAE,mCAAmC;QACxC,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,oDAAoD;QAC3D,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,EAAE,KAAK,EAAE;KACxD;CACF,CAAC;AAEW,QAAA,yBAAyB,GAAc;IAClD;QACE,GAAG,EAAE,iBAAiB;QACtB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,uBAAuB;QAC9B,OAAO,EAAE,EAAE;QACX,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;YAC5B,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,wBAAwB,EAAE;YACrD,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE;YACtC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;YACpC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;SACjC;KACF;IACD;QACE,GAAG,EAAE,OAAO;QACZ,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,cAAc;QACrB,OAAO,EAAE,KAAK;QACd,GAAG,EAAE,CAAC;QACN,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,IAAI;QACV,KAAK,EAAE;YACL,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;YAC3B,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;SAC5B;KACF;IACD;QACE,GAAG,EAAE,wBAAwB;QAC7B,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,6BAA6B;QACpC,OAAO,EAAE,KAAK;KACf;IACD,GAAG,yBAAyB;IAC5B;QACE,GAAG,EAAE,gBAAgB;QACrB,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,kBAAkB;QAC3B,WAAW,EAAE,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,EAAE,KAAK,EAAE;KACxD;CACF,CAAC;AAEW,QAAA,yBAAyB,GAAc;IAClD;QACE,GAAG,EAAE,aAAa;QAClB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE,GAAG;QACZ,GAAG,EAAE,CAAC;QACN,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,GAAG;KACV;IACD,GAAG,yBAAyB;CAC7B,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const UI_FIELD_TYPES: readonly ["number", "slider", "select", "checkbox", "switch", "turnDetection"];
|
|
2
|
+
export type UiFieldType = (typeof UI_FIELD_TYPES)[number];
|
|
3
|
+
export type UiFieldOption = {
|
|
4
|
+
value: string;
|
|
5
|
+
label: string;
|
|
6
|
+
};
|
|
7
|
+
export type UiFieldVisibleWhen = {
|
|
8
|
+
key: string;
|
|
9
|
+
equals: unknown;
|
|
10
|
+
};
|
|
11
|
+
/** Recipe the dashboard uses to pick a widget for one saved `aiProvider` key. */
|
|
12
|
+
export type UiField = {
|
|
13
|
+
key: string;
|
|
14
|
+
type: UiFieldType;
|
|
15
|
+
label: string;
|
|
16
|
+
default?: unknown;
|
|
17
|
+
min?: number;
|
|
18
|
+
max?: number;
|
|
19
|
+
step?: number;
|
|
20
|
+
options?: UiFieldOption[];
|
|
21
|
+
marks?: {
|
|
22
|
+
value: number;
|
|
23
|
+
label: string;
|
|
24
|
+
}[];
|
|
25
|
+
/** When true, a switch/checkbox displays the inverse of the stored value. */
|
|
26
|
+
invert?: boolean;
|
|
27
|
+
visibleWhen?: UiFieldVisibleWhen;
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=uiFields.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uiFields.types.d.ts","sourceRoot":"","sources":["../../../src/configuration/models/uiFields.types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,gFAOjB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,iFAAiF;AACjF,MAAM,MAAM,OAAO,GAAG;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,6EAA6E;IAC7E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UI_FIELD_TYPES = void 0;
|
|
4
|
+
exports.UI_FIELD_TYPES = [
|
|
5
|
+
"number",
|
|
6
|
+
"slider",
|
|
7
|
+
"select",
|
|
8
|
+
"checkbox",
|
|
9
|
+
"switch",
|
|
10
|
+
"turnDetection",
|
|
11
|
+
];
|
|
12
|
+
//# sourceMappingURL=uiFields.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uiFields.types.js","sourceRoot":"","sources":["../../../src/configuration/models/uiFields.types.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG;IAC5B,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,eAAe;CACP,CAAC"}
|
|
@@ -2,4 +2,5 @@ import { Client } from "../index";
|
|
|
2
2
|
import { Collection } from "mongodb";
|
|
3
3
|
export declare const getClientsCollection: () => Collection<Client>;
|
|
4
4
|
export declare const getClientByAPIKey: (apiKey: string) => Promise<Client | null>;
|
|
5
|
+
export declare const getClientByClientId: (clientId: string) => Promise<Client | null>;
|
|
5
6
|
//# sourceMappingURL=clients.getters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clients.getters.d.ts","sourceRoot":"","sources":["../../../src/talkpilot/clients/clients.getters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,eAAO,MAAM,oBAAoB,QAAO,UAAU,CAAC,MAAM,CAExD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,KACb,OAAO,CAAC,MAAM,GAAG,IAAI,CAMvB,CAAC"}
|
|
1
|
+
{"version":3,"file":"clients.getters.d.ts","sourceRoot":"","sources":["../../../src/talkpilot/clients/clients.getters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,eAAO,MAAM,oBAAoB,QAAO,UAAU,CAAC,MAAM,CAExD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,KACb,OAAO,CAAC,MAAM,GAAG,IAAI,CAMvB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAC9B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getClientByAPIKey = exports.getClientsCollection = void 0;
|
|
3
|
+
exports.getClientByClientId = exports.getClientByAPIKey = exports.getClientsCollection = void 0;
|
|
4
4
|
const index_1 = require("../index");
|
|
5
5
|
const getClientsCollection = () => {
|
|
6
6
|
return (0, index_1.getDb)().collection("clients");
|
|
@@ -14,4 +14,6 @@ const getClientByAPIKey = async (apiKey) => {
|
|
|
14
14
|
return client ? client : null;
|
|
15
15
|
};
|
|
16
16
|
exports.getClientByAPIKey = getClientByAPIKey;
|
|
17
|
+
const getClientByClientId = (clientId) => (0, exports.getClientsCollection)().findOne({ clientId });
|
|
18
|
+
exports.getClientByClientId = getClientByClientId;
|
|
17
19
|
//# sourceMappingURL=clients.getters.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clients.getters.js","sourceRoot":"","sources":["../../../src/talkpilot/clients/clients.getters.ts"],"names":[],"mappings":";;;AAAA,oCAAyC;AAGlC,MAAM,oBAAoB,GAAG,GAAuB,EAAE;IAC3D,OAAO,IAAA,aAAK,GAAE,CAAC,UAAU,CAAS,SAAS,CAAC,CAAC;AAC/C,CAAC,CAAC;AAFW,QAAA,oBAAoB,wBAE/B;AAEK,MAAM,iBAAiB,GAAG,KAAK,EACpC,MAAc,EACU,EAAE;IAC1B,MAAM,MAAM,GAAG,MAAM,IAAA,4BAAoB,GAAE,CAAC,OAAO,CAAC;QAClD,MAAM;QACN,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAChC,CAAC,CAAC;AARW,QAAA,iBAAiB,qBAQ5B"}
|
|
1
|
+
{"version":3,"file":"clients.getters.js","sourceRoot":"","sources":["../../../src/talkpilot/clients/clients.getters.ts"],"names":[],"mappings":";;;AAAA,oCAAyC;AAGlC,MAAM,oBAAoB,GAAG,GAAuB,EAAE;IAC3D,OAAO,IAAA,aAAK,GAAE,CAAC,UAAU,CAAS,SAAS,CAAC,CAAC;AAC/C,CAAC,CAAC;AAFW,QAAA,oBAAoB,wBAE/B;AAEK,MAAM,iBAAiB,GAAG,KAAK,EACpC,MAAc,EACU,EAAE;IAC1B,MAAM,MAAM,GAAG,MAAM,IAAA,4BAAoB,GAAE,CAAC,OAAO,CAAC;QAClD,MAAM;QACN,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAChC,CAAC,CAAC;AARW,QAAA,iBAAiB,qBAQ5B;AAEK,MAAM,mBAAmB,GAAG,CAAC,QAAgB,EAA0B,EAAE,CAC9E,IAAA,4BAAoB,GAAE,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;AADlC,QAAA,mBAAmB,uBACe"}
|
|
@@ -13,4 +13,10 @@ export declare const createPurchasedPhoneNumber: (phoneNumber: string, providerP
|
|
|
13
13
|
export declare const findClientByPhoneNumber: (phoneNumber: string) => Promise<Client>;
|
|
14
14
|
export declare const getPrimaryPhoneFlowId: (clientId: string) => Promise<string | null>;
|
|
15
15
|
export declare const bindClientPhoneToFlow: (clientId: string, flowId: string) => Promise<void>;
|
|
16
|
+
export declare const findPhoneNumbersByClientId: (clientId: string) => Promise<PhoneNumber[]>;
|
|
17
|
+
export declare const getOwnedPhoneNumber: (clientId: string, phoneNumber: string) => Promise<PhoneNumber | null>;
|
|
18
|
+
export declare const getPhoneNumberByClientAndFlow: (clientId: string, flowId: string) => Promise<PhoneNumber | null>;
|
|
19
|
+
export declare const clearPhoneNumberFlow: (clientId: string, phoneNumber: string) => Promise<void>;
|
|
20
|
+
export declare const assignExclusiveFlow: (clientId: string, phoneNumber: string, flowId: string) => Promise<void>;
|
|
21
|
+
export declare const unbindFlowFromClientNumbers: (clientId: string, flowId: string) => Promise<void>;
|
|
16
22
|
//# sourceMappingURL=phone_numbers.getter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"phone_numbers.getter.d.ts","sourceRoot":"","sources":["../../../src/talkpilot/phone_numbers/phone_numbers.getter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EACL,MAAM,EAMP,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,wBAAwB,EACxB,WAAW,EACX,mBAAmB,EACnB,6BAA6B,EAC9B,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"phone_numbers.getter.d.ts","sourceRoot":"","sources":["../../../src/talkpilot/phone_numbers/phone_numbers.getter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EACL,MAAM,EAMP,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,wBAAwB,EACxB,WAAW,EACX,mBAAmB,EACnB,6BAA6B,EAC9B,MAAM,uBAAuB,CAAC;AAG/B,eAAO,MAAM,yBAAyB,QAAO,UAAU,CAAC,WAAW,CACjB,CAAC;AAEnD,eAAO,MAAM,yBAAyB,GACpC,aAAa,MAAM,KAClB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAwBpC,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,UAAU,MAAM,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CASvB,CAAC;AAEF,eAAO,MAAM,oBAAoB,aAZrB,MAAM,KACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAWuC,CAAC;AAEhE,eAAO,MAAM,kBAAkB,GAC7B,UAAU,MAAM,EAChB,YAAY,OAAO,KAClB,OAAO,CAAC,WAAW,GAAG,IAAI,CAK5B,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,UAAU,MAAM,KACf,OAAO,CAAC,wBAAwB,EAAE,CAepC,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,aAAa,MAAM,EACnB,QAAQ,MAAM,EACd,UAAU,MAAM,KACf,OAAO,CAAC,WAAW,CAerB,CAAC;AAEF,yFAAyF;AACzF,eAAO,MAAM,0BAA0B,GACrC,aAAa,MAAM,EACnB,iBAAiB,6BAA6B,EAC9C,UAAU,MAAM,EAChB,SAAS,MAAM,GAAG,IAAI,KACrB,OAAO,CAAC,WAAW,CA0BrB,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,aAAa,MAAM,KAClB,OAAO,CAAC,MAAM,CAShB,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAGnF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,UAAU,MAAM,EAChB,QAAQ,MAAM,KACb,OAAO,CAAC,IAAI,CAQd,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,UAAU,MAAM,KACf,OAAO,CAAC,WAAW,EAAE,CAC6C,CAAC;AAEtE,eAAO,MAAM,mBAAmB,GAC9B,UAAU,MAAM,EAChB,aAAa,MAAM,KAClB,OAAO,CAAC,WAAW,GAAG,IAAI,CAIzB,CAAC;AAEL,eAAO,MAAM,6BAA6B,GACxC,UAAU,MAAM,EAChB,QAAQ,MAAM,KACb,OAAO,CAAC,WAAW,GAAG,IAAI,CAIzB,CAAC;AAEL,eAAO,MAAM,oBAAoB,GAC/B,UAAU,MAAM,EAChB,aAAa,MAAM,KAClB,OAAO,CAAC,IAAI,CAKd,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,UAAU,MAAM,EAChB,aAAa,MAAM,EACnB,QAAQ,MAAM,KACb,OAAO,CAAC,IAAI,CAcd,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,UAAU,MAAM,EAChB,QAAQ,MAAM,KACb,OAAO,CAAC,IAAI,CAKd,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.bindClientPhoneToFlow = exports.getPrimaryPhoneFlowId = exports.findClientByPhoneNumber = exports.createPurchasedPhoneNumber = exports.createPhoneNumberEntity = exports.getPhoneNumbersForFlows = exports.getClientPhoneData = exports.getClientPhoneNumber = exports.getClientPrimaryPhoneNumber = exports.getPhoneDataByPhoneNumber = exports.getPhoneNumbersCollection = void 0;
|
|
3
|
+
exports.unbindFlowFromClientNumbers = exports.assignExclusiveFlow = exports.clearPhoneNumberFlow = exports.getPhoneNumberByClientAndFlow = exports.getOwnedPhoneNumber = exports.findPhoneNumbersByClientId = exports.bindClientPhoneToFlow = exports.getPrimaryPhoneFlowId = exports.findClientByPhoneNumber = exports.createPurchasedPhoneNumber = exports.createPhoneNumberEntity = exports.getPhoneNumbersForFlows = exports.getClientPhoneData = exports.getClientPhoneNumber = exports.getClientPrimaryPhoneNumber = exports.getPhoneDataByPhoneNumber = exports.getPhoneNumbersCollection = void 0;
|
|
4
4
|
const index_1 = require("../index");
|
|
5
|
+
const phone_numbers_utils_1 = require("./phone_numbers.utils");
|
|
5
6
|
const getPhoneNumbersCollection = () => (0, index_1.getDb)().collection("phone_numbers");
|
|
6
7
|
exports.getPhoneNumbersCollection = getPhoneNumbersCollection;
|
|
7
8
|
const getPhoneDataByPhoneNumber = async (phoneNumber) => {
|
|
@@ -125,4 +126,34 @@ const bindClientPhoneToFlow = async (clientId, flowId) => {
|
|
|
125
126
|
}
|
|
126
127
|
};
|
|
127
128
|
exports.bindClientPhoneToFlow = bindClientPhoneToFlow;
|
|
129
|
+
const findPhoneNumbersByClientId = (clientId) => (0, exports.getPhoneNumbersCollection)().find({ client_id: clientId }).toArray();
|
|
130
|
+
exports.findPhoneNumbersByClientId = findPhoneNumbersByClientId;
|
|
131
|
+
const getOwnedPhoneNumber = (clientId, phoneNumber) => (0, exports.getPhoneNumbersCollection)().findOne({
|
|
132
|
+
client_id: clientId,
|
|
133
|
+
phone_number: phoneNumber,
|
|
134
|
+
});
|
|
135
|
+
exports.getOwnedPhoneNumber = getOwnedPhoneNumber;
|
|
136
|
+
const getPhoneNumberByClientAndFlow = (clientId, flowId) => (0, exports.getPhoneNumbersCollection)().findOne({
|
|
137
|
+
client_id: clientId,
|
|
138
|
+
$or: (0, phone_numbers_utils_1.flowIdAsObjectIdOrString)(flowId),
|
|
139
|
+
});
|
|
140
|
+
exports.getPhoneNumberByClientAndFlow = getPhoneNumberByClientAndFlow;
|
|
141
|
+
const clearPhoneNumberFlow = async (clientId, phoneNumber) => {
|
|
142
|
+
await (0, exports.getPhoneNumbersCollection)().updateOne({ client_id: clientId, phone_number: phoneNumber }, { $unset: { flow_id: "" }, $set: { updatedAt: new Date() } });
|
|
143
|
+
};
|
|
144
|
+
exports.clearPhoneNumberFlow = clearPhoneNumberFlow;
|
|
145
|
+
const assignExclusiveFlow = async (clientId, phoneNumber, flowId) => {
|
|
146
|
+
const collection = (0, exports.getPhoneNumbersCollection)();
|
|
147
|
+
await collection.updateMany({
|
|
148
|
+
client_id: clientId,
|
|
149
|
+
phone_number: { $ne: phoneNumber },
|
|
150
|
+
$or: (0, phone_numbers_utils_1.flowIdAsObjectIdOrString)(flowId),
|
|
151
|
+
}, { $unset: { flow_id: "" }, $set: { updatedAt: new Date() } });
|
|
152
|
+
await collection.updateOne({ client_id: clientId, phone_number: phoneNumber }, { $set: { flow_id: new index_1.ObjectId(flowId), updatedAt: new Date() } });
|
|
153
|
+
};
|
|
154
|
+
exports.assignExclusiveFlow = assignExclusiveFlow;
|
|
155
|
+
const unbindFlowFromClientNumbers = async (clientId, flowId) => {
|
|
156
|
+
await (0, exports.getPhoneNumbersCollection)().updateMany({ client_id: clientId, $or: (0, phone_numbers_utils_1.flowIdAsObjectIdOrString)(flowId) }, { $unset: { flow_id: "" }, $set: { updatedAt: new Date() } });
|
|
157
|
+
};
|
|
158
|
+
exports.unbindFlowFromClientNumbers = unbindFlowFromClientNumbers;
|
|
128
159
|
//# sourceMappingURL=phone_numbers.getter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"phone_numbers.getter.js","sourceRoot":"","sources":["../../../src/talkpilot/phone_numbers/phone_numbers.getter.ts"],"names":[],"mappings":";;;AACA,oCAOkB;
|
|
1
|
+
{"version":3,"file":"phone_numbers.getter.js","sourceRoot":"","sources":["../../../src/talkpilot/phone_numbers/phone_numbers.getter.ts"],"names":[],"mappings":";;;AACA,oCAOkB;AAOlB,+DAAiE;AAE1D,MAAM,yBAAyB,GAAG,GAA4B,EAAE,CACrE,IAAA,aAAK,GAAE,CAAC,UAAU,CAAc,eAAe,CAAC,CAAC;AADtC,QAAA,yBAAyB,6BACa;AAE5C,MAAM,yBAAyB,GAAG,KAAK,EAC5C,WAAmB,EACkB,EAAE;IACvC,MAAM,aAAa,GAAG,MAAM,IAAA,iCAAyB,GAAE,CAAC,OAAO,CAAC;QAC9D,YAAY,EAAE,WAAW;KAC1B,CAAC,CAAC;IACH,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,IAAA,0BAAkB,GAAE,CAAC,OAAO,CAAC;QAC9C,GAAG,EAAE,IAAI,gBAAQ,CAAC,aAAa,CAAC,OAAO,CAAC;KACzC,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACpC,CAAC;IACD,MAAM,CAAC,YAAY,CAAC,GAClB,CAAC,MAAM,IAAA,yBAAiB,EAAC;QACvB,QAAQ,EAAE,aAAa,CAAC,SAAS;QACjC,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC,IAAI,EAAE,CAAC;IAEZ,OAAO;QACL,GAAG,aAAa;QAChB,IAAI;QACJ,cAAc,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,SAAS;KAC3D,CAAC;AACJ,CAAC,CAAC;AA1BW,QAAA,yBAAyB,6BA0BpC;AAEK,MAAM,2BAA2B,GAAG,KAAK,EAC9C,QAAgB,EACQ,EAAE;IAC1B,OAAO,CACL,CACE,MAAM,IAAA,iCAAyB,GAAE,CAAC,OAAO,CAAC;QACxC,SAAS,EAAE,QAAQ;QACnB,UAAU,EAAE,IAAI;KACjB,CAAC,CACH,EAAE,YAAY,IAAI,IAAI,CACxB,CAAC;AACJ,CAAC,CAAC;AAXW,QAAA,2BAA2B,+BAWtC;AAEW,QAAA,oBAAoB,GAAG,mCAA2B,CAAC;AAEzD,MAAM,kBAAkB,GAAG,KAAK,EACrC,QAAgB,EAChB,SAAmB,EACU,EAAE;IAC/B,MAAM,MAAM,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,KAAK,KAAK,EAAE,CAAC;IACxE,MAAM,OAAO,GACX,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,OAAO,IAAA,iCAAyB,GAAE,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC,CAAC;AARW,QAAA,kBAAkB,sBAQ7B;AAEK,MAAM,uBAAuB,GAAG,KAAK,EAC1C,QAAgB,EACqB,EAAE;IACvC,MAAM,IAAI,GAAG,MAAM,IAAA,iCAAyB,GAAE;SAC3C,IAAI,CAAC;QACJ,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE;KAC9C,CAAC;SACD,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;SAC/D,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC;SACvB,OAAO,EAAE,CAAC;IAEb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;QAC3B,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC,CAAC,CAAC;AACN,CAAC,CAAC;AAjBW,QAAA,uBAAuB,2BAiBlC;AAEK,MAAM,uBAAuB,GAAG,KAAK,EAC1C,WAAmB,EACnB,MAAc,EACd,QAAgB,EACM,EAAE;IACxB,MAAM,QAAQ,GAAG,MAAM,IAAA,0BAAkB,EAAC,QAAQ,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,CAAC,QAAQ,CAAC;IAE5B,MAAM,IAAA,iCAAyB,GAAE,CAAC,SAAS,CAAC;QAC1C,YAAY,EAAE,WAAW;QACzB,OAAO,EAAE,IAAI,gBAAQ,CAAC,MAAM,CAAC;QAC7B,SAAS,EAAE,QAAQ;QACnB,UAAU,EAAE,SAAS;QACrB,SAAS,EAAE,IAAI,IAAI,EAAE;QACrB,SAAS,EAAE,IAAI,IAAI,EAAE;KACtB,CAAC,CAAC;IACH,MAAM,eAAe,GAAG,MAAM,IAAA,0BAAkB,EAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACtE,IAAI,CAAC,eAAe;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACtE,OAAO,eAAe,CAAC;AACzB,CAAC,CAAC;AAnBW,QAAA,uBAAuB,2BAmBlC;AAEF,yFAAyF;AAClF,MAAM,0BAA0B,GAAG,KAAK,EAC7C,WAAmB,EACnB,eAA8C,EAC9C,QAAgB,EAChB,MAAsB,EACA,EAAE;IACxB,MAAM,sBAAsB,GAAG,MAAM,IAAA,0BAAkB,EAAC,QAAQ,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,CAAC,sBAAsB,CAAC;IAE1C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,aAAa,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;IACrC,MAAM,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,gBAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE7E,MAAM,GAAG,GAAgB;QACvB,YAAY,EAAE,WAAW;QACzB,SAAS,EAAE,QAAQ;QACnB,UAAU,EAAE,SAAS;QACrB,GAAG,eAAe;QAClB,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG;KACf,CAAC;IAEF,IAAI,YAAY,EAAE,CAAC;QACjB,GAAG,CAAC,OAAO,GAAG,YAAY,CAAC;IAC7B,CAAC;IAED,MAAM,IAAA,iCAAyB,GAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAEjD,MAAM,OAAO,GAAG,MAAM,IAAA,0BAAkB,EAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC9D,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC9D,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AA/BW,QAAA,0BAA0B,8BA+BrC;AAEK,MAAM,uBAAuB,GAAG,KAAK,EAC1C,WAAmB,EACF,EAAE;IACnB,MAAM,SAAS,GAAG,MAAM,IAAA,iCAAyB,GAAE,CAAC,OAAO,CAAC;QAC1D,YAAY,EAAE,WAAW;KAC1B,CAAC,CAAC;IACH,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,IAAA,4BAAoB,GAAE,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClE,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAXW,QAAA,uBAAuB,2BAWlC;AAEK,MAAM,qBAAqB,GAAG,KAAK,EAAE,QAAgB,EAA0B,EAAE;IACtF,MAAM,KAAK,GAAG,MAAM,IAAA,0BAAkB,EAAC,QAAQ,CAAC,CAAC;IACjD,OAAO,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD,CAAC,CAAC;AAHW,QAAA,qBAAqB,yBAGhC;AAEK,MAAM,qBAAqB,GAAG,KAAK,EACxC,QAAgB,EAChB,MAAc,EACC,EAAE;IACjB,MAAM,MAAM,GAAG,MAAM,IAAA,iCAAyB,GAAE,CAAC,SAAS,CACxD,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,EACzC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,gBAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,CACnE,CAAC;IACF,IAAI,MAAM,CAAC,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,6CAA6C,QAAQ,EAAE,CAAC,CAAC;IAC3E,CAAC;AACH,CAAC,CAAC;AAXW,QAAA,qBAAqB,yBAWhC;AAEK,MAAM,0BAA0B,GAAG,CACxC,QAAgB,EACQ,EAAE,CAC1B,IAAA,iCAAyB,GAAE,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;AAHzD,QAAA,0BAA0B,8BAG+B;AAE/D,MAAM,mBAAmB,GAAG,CACjC,QAAgB,EAChB,WAAmB,EACU,EAAE,CAC/B,IAAA,iCAAyB,GAAE,CAAC,OAAO,CAAC;IAClC,SAAS,EAAE,QAAQ;IACnB,YAAY,EAAE,WAAW;CAC1B,CAAC,CAAC;AAPQ,QAAA,mBAAmB,uBAO3B;AAEE,MAAM,6BAA6B,GAAG,CAC3C,QAAgB,EAChB,MAAc,EACe,EAAE,CAC/B,IAAA,iCAAyB,GAAE,CAAC,OAAO,CAAC;IAClC,SAAS,EAAE,QAAQ;IACnB,GAAG,EAAE,IAAA,8CAAwB,EAAC,MAAM,CAAC;CACtC,CAAC,CAAC;AAPQ,QAAA,6BAA6B,iCAOrC;AAEE,MAAM,oBAAoB,GAAG,KAAK,EACvC,QAAgB,EAChB,WAAmB,EACJ,EAAE;IACjB,MAAM,IAAA,iCAAyB,GAAE,CAAC,SAAS,CACzC,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,EAClD,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,CAC7D,CAAC;AACJ,CAAC,CAAC;AARW,QAAA,oBAAoB,wBAQ/B;AAEK,MAAM,mBAAmB,GAAG,KAAK,EACtC,QAAgB,EAChB,WAAmB,EACnB,MAAc,EACC,EAAE;IACjB,MAAM,UAAU,GAAG,IAAA,iCAAyB,GAAE,CAAC;IAC/C,MAAM,UAAU,CAAC,UAAU,CACzB;QACE,SAAS,EAAE,QAAQ;QACnB,YAAY,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE;QAClC,GAAG,EAAE,IAAA,8CAAwB,EAAC,MAAM,CAAC;KACtC,EACD,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,CAC7D,CAAC;IACF,MAAM,UAAU,CAAC,SAAS,CACxB,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,EAClD,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,gBAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,CACnE,CAAC;AACJ,CAAC,CAAC;AAlBW,QAAA,mBAAmB,uBAkB9B;AAEK,MAAM,2BAA2B,GAAG,KAAK,EAC9C,QAAgB,EAChB,MAAc,EACC,EAAE;IACjB,MAAM,IAAA,iCAAyB,GAAE,CAAC,UAAU,CAC1C,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAA,8CAAwB,EAAC,MAAM,CAAC,EAAE,EAC9D,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,CAC7D,CAAC;AACJ,CAAC,CAAC;AARW,QAAA,2BAA2B,+BAQtC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phone_numbers.utils.d.ts","sourceRoot":"","sources":["../../../src/talkpilot/phone_numbers/phone_numbers.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,2DAA2D;AAC3D,eAAO,MAAM,wBAAwB,GACnC,QAAQ,MAAM,KACb,KAAK,CAAC;IAAE,OAAO,EAAE,QAAQ,CAAA;CAAE,CAG7B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.flowIdAsObjectIdOrString = void 0;
|
|
4
|
+
const mongodb_1 = require("mongodb");
|
|
5
|
+
/** Older phone_numbers rows stored flow_id as a string. */
|
|
6
|
+
const flowIdAsObjectIdOrString = (flowId) => [
|
|
7
|
+
{ flow_id: new mongodb_1.ObjectId(flowId) },
|
|
8
|
+
{ flow_id: flowId },
|
|
9
|
+
];
|
|
10
|
+
exports.flowIdAsObjectIdOrString = flowIdAsObjectIdOrString;
|
|
11
|
+
//# sourceMappingURL=phone_numbers.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phone_numbers.utils.js","sourceRoot":"","sources":["../../../src/talkpilot/phone_numbers/phone_numbers.utils.ts"],"names":[],"mappings":";;;AAAA,qCAAmC;AAEnC,2DAA2D;AACpD,MAAM,wBAAwB,GAAG,CACtC,MAAc,EACgB,EAAE,CAAC;IACjC,EAAE,OAAO,EAAE,IAAI,kBAAQ,CAAC,MAAM,CAAC,EAAE;IACjC,EAAE,OAAO,EAAE,MAA6B,EAAE;CAC3C,CAAC;AALW,QAAA,wBAAwB,4BAKnC"}
|
package/package.json
CHANGED
|
@@ -7,6 +7,12 @@ import {
|
|
|
7
7
|
createPhoneNumberEntity,
|
|
8
8
|
createPurchasedPhoneNumber,
|
|
9
9
|
getPrimaryPhoneFlowId,
|
|
10
|
+
findPhoneNumbersByClientId,
|
|
11
|
+
getOwnedPhoneNumber,
|
|
12
|
+
getPhoneNumberByClientAndFlow,
|
|
13
|
+
clearPhoneNumberFlow,
|
|
14
|
+
assignExclusiveFlow,
|
|
15
|
+
unbindFlowFromClientNumbers,
|
|
10
16
|
} from "../phone_numbers.getter";
|
|
11
17
|
import { getFlowsCollection } from "../../flows/flows.getter";
|
|
12
18
|
import { createFlow, createPhoneNumber } from "../../../test-utils/factories";
|
|
@@ -272,11 +278,253 @@ describe("db.phoneNumbers", () => {
|
|
|
272
278
|
|
|
273
279
|
it("returns null when primary phone has no flow_id", async () => {
|
|
274
280
|
const clientId = "phoneNoFlow";
|
|
275
|
-
const phone = createPhoneNumber({
|
|
281
|
+
const phone = createPhoneNumber({
|
|
282
|
+
client_id: clientId,
|
|
283
|
+
is_primary: true,
|
|
284
|
+
});
|
|
276
285
|
delete phone.flow_id;
|
|
277
286
|
await getPhoneNumbersCollection().insertOne(phone);
|
|
278
287
|
|
|
279
288
|
expect(await getPrimaryPhoneFlowId(clientId)).toBeNull();
|
|
280
289
|
});
|
|
281
290
|
});
|
|
291
|
+
|
|
292
|
+
describe("findPhoneNumbersByClientId", () => {
|
|
293
|
+
it("returns only that client's numbers", async () => {
|
|
294
|
+
const clientId = "list-client";
|
|
295
|
+
await getPhoneNumbersCollection().insertMany([
|
|
296
|
+
createPhoneNumber({ client_id: clientId, phone_number: "+100" }),
|
|
297
|
+
createPhoneNumber({ client_id: clientId, phone_number: "+200" }),
|
|
298
|
+
createPhoneNumber({
|
|
299
|
+
client_id: "other-list-client",
|
|
300
|
+
phone_number: "+300",
|
|
301
|
+
}),
|
|
302
|
+
]);
|
|
303
|
+
|
|
304
|
+
const docs = await findPhoneNumbersByClientId(clientId);
|
|
305
|
+
expect(docs.map((doc) => doc.phone_number).sort()).toEqual([
|
|
306
|
+
"+100",
|
|
307
|
+
"+200",
|
|
308
|
+
]);
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
describe("getOwnedPhoneNumber", () => {
|
|
313
|
+
it("returns the number when it belongs to the client", async () => {
|
|
314
|
+
await getPhoneNumbersCollection().insertOne(
|
|
315
|
+
createPhoneNumber({
|
|
316
|
+
client_id: "owned-client",
|
|
317
|
+
phone_number: "+111",
|
|
318
|
+
}),
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
const doc = await getOwnedPhoneNumber("owned-client", "+111");
|
|
322
|
+
expect(doc?.phone_number).toBe("+111");
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it("returns null when the number belongs to another client", async () => {
|
|
326
|
+
await getPhoneNumbersCollection().insertOne(
|
|
327
|
+
createPhoneNumber({
|
|
328
|
+
client_id: "owned-other",
|
|
329
|
+
phone_number: "+111",
|
|
330
|
+
}),
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
expect(await getOwnedPhoneNumber("owned-client", "+111")).toBeNull();
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
describe("getPhoneNumberByClientAndFlow", () => {
|
|
338
|
+
it("finds a number bound with ObjectId flow_id", async () => {
|
|
339
|
+
const clientId = "flow-oid-client";
|
|
340
|
+
const flowId = new ObjectId();
|
|
341
|
+
await getPhoneNumbersCollection().insertOne(
|
|
342
|
+
createPhoneNumber({
|
|
343
|
+
client_id: clientId,
|
|
344
|
+
phone_number: "+oid",
|
|
345
|
+
flow_id: flowId,
|
|
346
|
+
}),
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
expect(
|
|
350
|
+
(await getPhoneNumberByClientAndFlow(clientId, flowId.toHexString()))
|
|
351
|
+
?.phone_number,
|
|
352
|
+
).toBe("+oid");
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
it("finds a number bound with string-stored flow_id", async () => {
|
|
356
|
+
const clientId = "flow-str-client";
|
|
357
|
+
const flowId = new ObjectId();
|
|
358
|
+
const doc = createPhoneNumber({
|
|
359
|
+
client_id: clientId,
|
|
360
|
+
phone_number: "+str",
|
|
361
|
+
});
|
|
362
|
+
delete doc.flow_id;
|
|
363
|
+
await getPhoneNumbersCollection().insertOne({
|
|
364
|
+
...doc,
|
|
365
|
+
flow_id: flowId.toHexString() as unknown as ObjectId,
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
expect(
|
|
369
|
+
(await getPhoneNumberByClientAndFlow(clientId, flowId.toHexString()))
|
|
370
|
+
?.phone_number,
|
|
371
|
+
).toBe("+str");
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
it("returns null for another client's bind", async () => {
|
|
375
|
+
const flowId = new ObjectId();
|
|
376
|
+
await getPhoneNumbersCollection().insertOne(
|
|
377
|
+
createPhoneNumber({
|
|
378
|
+
client_id: "flow-other-client",
|
|
379
|
+
flow_id: flowId,
|
|
380
|
+
}),
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
expect(
|
|
384
|
+
await getPhoneNumberByClientAndFlow(
|
|
385
|
+
"flow-lookup-client",
|
|
386
|
+
flowId.toHexString(),
|
|
387
|
+
),
|
|
388
|
+
).toBeNull();
|
|
389
|
+
});
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
describe("assignExclusiveFlow", () => {
|
|
393
|
+
it("binds the number and unsets the same client's previous bind", async () => {
|
|
394
|
+
const clientId = "exclusive-client";
|
|
395
|
+
const flowId = new ObjectId();
|
|
396
|
+
await getPhoneNumbersCollection().insertMany([
|
|
397
|
+
createPhoneNumber({
|
|
398
|
+
client_id: clientId,
|
|
399
|
+
phone_number: "+old",
|
|
400
|
+
flow_id: flowId,
|
|
401
|
+
}),
|
|
402
|
+
createPhoneNumber({
|
|
403
|
+
client_id: clientId,
|
|
404
|
+
phone_number: "+new",
|
|
405
|
+
}),
|
|
406
|
+
createPhoneNumber({
|
|
407
|
+
client_id: "exclusive-other",
|
|
408
|
+
phone_number: "+other",
|
|
409
|
+
flow_id: flowId,
|
|
410
|
+
}),
|
|
411
|
+
]);
|
|
412
|
+
|
|
413
|
+
await assignExclusiveFlow(clientId, "+new", flowId.toHexString());
|
|
414
|
+
|
|
415
|
+
const [oldDoc, newDoc, otherDoc] = await Promise.all([
|
|
416
|
+
getPhoneNumbersCollection().findOne({ phone_number: "+old" }),
|
|
417
|
+
getPhoneNumbersCollection().findOne({ phone_number: "+new" }),
|
|
418
|
+
getPhoneNumbersCollection().findOne({ phone_number: "+other" }),
|
|
419
|
+
]);
|
|
420
|
+
expect(oldDoc?.flow_id).toBeUndefined();
|
|
421
|
+
expect(newDoc?.flow_id?.toString()).toBe(flowId.toHexString());
|
|
422
|
+
expect(otherDoc?.flow_id?.toString()).toBe(flowId.toHexString());
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
it("steals when the previous bind stored flow_id as a string", async () => {
|
|
426
|
+
const clientId = "exclusive-string-client";
|
|
427
|
+
const flowId = new ObjectId();
|
|
428
|
+
const previous = createPhoneNumber({
|
|
429
|
+
client_id: clientId,
|
|
430
|
+
phone_number: "+old-str",
|
|
431
|
+
});
|
|
432
|
+
delete previous.flow_id;
|
|
433
|
+
await getPhoneNumbersCollection().insertMany([
|
|
434
|
+
{
|
|
435
|
+
...previous,
|
|
436
|
+
flow_id: flowId.toHexString() as unknown as ObjectId,
|
|
437
|
+
},
|
|
438
|
+
createPhoneNumber({
|
|
439
|
+
client_id: clientId,
|
|
440
|
+
phone_number: "+new-str",
|
|
441
|
+
}),
|
|
442
|
+
]);
|
|
443
|
+
|
|
444
|
+
await assignExclusiveFlow(clientId, "+new-str", flowId.toHexString());
|
|
445
|
+
|
|
446
|
+
const [oldDoc, newDoc] = await Promise.all([
|
|
447
|
+
getPhoneNumbersCollection().findOne({ phone_number: "+old-str" }),
|
|
448
|
+
getPhoneNumbersCollection().findOne({ phone_number: "+new-str" }),
|
|
449
|
+
]);
|
|
450
|
+
expect(oldDoc?.flow_id).toBeUndefined();
|
|
451
|
+
expect(newDoc?.flow_id?.toString()).toBe(flowId.toHexString());
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
describe("clearPhoneNumberFlow", () => {
|
|
456
|
+
it("unsets flow_id on that number only", async () => {
|
|
457
|
+
const clientId = "clear-client";
|
|
458
|
+
const flowA = new ObjectId();
|
|
459
|
+
const flowB = new ObjectId();
|
|
460
|
+
await getPhoneNumbersCollection().insertMany([
|
|
461
|
+
createPhoneNumber({
|
|
462
|
+
client_id: clientId,
|
|
463
|
+
phone_number: "+a",
|
|
464
|
+
flow_id: flowA,
|
|
465
|
+
}),
|
|
466
|
+
createPhoneNumber({
|
|
467
|
+
client_id: clientId,
|
|
468
|
+
phone_number: "+b",
|
|
469
|
+
flow_id: flowB,
|
|
470
|
+
}),
|
|
471
|
+
]);
|
|
472
|
+
|
|
473
|
+
await clearPhoneNumberFlow(clientId, "+a");
|
|
474
|
+
|
|
475
|
+
const [a, b] = await Promise.all([
|
|
476
|
+
getPhoneNumbersCollection().findOne({ phone_number: "+a" }),
|
|
477
|
+
getPhoneNumbersCollection().findOne({ phone_number: "+b" }),
|
|
478
|
+
]);
|
|
479
|
+
expect(a?.flow_id).toBeUndefined();
|
|
480
|
+
expect(b?.flow_id?.toString()).toBe(flowB.toHexString());
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
describe("unbindFlowFromClientNumbers", () => {
|
|
485
|
+
it("clears ObjectId and string-stored flow_id for that client only", async () => {
|
|
486
|
+
const clientId = "unbind-client";
|
|
487
|
+
const flowId = new ObjectId();
|
|
488
|
+
const otherFlowId = new ObjectId();
|
|
489
|
+
const stringDoc = createPhoneNumber({
|
|
490
|
+
client_id: clientId,
|
|
491
|
+
phone_number: "+str-unbind",
|
|
492
|
+
});
|
|
493
|
+
delete stringDoc.flow_id;
|
|
494
|
+
await getPhoneNumbersCollection().insertMany([
|
|
495
|
+
createPhoneNumber({
|
|
496
|
+
client_id: clientId,
|
|
497
|
+
phone_number: "+oid-unbind",
|
|
498
|
+
flow_id: flowId,
|
|
499
|
+
}),
|
|
500
|
+
{
|
|
501
|
+
...stringDoc,
|
|
502
|
+
flow_id: flowId.toHexString() as unknown as ObjectId,
|
|
503
|
+
},
|
|
504
|
+
createPhoneNumber({
|
|
505
|
+
client_id: clientId,
|
|
506
|
+
phone_number: "+keep",
|
|
507
|
+
flow_id: otherFlowId,
|
|
508
|
+
}),
|
|
509
|
+
createPhoneNumber({
|
|
510
|
+
client_id: "unbind-other",
|
|
511
|
+
phone_number: "+other-keep",
|
|
512
|
+
flow_id: flowId,
|
|
513
|
+
}),
|
|
514
|
+
]);
|
|
515
|
+
|
|
516
|
+
await unbindFlowFromClientNumbers(clientId, flowId.toHexString());
|
|
517
|
+
|
|
518
|
+
const [oidDoc, strDoc, keep, other] = await Promise.all([
|
|
519
|
+
getPhoneNumbersCollection().findOne({ phone_number: "+oid-unbind" }),
|
|
520
|
+
getPhoneNumbersCollection().findOne({ phone_number: "+str-unbind" }),
|
|
521
|
+
getPhoneNumbersCollection().findOne({ phone_number: "+keep" }),
|
|
522
|
+
getPhoneNumbersCollection().findOne({ phone_number: "+other-keep" }),
|
|
523
|
+
]);
|
|
524
|
+
expect(oidDoc?.flow_id).toBeUndefined();
|
|
525
|
+
expect(strDoc?.flow_id).toBeUndefined();
|
|
526
|
+
expect(keep?.flow_id?.toString()).toBe(otherFlowId.toHexString());
|
|
527
|
+
expect(other?.flow_id?.toString()).toBe(flowId.toHexString());
|
|
528
|
+
});
|
|
529
|
+
});
|
|
282
530
|
});
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
PhoneNumberWithFlow,
|
|
14
14
|
PurchasedPhoneProviderPayload,
|
|
15
15
|
} from "./phone_numbers.types";
|
|
16
|
+
import { flowIdAsObjectIdOrString } from "./phone_numbers.utils";
|
|
16
17
|
|
|
17
18
|
export const getPhoneNumbersCollection = (): Collection<PhoneNumber> =>
|
|
18
19
|
getDb().collection<PhoneNumber>("phone_numbers");
|
|
@@ -174,3 +175,66 @@ export const bindClientPhoneToFlow = async (
|
|
|
174
175
|
throw new Error(`No primary phone number found for client: ${clientId}`);
|
|
175
176
|
}
|
|
176
177
|
};
|
|
178
|
+
|
|
179
|
+
export const findPhoneNumbersByClientId = (
|
|
180
|
+
clientId: string,
|
|
181
|
+
): Promise<PhoneNumber[]> =>
|
|
182
|
+
getPhoneNumbersCollection().find({ client_id: clientId }).toArray();
|
|
183
|
+
|
|
184
|
+
export const getOwnedPhoneNumber = (
|
|
185
|
+
clientId: string,
|
|
186
|
+
phoneNumber: string,
|
|
187
|
+
): Promise<PhoneNumber | null> =>
|
|
188
|
+
getPhoneNumbersCollection().findOne({
|
|
189
|
+
client_id: clientId,
|
|
190
|
+
phone_number: phoneNumber,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
export const getPhoneNumberByClientAndFlow = (
|
|
194
|
+
clientId: string,
|
|
195
|
+
flowId: string,
|
|
196
|
+
): Promise<PhoneNumber | null> =>
|
|
197
|
+
getPhoneNumbersCollection().findOne({
|
|
198
|
+
client_id: clientId,
|
|
199
|
+
$or: flowIdAsObjectIdOrString(flowId),
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
export const clearPhoneNumberFlow = async (
|
|
203
|
+
clientId: string,
|
|
204
|
+
phoneNumber: string,
|
|
205
|
+
): Promise<void> => {
|
|
206
|
+
await getPhoneNumbersCollection().updateOne(
|
|
207
|
+
{ client_id: clientId, phone_number: phoneNumber },
|
|
208
|
+
{ $unset: { flow_id: "" }, $set: { updatedAt: new Date() } },
|
|
209
|
+
);
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
export const assignExclusiveFlow = async (
|
|
213
|
+
clientId: string,
|
|
214
|
+
phoneNumber: string,
|
|
215
|
+
flowId: string,
|
|
216
|
+
): Promise<void> => {
|
|
217
|
+
const collection = getPhoneNumbersCollection();
|
|
218
|
+
await collection.updateMany(
|
|
219
|
+
{
|
|
220
|
+
client_id: clientId,
|
|
221
|
+
phone_number: { $ne: phoneNumber },
|
|
222
|
+
$or: flowIdAsObjectIdOrString(flowId),
|
|
223
|
+
},
|
|
224
|
+
{ $unset: { flow_id: "" }, $set: { updatedAt: new Date() } },
|
|
225
|
+
);
|
|
226
|
+
await collection.updateOne(
|
|
227
|
+
{ client_id: clientId, phone_number: phoneNumber },
|
|
228
|
+
{ $set: { flow_id: new ObjectId(flowId), updatedAt: new Date() } },
|
|
229
|
+
);
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
export const unbindFlowFromClientNumbers = async (
|
|
233
|
+
clientId: string,
|
|
234
|
+
flowId: string,
|
|
235
|
+
): Promise<void> => {
|
|
236
|
+
await getPhoneNumbersCollection().updateMany(
|
|
237
|
+
{ client_id: clientId, $or: flowIdAsObjectIdOrString(flowId) },
|
|
238
|
+
{ $unset: { flow_id: "" }, $set: { updatedAt: new Date() } },
|
|
239
|
+
);
|
|
240
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ObjectId } from "mongodb";
|
|
2
|
+
|
|
3
|
+
/** Older phone_numbers rows stored flow_id as a string. */
|
|
4
|
+
export const flowIdAsObjectIdOrString = (
|
|
5
|
+
flowId: string,
|
|
6
|
+
): Array<{ flow_id: ObjectId }> => [
|
|
7
|
+
{ flow_id: new ObjectId(flowId) },
|
|
8
|
+
{ flow_id: flowId as unknown as ObjectId },
|
|
9
|
+
];
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"clients.quota.constants.d.ts","sourceRoot":"","sources":["../../../src/talkpilot/clients/clients.quota.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,MAAM,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"clients.quota.constants.js","sourceRoot":"","sources":["../../../src/talkpilot/clients/clients.quota.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,oBAAoB,GAAG,GAAG,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ClientQuotaNotifications, ClientQuotaState, ClientQuotaStatus, QuotaThresholdAlert } from "./clients.quota.types";
|
|
2
|
-
export declare const computeClientQuotaStatus: (quota: ClientQuotaState | null) => ClientQuotaStatus;
|
|
3
|
-
export declare const getQuotaAlerts: (quota?: ClientQuotaState) => QuotaThresholdAlert[];
|
|
4
|
-
export declare const findFullQuotaAlertIndex: (alerts: QuotaThresholdAlert[]) => number;
|
|
5
|
-
export declare const getFullQuotaAlert: (quota?: ClientQuotaState) => QuotaThresholdAlert | undefined;
|
|
6
|
-
export declare const isFullQuotaAlert: (thresholdPct: number) => boolean;
|
|
7
|
-
export declare const toClientQuotaNotifications: (quota: ClientQuotaState | null) => ClientQuotaNotifications;
|
|
8
|
-
//# sourceMappingURL=clients.quota.utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"clients.quota.utils.d.ts","sourceRoot":"","sources":["../../../src/talkpilot/clients/clients.quota.utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAQ/B,eAAO,MAAM,wBAAwB,GACnC,OAAO,gBAAgB,GAAG,IAAI,KAC7B,iBAiBF,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,QAAQ,gBAAgB,KAAG,mBAAmB,EAClC,CAAC;AAE5C,eAAO,MAAM,uBAAuB,GAAI,QAAQ,mBAAmB,EAAE,KAAG,MACP,CAAC;AAElE,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,gBAAgB,KACvB,mBAAmB,GAAG,SAIxB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,cAAc,MAAM,KAAG,OAClB,CAAC;AAEvC,eAAO,MAAM,0BAA0B,GACrC,OAAO,gBAAgB,GAAG,IAAI,KAC7B,wBASD,CAAC"}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toClientQuotaNotifications = exports.isFullQuotaAlert = exports.getFullQuotaAlert = exports.findFullQuotaAlertIndex = exports.getQuotaAlerts = exports.computeClientQuotaStatus = void 0;
|
|
4
|
-
const clients_quota_constants_1 = require("./clients.quota.constants");
|
|
5
|
-
const computeUsagePct = (usedQuota, totalQuota) => totalQuota > 0 ? Math.round((usedQuota / totalQuota) * 100) : 0;
|
|
6
|
-
const isPastExpiration = (expiresAt) => expiresAt ? Date.now() > new Date(expiresAt).getTime() : false;
|
|
7
|
-
const computeClientQuotaStatus = (quota) => {
|
|
8
|
-
if (!quota) {
|
|
9
|
-
return { hasQuota: false };
|
|
10
|
-
}
|
|
11
|
-
const totalQuota = quota.totalQuota;
|
|
12
|
-
const usedQuota = quota.usedQuota ?? 0;
|
|
13
|
-
return {
|
|
14
|
-
hasQuota: true,
|
|
15
|
-
totalQuota,
|
|
16
|
-
usedQuota,
|
|
17
|
-
pct: computeUsagePct(usedQuota, totalQuota),
|
|
18
|
-
expiresAt: quota.expiresAt ? new Date(quota.expiresAt).toISOString() : null,
|
|
19
|
-
isExceeded: usedQuota >= totalQuota,
|
|
20
|
-
isExpired: isPastExpiration(quota.expiresAt),
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
exports.computeClientQuotaStatus = computeClientQuotaStatus;
|
|
24
|
-
const getQuotaAlerts = (quota) => quota?.alerts?.length ? quota.alerts : [];
|
|
25
|
-
exports.getQuotaAlerts = getQuotaAlerts;
|
|
26
|
-
const findFullQuotaAlertIndex = (alerts) => alerts.findIndex((a) => a.thresholdPct >= clients_quota_constants_1.FULL_QUOTA_THRESHOLD);
|
|
27
|
-
exports.findFullQuotaAlertIndex = findFullQuotaAlertIndex;
|
|
28
|
-
const getFullQuotaAlert = (quota) => {
|
|
29
|
-
const alerts = (0, exports.getQuotaAlerts)(quota);
|
|
30
|
-
const index = (0, exports.findFullQuotaAlertIndex)(alerts);
|
|
31
|
-
return index >= 0 ? alerts[index] : undefined;
|
|
32
|
-
};
|
|
33
|
-
exports.getFullQuotaAlert = getFullQuotaAlert;
|
|
34
|
-
const isFullQuotaAlert = (thresholdPct) => thresholdPct >= clients_quota_constants_1.FULL_QUOTA_THRESHOLD;
|
|
35
|
-
exports.isFullQuotaAlert = isFullQuotaAlert;
|
|
36
|
-
const toClientQuotaNotifications = (quota) => ({
|
|
37
|
-
alerts: (0, exports.getQuotaAlerts)(quota ?? undefined).map(({ thresholdPct, recipientEmails, thresholdSent }) => ({
|
|
38
|
-
thresholdPct,
|
|
39
|
-
recipientEmails: recipientEmails ?? [],
|
|
40
|
-
...(thresholdSent ? { thresholdSent: true } : {}),
|
|
41
|
-
})),
|
|
42
|
-
...(quota?.expiredSent ? { expiredSent: true } : {}),
|
|
43
|
-
});
|
|
44
|
-
exports.toClientQuotaNotifications = toClientQuotaNotifications;
|
|
45
|
-
//# sourceMappingURL=clients.quota.utils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"clients.quota.utils.js","sourceRoot":"","sources":["../../../src/talkpilot/clients/clients.quota.utils.ts"],"names":[],"mappings":"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"}
|