@talkpilot/core-db 1.3.47 → 1.3.48
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 +30 -0
- package/dist/configuration/models/models.constants.d.ts +1 -1
- package/dist/configuration/models/models.constants.d.ts.map +1 -1
- package/dist/configuration/models/models.constants.js +1 -1
- package/dist/configuration/models/models.constants.js.map +1 -1
- package/dist/talkpilot/calls/calls.types.d.ts +14 -0
- package/dist/talkpilot/calls/calls.types.d.ts.map +1 -1
- package/dist/websitalk/scanResources/scanResources.getters.d.ts.map +1 -1
- package/dist/websitalk/scanResources/scanResources.getters.js +3 -2
- package/dist/websitalk/scanResources/scanResources.getters.js.map +1 -1
- package/dist/websitalk/scanResources/scanResources.utils.d.ts +1 -0
- package/dist/websitalk/scanResources/scanResources.utils.d.ts.map +1 -1
- package/dist/websitalk/scanResources/scanResources.utils.js +3 -1
- package/dist/websitalk/scanResources/scanResources.utils.js.map +1 -1
- package/package.json +1 -1
- package/src/configuration/models/models.constants.ts +1 -1
- package/src/talkpilot/calls/calls.types.ts +15 -0
- package/src/websitalk/scanResources/__tests__/scanResources.spec.ts +66 -9
- package/src/websitalk/scanResources/scanResources.getters.ts +12 -4
- package/src/websitalk/scanResources/scanResources.utils.ts +3 -0
package/README.md
CHANGED
|
@@ -175,6 +175,8 @@ Refer to `DEVELOPMENT.md` for the full walkthrough, token instructions, and fact
|
|
|
175
175
|
| 1.3.38 | Added optional `transcriptionComparison` field to `Call` (CP-1594): per-`{provider}-{model}` side-channel transcription comparison results, same segment shape as `Call.transcription`. |
|
|
176
176
|
| 1.3.39 | Multi-scan support for WebsiteTalk (CP-1628): `clientsConfig.activeScanIds` (up to `MAX_ACTIVE_SCANS`) and `primaryScanId` replace the single `activeScanId` for search; `addActiveScanId`/`removeActiveScanId`/`getActiveScanIds`, `setPrimaryScanId`/`clearPrimaryScanId`/`getPrimaryScanId`. `getActiveScanIds` falls back to the legacy singular field, so pre-migration clients keep working. |
|
|
177
177
|
| 1.3.40 | Live scan progress for WebsiteTalk (CP-1527): `scanResources` module with KPI counts, board pagination, and page detail; terminal snapshot fields on `Scan`. |
|
|
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
|
+
| 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. |
|
|
178
180
|
|
|
179
181
|
### 1.1.9
|
|
180
182
|
|
|
@@ -735,6 +737,34 @@ No — purely additive, and `getActiveScanIds` keeps working for clients still o
|
|
|
735
737
|
|
|
736
738
|
Adds the `scanResources` module so WebsiteTalk can show live per-page scan progress. Use `getScanKpiCounts` for status totals while a scan is running (do not use `Scan.pagesCompleted` / related fields for live UI — those are a finalize-only snapshot), `getScanPages` for a cursor-paginated board column, and `getScanResourceById` for page detail. `Scan` also gains optional terminal fields (`startedAt`, `completedAt`, `pagesCompleted`, `pagesFailedPermanent`, `pagesDuplicate`) written once when the scan finishes.
|
|
737
739
|
|
|
740
|
+
### 1.3.47 — Account owner email for WebsiteTalk (CP-1715)
|
|
741
|
+
|
|
742
|
+
Adds an optional `accountOwnerEmail` field to `WebsiteTalkProduct`, used by the new end-of-call summary email feature: the recipient is filled in once from the client's login email and can be edited afterward in Settings.
|
|
743
|
+
|
|
744
|
+
**Added**
|
|
745
|
+
|
|
746
|
+
| Export | Purpose |
|
|
747
|
+
| --- | --- |
|
|
748
|
+
| `WebsiteTalkProduct.accountOwnerEmail` | Optional email address that receives the end-of-call summary email. |
|
|
749
|
+
|
|
750
|
+
**Do I need to update my app?**
|
|
751
|
+
|
|
752
|
+
No — purely additive.
|
|
753
|
+
|
|
754
|
+
### 1.3.48 — Fix `getScanPages` search regex escaping (CP-1726)
|
|
755
|
+
|
|
756
|
+
`getScanPages` passed the raw `search` string straight into MongoDB's `$regex` without escaping. Regex-special characters in the input (most commonly `?` in a URL's query string) changed the meaning of the pattern instead of matching literally, so searching for a URL/title containing one returned zero results even though the document existed and was fully processed.
|
|
757
|
+
|
|
758
|
+
**Fixed**
|
|
759
|
+
|
|
760
|
+
| Area | What |
|
|
761
|
+
| --- | --- |
|
|
762
|
+
| `getScanPages` (`scanResources.getters.ts`) | Search input is now escaped via the new `escapeRegex()` helper (`scanResources.utils.ts`) before being used in the `url`/`title` `$regex` filter. Plain-text searches are unaffected. |
|
|
763
|
+
|
|
764
|
+
**Do I need to update my app?**
|
|
765
|
+
|
|
766
|
+
No API changes. **WTIS** (the only current consumer of `getScanPages`) should upgrade to 1.3.48 or later to pick up the fix.
|
|
767
|
+
|
|
738
768
|
## 🛠 CI/CD & deployment
|
|
739
769
|
|
|
740
770
|
- 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,5 +1,5 @@
|
|
|
1
1
|
export declare const MODELS_COLLECTION = "models";
|
|
2
2
|
export declare const MODEL_TYPES: readonly ["realtime", "stt"];
|
|
3
|
-
export declare const REALTIME_MODEL_PROVIDERS: readonly ["openai", "gemini"];
|
|
3
|
+
export declare const REALTIME_MODEL_PROVIDERS: readonly ["openai", "gemini", "xai"];
|
|
4
4
|
export declare const STT_MODEL_PROVIDERS: readonly ["openai-stt", "google-stt", "deepgram-stt", "deepgram-flux", "elevenlabs-scribe", "gladia-stt"];
|
|
5
5
|
//# sourceMappingURL=models.constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.constants.d.ts","sourceRoot":"","sources":["../../../src/configuration/models/models.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C,eAAO,MAAM,WAAW,8BAA+B,CAAC;AAExD,eAAO,MAAM,wBAAwB
|
|
1
|
+
{"version":3,"file":"models.constants.d.ts","sourceRoot":"","sources":["../../../src/configuration/models/models.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C,eAAO,MAAM,WAAW,8BAA+B,CAAC;AAExD,eAAO,MAAM,wBAAwB,sCAAuC,CAAC;AAC7E,eAAO,MAAM,mBAAmB,2GAOtB,CAAC"}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.STT_MODEL_PROVIDERS = exports.REALTIME_MODEL_PROVIDERS = exports.MODEL_TYPES = exports.MODELS_COLLECTION = void 0;
|
|
4
4
|
exports.MODELS_COLLECTION = "models";
|
|
5
5
|
exports.MODEL_TYPES = ["realtime", "stt"];
|
|
6
|
-
exports.REALTIME_MODEL_PROVIDERS = ["openai", "gemini"];
|
|
6
|
+
exports.REALTIME_MODEL_PROVIDERS = ["openai", "gemini", "xai"];
|
|
7
7
|
exports.STT_MODEL_PROVIDERS = [
|
|
8
8
|
"openai-stt",
|
|
9
9
|
"google-stt",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.constants.js","sourceRoot":"","sources":["../../../src/configuration/models/models.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,iBAAiB,GAAG,QAAQ,CAAC;AAE7B,QAAA,WAAW,GAAG,CAAC,UAAU,EAAE,KAAK,CAAU,CAAC;AAE3C,QAAA,wBAAwB,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"models.constants.js","sourceRoot":"","sources":["../../../src/configuration/models/models.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,iBAAiB,GAAG,QAAQ,CAAC;AAE7B,QAAA,WAAW,GAAG,CAAC,UAAU,EAAE,KAAK,CAAU,CAAC;AAE3C,QAAA,wBAAwB,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAU,CAAC;AAChE,QAAA,mBAAmB,GAAG;IACjC,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,eAAe;IACf,mBAAmB;IACnB,YAAY;CACJ,CAAC"}
|
|
@@ -33,9 +33,23 @@ export type Call = {
|
|
|
33
33
|
isConferenceCall?: boolean;
|
|
34
34
|
conferenceRole?: ConferenceRole;
|
|
35
35
|
redirectedCall?: boolean;
|
|
36
|
+
/** Present only on redirected calls: what the dialled leg did. */
|
|
37
|
+
redirectCallLog?: RedirectCallLog;
|
|
36
38
|
toolExecutions?: ToolExecution[];
|
|
37
39
|
transcriptionComparison?: Record<string, TranscriptionSegment[]>;
|
|
38
40
|
};
|
|
41
|
+
/**
|
|
42
|
+
* The outcome of the <Dial> that transferred a call, reported by Twilio when the
|
|
43
|
+
* dialled leg ends. `durationSeconds` is the bridged time, which is 0 when the
|
|
44
|
+
* destination never answered.
|
|
45
|
+
*/
|
|
46
|
+
export type RedirectCallLog = {
|
|
47
|
+
childCallSid?: string;
|
|
48
|
+
to?: string;
|
|
49
|
+
status: CallStatus;
|
|
50
|
+
durationSeconds: number;
|
|
51
|
+
endedAt: Date;
|
|
52
|
+
};
|
|
39
53
|
export type ToolExecution = {
|
|
40
54
|
toolName: string;
|
|
41
55
|
executedAt: Date;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calls.types.d.ts","sourceRoot":"","sources":["../../../src/talkpilot/calls/calls.types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"calls.types.d.ts","sourceRoot":"","sources":["../../../src/talkpilot/calls/calls.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanResources.getters.d.ts","sourceRoot":"","sources":["../../../src/websitalk/scanResources/scanResources.getters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAoB,MAAM,SAAS,CAAC;AAQvD,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACZ,2BAA2B,EAC3B,eAAe,EACf,aAAa,EACd,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"scanResources.getters.d.ts","sourceRoot":"","sources":["../../../src/websitalk/scanResources/scanResources.getters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAoB,MAAM,SAAS,CAAC;AAQvD,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACZ,2BAA2B,EAC3B,eAAe,EACf,aAAa,EACd,MAAM,uBAAuB,CAAC;AAQ/B,eAAO,MAAM,0BAA0B,QAAO,UAAU,CAAC,YAAY,CACR,CAAC;AAE9D,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,MAAM,KACb,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAYhD,CAAC;AAEF,eAAO,MAAM,8BAA8B,GACzC,SAAS,MAAM,EAAE,KAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWhC,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,OAAO,cAAc,KACpB,OAAO,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAoClD,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,MAAM,EACd,QAAQ,MAAM,KACb,OAAO,CAAC,eAAe,GAAG,IAAI,CAC4C,CAAC"}
|
|
@@ -42,9 +42,10 @@ const getScanPages = async (query) => {
|
|
|
42
42
|
filter._id = { $gt: (0, scanResources_utils_1.decodeCursor)(query.cursor) };
|
|
43
43
|
}
|
|
44
44
|
if (query.search) {
|
|
45
|
+
const searchPattern = (0, scanResources_utils_1.escapeRegex)(query.search);
|
|
45
46
|
filter.$or = [
|
|
46
|
-
{ url: { $regex:
|
|
47
|
-
{ title: { $regex:
|
|
47
|
+
{ url: { $regex: searchPattern, $options: "i" } },
|
|
48
|
+
{ title: { $regex: searchPattern, $options: "i" } },
|
|
48
49
|
];
|
|
49
50
|
}
|
|
50
51
|
if (query.since) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanResources.getters.js","sourceRoot":"","sources":["../../../src/websitalk/scanResources/scanResources.getters.ts"],"names":[],"mappings":";;;AAAA,qCAAuD;AACvD,oCAAiC;AACjC,uEAKmC;AASnC,+
|
|
1
|
+
{"version":3,"file":"scanResources.getters.js","sourceRoot":"","sources":["../../../src/websitalk/scanResources/scanResources.getters.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,4 +4,5 @@ export declare const boardColumn: (status: UrlTaskStatus) => BoardColumn;
|
|
|
4
4
|
export declare const statusesForColumn: (column: BoardColumn) => readonly UrlTaskStatus[];
|
|
5
5
|
export declare const encodeCursor: (id: ObjectId) => string;
|
|
6
6
|
export declare const decodeCursor: (cursor: string) => ObjectId;
|
|
7
|
+
export declare const escapeRegex: (text: string) => string;
|
|
7
8
|
//# sourceMappingURL=scanResources.utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanResources.utils.d.ts","sourceRoot":"","sources":["../../../src/websitalk/scanResources/scanResources.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAcxE,eAAO,MAAM,WAAW,GAAI,QAAQ,aAAa,KAAG,WAC1B,CAAC;AAE3B,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,WAAW,KAClB,SAAS,aAAa,EAAmC,CAAC;AAE7D,eAAO,MAAM,YAAY,GAAI,IAAI,QAAQ,KAAG,MACM,CAAC;AAEnD,eAAO,MAAM,YAAY,GAAI,QAAQ,MAAM,KAAG,QACiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"scanResources.utils.d.ts","sourceRoot":"","sources":["../../../src/websitalk/scanResources/scanResources.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAcxE,eAAO,MAAM,WAAW,GAAI,QAAQ,aAAa,KAAG,WAC1B,CAAC;AAE3B,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,WAAW,KAClB,SAAS,aAAa,EAAmC,CAAC;AAE7D,eAAO,MAAM,YAAY,GAAI,IAAI,QAAQ,KAAG,MACM,CAAC;AAEnD,eAAO,MAAM,YAAY,GAAI,QAAQ,MAAM,KAAG,QACiB,CAAC;AAEhE,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,MACE,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.decodeCursor = exports.encodeCursor = exports.statusesForColumn = exports.boardColumn = void 0;
|
|
3
|
+
exports.escapeRegex = exports.decodeCursor = exports.encodeCursor = exports.statusesForColumn = exports.boardColumn = void 0;
|
|
4
4
|
const mongodb_1 = require("mongodb");
|
|
5
5
|
const scanResources_constants_1 = require("./scanResources.constants");
|
|
6
6
|
const STATUS_TO_COLUMN = Object.entries(scanResources_constants_1.BOARD_COLUMN_STATUSES).reduce((acc, [column, statuses]) => {
|
|
@@ -17,4 +17,6 @@ const encodeCursor = (id) => Buffer.from(id.toHexString()).toString("base64");
|
|
|
17
17
|
exports.encodeCursor = encodeCursor;
|
|
18
18
|
const decodeCursor = (cursor) => new mongodb_1.ObjectId(Buffer.from(cursor, "base64").toString("utf-8"));
|
|
19
19
|
exports.decodeCursor = decodeCursor;
|
|
20
|
+
const escapeRegex = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
21
|
+
exports.escapeRegex = escapeRegex;
|
|
20
22
|
//# sourceMappingURL=scanResources.utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanResources.utils.js","sourceRoot":"","sources":["../../../src/websitalk/scanResources/scanResources.utils.ts"],"names":[],"mappings":";;;AAAA,qCAAmC;AACnC,uEAAkE;AAGlE,MAAM,gBAAgB,GAAuC,MAAM,CAAC,OAAO,CACzE,+CAAqB,CACtB,CAAC,MAAM,CACN,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE;IAC1B,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,MAAqB,CAAC;IACtC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,EACD,EAAwC,CACzC,CAAC;AAEK,MAAM,WAAW,GAAG,CAAC,MAAqB,EAAe,EAAE,CAChE,gBAAgB,CAAC,MAAM,CAAC,CAAC;AADd,QAAA,WAAW,eACG;AAEpB,MAAM,iBAAiB,GAAG,CAC/B,MAAmB,EACO,EAAE,CAAC,+CAAqB,CAAC,MAAM,CAAC,CAAC;AAFhD,QAAA,iBAAiB,qBAE+B;AAEtD,MAAM,YAAY,GAAG,CAAC,EAAY,EAAU,EAAE,CACnD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AADtC,QAAA,YAAY,gBAC0B;AAE5C,MAAM,YAAY,GAAG,CAAC,MAAc,EAAY,EAAE,CACvD,IAAI,kBAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AADnD,QAAA,YAAY,gBACuC"}
|
|
1
|
+
{"version":3,"file":"scanResources.utils.js","sourceRoot":"","sources":["../../../src/websitalk/scanResources/scanResources.utils.ts"],"names":[],"mappings":";;;AAAA,qCAAmC;AACnC,uEAAkE;AAGlE,MAAM,gBAAgB,GAAuC,MAAM,CAAC,OAAO,CACzE,+CAAqB,CACtB,CAAC,MAAM,CACN,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE;IAC1B,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,MAAqB,CAAC;IACtC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,EACD,EAAwC,CACzC,CAAC;AAEK,MAAM,WAAW,GAAG,CAAC,MAAqB,EAAe,EAAE,CAChE,gBAAgB,CAAC,MAAM,CAAC,CAAC;AADd,QAAA,WAAW,eACG;AAEpB,MAAM,iBAAiB,GAAG,CAC/B,MAAmB,EACO,EAAE,CAAC,+CAAqB,CAAC,MAAM,CAAC,CAAC;AAFhD,QAAA,iBAAiB,qBAE+B;AAEtD,MAAM,YAAY,GAAG,CAAC,EAAY,EAAU,EAAE,CACnD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AADtC,QAAA,YAAY,gBAC0B;AAE5C,MAAM,YAAY,GAAG,CAAC,MAAc,EAAY,EAAE,CACvD,IAAI,kBAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AADnD,QAAA,YAAY,gBACuC;AAEzD,MAAM,WAAW,GAAG,CAAC,IAAY,EAAU,EAAE,CAClD,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AADjC,QAAA,WAAW,eACsB"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@ export const MODELS_COLLECTION = "models";
|
|
|
2
2
|
|
|
3
3
|
export const MODEL_TYPES = ["realtime", "stt"] as const;
|
|
4
4
|
|
|
5
|
-
export const REALTIME_MODEL_PROVIDERS = ["openai", "gemini"] as const;
|
|
5
|
+
export const REALTIME_MODEL_PROVIDERS = ["openai", "gemini", "xai"] as const;
|
|
6
6
|
export const STT_MODEL_PROVIDERS = [
|
|
7
7
|
"openai-stt",
|
|
8
8
|
"google-stt",
|
|
@@ -44,10 +44,25 @@ export type Call = {
|
|
|
44
44
|
isConferenceCall?: boolean;
|
|
45
45
|
conferenceRole?: ConferenceRole;
|
|
46
46
|
redirectedCall?: boolean;
|
|
47
|
+
/** Present only on redirected calls: what the dialled leg did. */
|
|
48
|
+
redirectCallLog?: RedirectCallLog;
|
|
47
49
|
toolExecutions?: ToolExecution[];
|
|
48
50
|
transcriptionComparison?: Record<string, TranscriptionSegment[]>;
|
|
49
51
|
};
|
|
50
52
|
|
|
53
|
+
/**
|
|
54
|
+
* The outcome of the <Dial> that transferred a call, reported by Twilio when the
|
|
55
|
+
* dialled leg ends. `durationSeconds` is the bridged time, which is 0 when the
|
|
56
|
+
* destination never answered.
|
|
57
|
+
*/
|
|
58
|
+
export type RedirectCallLog = {
|
|
59
|
+
childCallSid?: string;
|
|
60
|
+
to?: string;
|
|
61
|
+
status: CallStatus;
|
|
62
|
+
durationSeconds: number;
|
|
63
|
+
endedAt: Date;
|
|
64
|
+
};
|
|
65
|
+
|
|
51
66
|
export type ToolExecution = {
|
|
52
67
|
toolName: string;
|
|
53
68
|
executedAt: Date;
|
|
@@ -52,12 +52,23 @@ describe("db.websitalk.scanResources", () => {
|
|
|
52
52
|
scanId,
|
|
53
53
|
status: "URL_COMPLETED",
|
|
54
54
|
context: "heavy markdown content",
|
|
55
|
-
stageLogs: [
|
|
55
|
+
stageLogs: [
|
|
56
|
+
{
|
|
57
|
+
from: null,
|
|
58
|
+
to: "URL_COMPLETED",
|
|
59
|
+
occurredAt: new Date(),
|
|
60
|
+
details: {},
|
|
61
|
+
},
|
|
62
|
+
],
|
|
56
63
|
}),
|
|
57
64
|
),
|
|
58
65
|
);
|
|
59
66
|
|
|
60
|
-
const page1 = await getScanPages({
|
|
67
|
+
const page1 = await getScanPages({
|
|
68
|
+
scanId,
|
|
69
|
+
column: "COMPLETED",
|
|
70
|
+
limit: 2,
|
|
71
|
+
});
|
|
61
72
|
expect(page1.items).toHaveLength(2);
|
|
62
73
|
expect(page1.nextCursor).not.toBeNull();
|
|
63
74
|
page1.items.forEach((item) => {
|
|
@@ -89,6 +100,29 @@ describe("db.websitalk.scanResources", () => {
|
|
|
89
100
|
const failed = await getScanPages({ scanId, column: "FAILED" });
|
|
90
101
|
expect(failed.items).toHaveLength(2);
|
|
91
102
|
});
|
|
103
|
+
|
|
104
|
+
it("finds a URL containing regex-special characters when searched verbatim", async () => {
|
|
105
|
+
const scanId = new ObjectId().toString();
|
|
106
|
+
const url =
|
|
107
|
+
"https://www.industry.org.il/index.php?dir=site&page=expert&op=item&cs=3022";
|
|
108
|
+
await getScanResourcesCollection().insertMany([
|
|
109
|
+
createScanResourceFixture({ scanId, status: "URL_COMPLETED", url }),
|
|
110
|
+
createScanResourceFixture({
|
|
111
|
+
scanId,
|
|
112
|
+
status: "URL_COMPLETED",
|
|
113
|
+
url: "https://example.com/other",
|
|
114
|
+
}),
|
|
115
|
+
]);
|
|
116
|
+
|
|
117
|
+
const result = await getScanPages({
|
|
118
|
+
scanId,
|
|
119
|
+
column: "COMPLETED",
|
|
120
|
+
search: url,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
expect(result.items).toHaveLength(1);
|
|
124
|
+
expect(result.items[0].url).toBe(url);
|
|
125
|
+
});
|
|
92
126
|
});
|
|
93
127
|
|
|
94
128
|
describe("getScanResourceCountsByScanIds()", () => {
|
|
@@ -101,7 +135,11 @@ describe("db.websitalk.scanResources", () => {
|
|
|
101
135
|
createScanResourceFixture({ scanId: scanB, status: "URL_PENDING" }),
|
|
102
136
|
]);
|
|
103
137
|
|
|
104
|
-
const counts = await getScanResourceCountsByScanIds([
|
|
138
|
+
const counts = await getScanResourceCountsByScanIds([
|
|
139
|
+
scanA,
|
|
140
|
+
scanB,
|
|
141
|
+
"missing",
|
|
142
|
+
]);
|
|
105
143
|
expect(counts[scanA]).toBe(2);
|
|
106
144
|
expect(counts[scanB]).toBe(1);
|
|
107
145
|
expect(counts.missing).toBeUndefined();
|
|
@@ -112,11 +150,26 @@ describe("db.websitalk.scanResources", () => {
|
|
|
112
150
|
it("returns the full document including stageLogs in insertion order", async () => {
|
|
113
151
|
const scanId = new ObjectId().toString();
|
|
114
152
|
const stageLogs = [
|
|
115
|
-
{
|
|
116
|
-
|
|
153
|
+
{
|
|
154
|
+
from: null,
|
|
155
|
+
to: "URL_PENDING" as const,
|
|
156
|
+
occurredAt: new Date("2024-01-01"),
|
|
157
|
+
details: {},
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
from: "URL_PENDING" as const,
|
|
161
|
+
to: "URL_SCANNING" as const,
|
|
162
|
+
occurredAt: new Date("2024-01-02"),
|
|
163
|
+
details: {},
|
|
164
|
+
},
|
|
117
165
|
];
|
|
118
|
-
const fixture = createScanResourceFixture({
|
|
119
|
-
|
|
166
|
+
const fixture = createScanResourceFixture({
|
|
167
|
+
scanId,
|
|
168
|
+
stageLogs,
|
|
169
|
+
context: "full content",
|
|
170
|
+
});
|
|
171
|
+
const { insertedId } =
|
|
172
|
+
await getScanResourcesCollection().insertOne(fixture);
|
|
120
173
|
|
|
121
174
|
const result = await getScanResourceById(scanId, insertedId.toString());
|
|
122
175
|
|
|
@@ -126,9 +179,13 @@ describe("db.websitalk.scanResources", () => {
|
|
|
126
179
|
|
|
127
180
|
it("returns null when the scan does not match", async () => {
|
|
128
181
|
const fixture = createScanResourceFixture();
|
|
129
|
-
const { insertedId } =
|
|
182
|
+
const { insertedId } =
|
|
183
|
+
await getScanResourcesCollection().insertOne(fixture);
|
|
130
184
|
|
|
131
|
-
const result = await getScanResourceById(
|
|
185
|
+
const result = await getScanResourceById(
|
|
186
|
+
new ObjectId().toString(),
|
|
187
|
+
insertedId.toString(),
|
|
188
|
+
);
|
|
132
189
|
|
|
133
190
|
expect(result).toBeNull();
|
|
134
191
|
});
|
|
@@ -14,7 +14,12 @@ import type {
|
|
|
14
14
|
ScanResourceDoc,
|
|
15
15
|
UrlTaskStatus,
|
|
16
16
|
} from "./scanResources.types";
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
decodeCursor,
|
|
19
|
+
encodeCursor,
|
|
20
|
+
escapeRegex,
|
|
21
|
+
statusesForColumn,
|
|
22
|
+
} from "./scanResources.utils";
|
|
18
23
|
|
|
19
24
|
export const getScanResourcesCollection = (): Collection<ScanResource> =>
|
|
20
25
|
getDb().collection<ScanResource>(SCAN_RESOURCES_COLLECTION);
|
|
@@ -63,9 +68,10 @@ export const getScanPages = async (
|
|
|
63
68
|
filter._id = { $gt: decodeCursor(query.cursor) };
|
|
64
69
|
}
|
|
65
70
|
if (query.search) {
|
|
71
|
+
const searchPattern = escapeRegex(query.search);
|
|
66
72
|
filter.$or = [
|
|
67
|
-
{ url: { $regex:
|
|
68
|
-
{ title: { $regex:
|
|
73
|
+
{ url: { $regex: searchPattern, $options: "i" } },
|
|
74
|
+
{ title: { $regex: searchPattern, $options: "i" } },
|
|
69
75
|
];
|
|
70
76
|
}
|
|
71
77
|
if (query.since) {
|
|
@@ -81,7 +87,9 @@ export const getScanPages = async (
|
|
|
81
87
|
.toArray();
|
|
82
88
|
|
|
83
89
|
const hasMore = docs.length > limit;
|
|
84
|
-
const items = (
|
|
90
|
+
const items = (
|
|
91
|
+
hasMore ? docs.slice(0, limit) : docs
|
|
92
|
+
) as ScanResourceBoardProjection[];
|
|
85
93
|
const nextCursor = hasMore ? encodeCursor(items[items.length - 1]._id) : null;
|
|
86
94
|
|
|
87
95
|
return { items, nextCursor };
|
|
@@ -26,3 +26,6 @@ export const encodeCursor = (id: ObjectId): string =>
|
|
|
26
26
|
|
|
27
27
|
export const decodeCursor = (cursor: string): ObjectId =>
|
|
28
28
|
new ObjectId(Buffer.from(cursor, "base64").toString("utf-8"));
|
|
29
|
+
|
|
30
|
+
export const escapeRegex = (text: string): string =>
|
|
31
|
+
text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|