@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 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,+BAAgC,CAAC;AACtE,eAAO,MAAM,mBAAmB,2GAOtB,CAAC"}
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;AACzD,QAAA,mBAAmB,GAAG;IACjC,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,eAAe;IACf,mBAAmB;IACnB,YAAY;CACJ,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;AAG/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,CAiClD,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,MAAM,EACd,QAAQ,MAAM,KACb,OAAO,CAAC,eAAe,GAAG,IAAI,CAC4C,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: query.search, $options: "i" } },
47
- { title: { $regex: query.search, $options: "i" } },
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":"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"}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@talkpilot/core-db",
3
- "version": "1.3.47",
3
+ "version": "1.3.48",
4
4
  "description": "Core database package for centralized connections and ORM integration.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -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: [{ from: null, to: "URL_COMPLETED", occurredAt: new Date(), details: {} }],
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({ scanId, column: "COMPLETED", limit: 2 });
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([scanA, scanB, "missing"]);
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
- { from: null, to: "URL_PENDING" as const, occurredAt: new Date("2024-01-01"), details: {} },
116
- { from: "URL_PENDING" as const, to: "URL_SCANNING" as const, occurredAt: new Date("2024-01-02"), details: {} },
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({ scanId, stageLogs, context: "full content" });
119
- const { insertedId } = await getScanResourcesCollection().insertOne(fixture);
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 } = await getScanResourcesCollection().insertOne(fixture);
182
+ const { insertedId } =
183
+ await getScanResourcesCollection().insertOne(fixture);
130
184
 
131
- const result = await getScanResourceById(new ObjectId().toString(), insertedId.toString());
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 { decodeCursor, encodeCursor, statusesForColumn } from "./scanResources.utils";
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: query.search, $options: "i" } },
68
- { title: { $regex: query.search, $options: "i" } },
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 = (hasMore ? docs.slice(0, limit) : docs) as ScanResourceBoardProjection[];
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, "\\$&");