@lhremote/core 0.1.0 → 0.2.1
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 +124 -0
- package/dist/cdp/app-discovery.d.ts +22 -0
- package/dist/cdp/app-discovery.d.ts.map +1 -0
- package/dist/cdp/app-discovery.js +60 -0
- package/dist/cdp/app-discovery.js.map +1 -0
- package/dist/cdp/app-discovery.test.d.ts +2 -0
- package/dist/cdp/app-discovery.test.d.ts.map +1 -0
- package/dist/cdp/app-discovery.test.js +124 -0
- package/dist/cdp/app-discovery.test.js.map +1 -0
- package/dist/cdp/client.d.ts +14 -0
- package/dist/cdp/client.d.ts.map +1 -1
- package/dist/cdp/client.integration.test.js +10 -3
- package/dist/cdp/client.integration.test.js.map +1 -1
- package/dist/cdp/client.js +41 -8
- package/dist/cdp/client.js.map +1 -1
- package/dist/cdp/client.test.js +267 -3
- package/dist/cdp/client.test.js.map +1 -1
- package/dist/cdp/discovery.d.ts.map +1 -1
- package/dist/cdp/discovery.integration.test.js +2 -0
- package/dist/cdp/discovery.integration.test.js.map +1 -1
- package/dist/cdp/discovery.js +2 -0
- package/dist/cdp/discovery.js.map +1 -1
- package/dist/cdp/discovery.test.js +2 -0
- package/dist/cdp/discovery.test.js.map +1 -1
- package/dist/cdp/errors.d.ts.map +1 -1
- package/dist/cdp/errors.js +2 -0
- package/dist/cdp/errors.js.map +1 -1
- package/dist/cdp/errors.test.js +2 -0
- package/dist/cdp/errors.test.js.map +1 -1
- package/dist/cdp/index.d.ts +1 -0
- package/dist/cdp/index.d.ts.map +1 -1
- package/dist/cdp/index.js +3 -0
- package/dist/cdp/index.js.map +1 -1
- package/dist/cdp/instance-discovery.d.ts.map +1 -1
- package/dist/cdp/instance-discovery.integration.test.js +2 -0
- package/dist/cdp/instance-discovery.integration.test.js.map +1 -1
- package/dist/cdp/instance-discovery.js +5 -17
- package/dist/cdp/instance-discovery.js.map +1 -1
- package/dist/cdp/instance-discovery.test.js +2 -0
- package/dist/cdp/instance-discovery.test.js.map +1 -1
- package/dist/cdp/testing/launch-chromium.d.ts.map +1 -1
- package/dist/cdp/testing/launch-chromium.js +4 -1
- package/dist/cdp/testing/launch-chromium.js.map +1 -1
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +7 -0
- package/dist/constants.js.map +1 -0
- package/dist/data/action-types.d.ts +39 -0
- package/dist/data/action-types.d.ts.map +1 -0
- package/dist/data/action-types.js +497 -0
- package/dist/data/action-types.js.map +1 -0
- package/dist/data/action-types.test.d.ts +2 -0
- package/dist/data/action-types.test.d.ts.map +1 -0
- package/dist/data/action-types.test.js +544 -0
- package/dist/data/action-types.test.js.map +1 -0
- package/dist/data/index.d.ts +3 -0
- package/dist/data/index.d.ts.map +1 -0
- package/dist/data/index.js +4 -0
- package/dist/data/index.js.map +1 -0
- package/dist/db/client.d.ts +19 -5
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.integration.test.js +5 -1
- package/dist/db/client.integration.test.js.map +1 -1
- package/dist/db/client.js +11 -5
- package/dist/db/client.js.map +1 -1
- package/dist/db/client.test.js +2 -0
- package/dist/db/client.test.js.map +1 -1
- package/dist/db/discovery.d.ts.map +1 -1
- package/dist/db/discovery.integration.test.js +2 -0
- package/dist/db/discovery.integration.test.js.map +1 -1
- package/dist/db/discovery.js +2 -0
- package/dist/db/discovery.js.map +1 -1
- package/dist/db/discovery.test.js +2 -0
- package/dist/db/discovery.test.js.map +1 -1
- package/dist/db/errors.d.ts +31 -0
- package/dist/db/errors.d.ts.map +1 -1
- package/dist/db/errors.js +49 -0
- package/dist/db/errors.js.map +1 -1
- package/dist/db/errors.test.js +2 -0
- package/dist/db/errors.test.js.map +1 -1
- package/dist/db/escape-like.d.ts +8 -0
- package/dist/db/escape-like.d.ts.map +1 -0
- package/dist/db/escape-like.js +12 -0
- package/dist/db/escape-like.js.map +1 -0
- package/dist/db/escape-like.test.d.ts +2 -0
- package/dist/db/escape-like.test.d.ts.map +1 -0
- package/dist/db/escape-like.test.js +25 -0
- package/dist/db/escape-like.test.js.map +1 -0
- package/dist/db/index.d.ts +3 -3
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +4 -2
- package/dist/db/index.js.map +1 -1
- package/dist/db/repositories/campaign-exclude-list.d.ts +89 -0
- package/dist/db/repositories/campaign-exclude-list.d.ts.map +1 -0
- package/dist/db/repositories/campaign-exclude-list.js +204 -0
- package/dist/db/repositories/campaign-exclude-list.js.map +1 -0
- package/dist/db/repositories/campaign-exclude-list.test.d.ts +2 -0
- package/dist/db/repositories/campaign-exclude-list.test.d.ts.map +1 -0
- package/dist/db/repositories/campaign-exclude-list.test.js +132 -0
- package/dist/db/repositories/campaign-exclude-list.test.js.map +1 -0
- package/dist/db/repositories/campaign-statistics.d.ts +58 -0
- package/dist/db/repositories/campaign-statistics.d.ts.map +1 -0
- package/dist/db/repositories/campaign-statistics.js +278 -0
- package/dist/db/repositories/campaign-statistics.js.map +1 -0
- package/dist/db/repositories/campaign-statistics.test.d.ts +2 -0
- package/dist/db/repositories/campaign-statistics.test.d.ts.map +1 -0
- package/dist/db/repositories/campaign-statistics.test.js +266 -0
- package/dist/db/repositories/campaign-statistics.test.js.map +1 -0
- package/dist/db/repositories/campaign.d.ts +103 -0
- package/dist/db/repositories/campaign.d.ts.map +1 -0
- package/dist/db/repositories/campaign.js +388 -0
- package/dist/db/repositories/campaign.js.map +1 -0
- package/dist/db/repositories/campaign.test.d.ts +2 -0
- package/dist/db/repositories/campaign.test.d.ts.map +1 -0
- package/dist/db/repositories/campaign.test.js +392 -0
- package/dist/db/repositories/campaign.test.js.map +1 -0
- package/dist/db/repositories/index.d.ts +4 -0
- package/dist/db/repositories/index.d.ts.map +1 -1
- package/dist/db/repositories/index.js +6 -0
- package/dist/db/repositories/index.js.map +1 -1
- package/dist/db/repositories/message.d.ts +57 -0
- package/dist/db/repositories/message.d.ts.map +1 -0
- package/dist/db/repositories/message.integration.test.d.ts +2 -0
- package/dist/db/repositories/message.integration.test.d.ts.map +1 -0
- package/dist/db/repositories/message.integration.test.js +137 -0
- package/dist/db/repositories/message.integration.test.js.map +1 -0
- package/dist/db/repositories/message.js +308 -0
- package/dist/db/repositories/message.js.map +1 -0
- package/dist/db/repositories/message.test.d.ts +2 -0
- package/dist/db/repositories/message.test.d.ts.map +1 -0
- package/dist/db/repositories/message.test.js +179 -0
- package/dist/db/repositories/message.test.js.map +1 -0
- package/dist/db/repositories/profile.d.ts +11 -1
- package/dist/db/repositories/profile.d.ts.map +1 -1
- package/dist/db/repositories/profile.integration.test.js +103 -0
- package/dist/db/repositories/profile.integration.test.js.map +1 -1
- package/dist/db/repositories/profile.js +52 -15
- package/dist/db/repositories/profile.js.map +1 -1
- package/dist/db/repositories/profile.test.js +90 -0
- package/dist/db/repositories/profile.test.js.map +1 -1
- package/dist/db/testing/create-fixture.d.ts +0 -6
- package/dist/db/testing/create-fixture.d.ts.map +1 -1
- package/dist/db/testing/create-fixture.js +463 -4
- package/dist/db/testing/create-fixture.js.map +1 -1
- package/dist/db/testing/open-fixture.d.ts +5 -4
- package/dist/db/testing/open-fixture.d.ts.map +1 -1
- package/dist/db/testing/open-fixture.js +24 -6
- package/dist/db/testing/open-fixture.js.map +1 -1
- package/dist/formats/campaign-format.d.ts +31 -0
- package/dist/formats/campaign-format.d.ts.map +1 -0
- package/dist/formats/campaign-format.js +225 -0
- package/dist/formats/campaign-format.js.map +1 -0
- package/dist/formats/campaign-format.test.d.ts +2 -0
- package/dist/formats/campaign-format.test.d.ts.map +1 -0
- package/dist/formats/campaign-format.test.js +442 -0
- package/dist/formats/campaign-format.test.js.map +1 -0
- package/dist/formats/errors.d.ts +7 -0
- package/dist/formats/errors.d.ts.map +1 -0
- package/dist/formats/errors.js +12 -0
- package/dist/formats/errors.js.map +1 -0
- package/dist/formats/index.d.ts +3 -0
- package/dist/formats/index.d.ts.map +1 -0
- package/dist/formats/index.js +5 -0
- package/dist/formats/index.js.map +1 -0
- package/dist/index.d.ts +10 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -4
- package/dist/index.js.map +1 -1
- package/dist/operations/campaign-add-action.d.ts +14 -0
- package/dist/operations/campaign-add-action.d.ts.map +1 -0
- package/dist/operations/campaign-add-action.js +33 -0
- package/dist/operations/campaign-add-action.js.map +1 -0
- package/dist/operations/campaign-add-action.test.d.ts +2 -0
- package/dist/operations/campaign-add-action.test.d.ts.map +1 -0
- package/dist/operations/campaign-add-action.test.js +122 -0
- package/dist/operations/campaign-add-action.test.js.map +1 -0
- package/dist/operations/campaign-create.d.ts +17 -0
- package/dist/operations/campaign-create.d.ts.map +1 -0
- package/dist/operations/campaign-create.js +21 -0
- package/dist/operations/campaign-create.js.map +1 -0
- package/dist/operations/campaign-create.test.d.ts +2 -0
- package/dist/operations/campaign-create.test.d.ts.map +1 -0
- package/dist/operations/campaign-create.test.js +121 -0
- package/dist/operations/campaign-create.test.js.map +1 -0
- package/dist/operations/campaign-delete.d.ts +20 -0
- package/dist/operations/campaign-delete.d.ts.map +1 -0
- package/dist/operations/campaign-delete.js +22 -0
- package/dist/operations/campaign-delete.js.map +1 -0
- package/dist/operations/campaign-delete.test.d.ts +2 -0
- package/dist/operations/campaign-delete.test.d.ts.map +1 -0
- package/dist/operations/campaign-delete.test.js +92 -0
- package/dist/operations/campaign-delete.test.js.map +1 -0
- package/dist/operations/campaign-exclude-add.d.ts +16 -0
- package/dist/operations/campaign-exclude-add.d.ts.map +1 -0
- package/dist/operations/campaign-exclude-add.js +27 -0
- package/dist/operations/campaign-exclude-add.js.map +1 -0
- package/dist/operations/campaign-exclude-add.test.d.ts +2 -0
- package/dist/operations/campaign-exclude-add.test.d.ts.map +1 -0
- package/dist/operations/campaign-exclude-add.test.js +114 -0
- package/dist/operations/campaign-exclude-add.test.js.map +1 -0
- package/dist/operations/campaign-exclude-list.d.ts +14 -0
- package/dist/operations/campaign-exclude-list.d.ts.map +1 -0
- package/dist/operations/campaign-exclude-list.js +26 -0
- package/dist/operations/campaign-exclude-list.js.map +1 -0
- package/dist/operations/campaign-exclude-list.test.d.ts +2 -0
- package/dist/operations/campaign-exclude-list.test.d.ts.map +1 -0
- package/dist/operations/campaign-exclude-list.test.js +113 -0
- package/dist/operations/campaign-exclude-list.test.js.map +1 -0
- package/dist/operations/campaign-exclude-remove.d.ts +16 -0
- package/dist/operations/campaign-exclude-remove.d.ts.map +1 -0
- package/dist/operations/campaign-exclude-remove.js +27 -0
- package/dist/operations/campaign-exclude-remove.js.map +1 -0
- package/dist/operations/campaign-exclude-remove.test.d.ts +2 -0
- package/dist/operations/campaign-exclude-remove.test.d.ts.map +1 -0
- package/dist/operations/campaign-exclude-remove.test.js +114 -0
- package/dist/operations/campaign-exclude-remove.test.js.map +1 -0
- package/dist/operations/campaign-export.d.ts +12 -0
- package/dist/operations/campaign-export.d.ts.map +1 -0
- package/dist/operations/campaign-export.js +24 -0
- package/dist/operations/campaign-export.js.map +1 -0
- package/dist/operations/campaign-export.test.d.ts +2 -0
- package/dist/operations/campaign-export.test.d.ts.map +1 -0
- package/dist/operations/campaign-export.test.js +134 -0
- package/dist/operations/campaign-export.test.js.map +1 -0
- package/dist/operations/campaign-get.d.ts +19 -0
- package/dist/operations/campaign-get.d.ts.map +1 -0
- package/dist/operations/campaign-get.js +23 -0
- package/dist/operations/campaign-get.js.map +1 -0
- package/dist/operations/campaign-get.test.d.ts +2 -0
- package/dist/operations/campaign-get.test.d.ts.map +1 -0
- package/dist/operations/campaign-get.test.js +99 -0
- package/dist/operations/campaign-get.test.js.map +1 -0
- package/dist/operations/campaign-list.d.ts +20 -0
- package/dist/operations/campaign-list.d.ts.map +1 -0
- package/dist/operations/campaign-list.js +23 -0
- package/dist/operations/campaign-list.js.map +1 -0
- package/dist/operations/campaign-list.test.d.ts +2 -0
- package/dist/operations/campaign-list.test.d.ts.map +1 -0
- package/dist/operations/campaign-list.test.js +106 -0
- package/dist/operations/campaign-list.test.js.map +1 -0
- package/dist/operations/campaign-move-next.d.ts +15 -0
- package/dist/operations/campaign-move-next.d.ts.map +1 -0
- package/dist/operations/campaign-move-next.js +25 -0
- package/dist/operations/campaign-move-next.js.map +1 -0
- package/dist/operations/campaign-move-next.test.d.ts +2 -0
- package/dist/operations/campaign-move-next.test.d.ts.map +1 -0
- package/dist/operations/campaign-move-next.test.js +105 -0
- package/dist/operations/campaign-move-next.test.js.map +1 -0
- package/dist/operations/campaign-remove-action.d.ts +12 -0
- package/dist/operations/campaign-remove-action.d.ts.map +1 -0
- package/dist/operations/campaign-remove-action.js +23 -0
- package/dist/operations/campaign-remove-action.js.map +1 -0
- package/dist/operations/campaign-remove-action.test.d.ts +2 -0
- package/dist/operations/campaign-remove-action.test.d.ts.map +1 -0
- package/dist/operations/campaign-remove-action.test.js +95 -0
- package/dist/operations/campaign-remove-action.test.js.map +1 -0
- package/dist/operations/campaign-reorder-actions.d.ts +13 -0
- package/dist/operations/campaign-reorder-actions.d.ts.map +1 -0
- package/dist/operations/campaign-reorder-actions.js +19 -0
- package/dist/operations/campaign-reorder-actions.js.map +1 -0
- package/dist/operations/campaign-reorder-actions.test.d.ts +2 -0
- package/dist/operations/campaign-reorder-actions.test.d.ts.map +1 -0
- package/dist/operations/campaign-reorder-actions.test.js +103 -0
- package/dist/operations/campaign-reorder-actions.test.js.map +1 -0
- package/dist/operations/campaign-retry.d.ts +13 -0
- package/dist/operations/campaign-retry.d.ts.map +1 -0
- package/dist/operations/campaign-retry.js +24 -0
- package/dist/operations/campaign-retry.js.map +1 -0
- package/dist/operations/campaign-retry.test.d.ts +2 -0
- package/dist/operations/campaign-retry.test.d.ts.map +1 -0
- package/dist/operations/campaign-retry.test.js +100 -0
- package/dist/operations/campaign-retry.test.js.map +1 -0
- package/dist/operations/campaign-start.d.ts +13 -0
- package/dist/operations/campaign-start.d.ts.map +1 -0
- package/dist/operations/campaign-start.js +24 -0
- package/dist/operations/campaign-start.js.map +1 -0
- package/dist/operations/campaign-start.test.d.ts +2 -0
- package/dist/operations/campaign-start.test.d.ts.map +1 -0
- package/dist/operations/campaign-start.test.js +105 -0
- package/dist/operations/campaign-start.test.js.map +1 -0
- package/dist/operations/campaign-statistics.d.ts +10 -0
- package/dist/operations/campaign-statistics.d.ts.map +1 -0
- package/dist/operations/campaign-statistics.js +23 -0
- package/dist/operations/campaign-statistics.js.map +1 -0
- package/dist/operations/campaign-statistics.test.d.ts +2 -0
- package/dist/operations/campaign-statistics.test.d.ts.map +1 -0
- package/dist/operations/campaign-statistics.test.js +120 -0
- package/dist/operations/campaign-statistics.test.js.map +1 -0
- package/dist/operations/campaign-status.d.ts +26 -0
- package/dist/operations/campaign-status.d.ts.map +1 -0
- package/dist/operations/campaign-status.js +32 -0
- package/dist/operations/campaign-status.js.map +1 -0
- package/dist/operations/campaign-status.test.d.ts +2 -0
- package/dist/operations/campaign-status.test.d.ts.map +1 -0
- package/dist/operations/campaign-status.test.js +142 -0
- package/dist/operations/campaign-status.test.js.map +1 -0
- package/dist/operations/campaign-stop.d.ts +11 -0
- package/dist/operations/campaign-stop.d.ts.map +1 -0
- package/dist/operations/campaign-stop.js +23 -0
- package/dist/operations/campaign-stop.js.map +1 -0
- package/dist/operations/campaign-stop.test.d.ts +2 -0
- package/dist/operations/campaign-stop.test.d.ts.map +1 -0
- package/dist/operations/campaign-stop.test.js +92 -0
- package/dist/operations/campaign-stop.test.js.map +1 -0
- package/dist/operations/campaign-update.d.ts +18 -0
- package/dist/operations/campaign-update.d.ts.map +1 -0
- package/dist/operations/campaign-update.js +21 -0
- package/dist/operations/campaign-update.js.map +1 -0
- package/dist/operations/campaign-update.test.d.ts +2 -0
- package/dist/operations/campaign-update.test.d.ts.map +1 -0
- package/dist/operations/campaign-update.test.js +105 -0
- package/dist/operations/campaign-update.test.js.map +1 -0
- package/dist/operations/check-replies.d.ts +12 -0
- package/dist/operations/check-replies.d.ts.map +1 -0
- package/dist/operations/check-replies.js +26 -0
- package/dist/operations/check-replies.js.map +1 -0
- package/dist/operations/check-replies.test.d.ts +2 -0
- package/dist/operations/check-replies.test.d.ts.map +1 -0
- package/dist/operations/check-replies.test.js +118 -0
- package/dist/operations/check-replies.test.js.map +1 -0
- package/dist/operations/import-people-from-urls.d.ts +16 -0
- package/dist/operations/import-people-from-urls.d.ts.map +1 -0
- package/dist/operations/import-people-from-urls.js +27 -0
- package/dist/operations/import-people-from-urls.js.map +1 -0
- package/dist/operations/import-people-from-urls.test.d.ts +2 -0
- package/dist/operations/import-people-from-urls.test.d.ts.map +1 -0
- package/dist/operations/import-people-from-urls.test.js +118 -0
- package/dist/operations/import-people-from-urls.test.js.map +1 -0
- package/dist/operations/index.d.ts +24 -0
- package/dist/operations/index.d.ts.map +1 -0
- package/dist/operations/index.js +30 -0
- package/dist/operations/index.js.map +1 -0
- package/dist/operations/query-messages.d.ts +23 -0
- package/dist/operations/query-messages.d.ts.map +1 -0
- package/dist/operations/query-messages.js +33 -0
- package/dist/operations/query-messages.js.map +1 -0
- package/dist/operations/query-messages.test.d.ts +2 -0
- package/dist/operations/query-messages.test.d.ts.map +1 -0
- package/dist/operations/query-messages.test.js +134 -0
- package/dist/operations/query-messages.test.js.map +1 -0
- package/dist/operations/scrape-messaging-history.d.ts +10 -0
- package/dist/operations/scrape-messaging-history.d.ts.map +1 -0
- package/dist/operations/scrape-messaging-history.js +24 -0
- package/dist/operations/scrape-messaging-history.js.map +1 -0
- package/dist/operations/scrape-messaging-history.test.d.ts +2 -0
- package/dist/operations/scrape-messaging-history.test.d.ts.map +1 -0
- package/dist/operations/scrape-messaging-history.test.js +112 -0
- package/dist/operations/scrape-messaging-history.test.js.map +1 -0
- package/dist/operations/types.d.ts +10 -0
- package/dist/operations/types.d.ts.map +1 -0
- package/dist/operations/types.js +4 -0
- package/dist/operations/types.js.map +1 -0
- package/dist/services/account-resolution.d.ts +22 -0
- package/dist/services/account-resolution.d.ts.map +1 -0
- package/dist/services/account-resolution.js +45 -0
- package/dist/services/account-resolution.js.map +1 -0
- package/dist/services/account-resolution.test.d.ts +2 -0
- package/dist/services/account-resolution.test.d.ts.map +1 -0
- package/dist/services/account-resolution.test.js +91 -0
- package/dist/services/account-resolution.test.js.map +1 -0
- package/dist/services/app.d.ts.map +1 -1
- package/dist/services/app.js +2 -0
- package/dist/services/app.js.map +1 -1
- package/dist/services/app.test.js +2 -0
- package/dist/services/app.test.js.map +1 -1
- package/dist/services/campaign.d.ts +143 -0
- package/dist/services/campaign.d.ts.map +1 -0
- package/dist/services/campaign.js +409 -0
- package/dist/services/campaign.js.map +1 -0
- package/dist/services/campaign.test.d.ts +2 -0
- package/dist/services/campaign.test.d.ts.map +1 -0
- package/dist/services/campaign.test.js +481 -0
- package/dist/services/campaign.test.js.map +1 -0
- package/dist/services/errors.d.ts +38 -0
- package/dist/services/errors.d.ts.map +1 -1
- package/dist/services/errors.js +60 -0
- package/dist/services/errors.js.map +1 -1
- package/dist/services/errors.test.js +53 -1
- package/dist/services/errors.test.js.map +1 -1
- package/dist/services/index.d.ts +5 -3
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +6 -2
- package/dist/services/index.js.map +1 -1
- package/dist/services/instance-context.d.ts +37 -0
- package/dist/services/instance-context.d.ts.map +1 -0
- package/dist/services/instance-context.js +49 -0
- package/dist/services/instance-context.js.map +1 -0
- package/dist/services/instance-context.test.d.ts +2 -0
- package/dist/services/instance-context.test.d.ts.map +1 -0
- package/dist/services/instance-context.test.js +203 -0
- package/dist/services/instance-context.test.js.map +1 -0
- package/dist/services/instance-lifecycle.d.ts.map +1 -1
- package/dist/services/instance-lifecycle.js +6 -6
- package/dist/services/instance-lifecycle.js.map +1 -1
- package/dist/services/instance-lifecycle.test.js +8 -2
- package/dist/services/instance-lifecycle.test.js.map +1 -1
- package/dist/services/instance.d.ts +40 -0
- package/dist/services/instance.d.ts.map +1 -1
- package/dist/services/instance.js +66 -9
- package/dist/services/instance.js.map +1 -1
- package/dist/services/instance.test.js +116 -6
- package/dist/services/instance.test.js.map +1 -1
- package/dist/services/launcher.d.ts +3 -0
- package/dist/services/launcher.d.ts.map +1 -1
- package/dist/services/launcher.js +25 -10
- package/dist/services/launcher.js.map +1 -1
- package/dist/services/launcher.test.js +39 -2
- package/dist/services/launcher.test.js.map +1 -1
- package/dist/services/status.d.ts +5 -1
- package/dist/services/status.d.ts.map +1 -1
- package/dist/services/status.js +24 -15
- package/dist/services/status.js.map +1 -1
- package/dist/services/status.test.js +42 -1
- package/dist/services/status.test.js.map +1 -1
- package/dist/testing/e2e-helpers.d.ts.map +1 -1
- package/dist/testing/e2e-helpers.js +7 -4
- package/dist/testing/e2e-helpers.js.map +1 -1
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +4 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types/account.d.ts.map +1 -1
- package/dist/types/account.js +2 -0
- package/dist/types/account.js.map +1 -1
- package/dist/types/account.test.js +2 -0
- package/dist/types/account.test.js.map +1 -1
- package/dist/types/campaign.d.ts +267 -0
- package/dist/types/campaign.d.ts.map +1 -0
- package/dist/types/campaign.js +4 -0
- package/dist/types/campaign.js.map +1 -0
- package/dist/types/cdp.d.ts.map +1 -1
- package/dist/types/cdp.js +2 -0
- package/dist/types/cdp.js.map +1 -1
- package/dist/types/cdp.test.js +2 -0
- package/dist/types/cdp.test.js.map +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/instance.d.ts.map +1 -1
- package/dist/types/instance.js +2 -6
- package/dist/types/instance.js.map +1 -1
- package/dist/types/instance.test.js +2 -0
- package/dist/types/instance.test.js.map +1 -1
- package/dist/types/messaging.d.ts +51 -0
- package/dist/types/messaging.d.ts.map +1 -0
- package/dist/types/messaging.js +4 -0
- package/dist/types/messaging.js.map +1 -0
- package/dist/types/profile.d.ts +31 -0
- package/dist/types/profile.d.ts.map +1 -1
- package/dist/types/profile.js +2 -6
- package/dist/types/profile.js.map +1 -1
- package/dist/types/profile.test.js +2 -0
- package/dist/types/profile.test.js.map +1 -1
- package/dist/utils/cdp-port.d.ts +5 -0
- package/dist/utils/cdp-port.d.ts.map +1 -0
- package/dist/utils/cdp-port.js +15 -0
- package/dist/utils/cdp-port.js.map +1 -0
- package/dist/utils/cdp-port.test.d.ts +2 -0
- package/dist/utils/cdp-port.test.d.ts.map +1 -0
- package/dist/utils/cdp-port.test.js +23 -0
- package/dist/utils/cdp-port.test.js.map +1 -0
- package/dist/utils/delay.d.ts +5 -0
- package/dist/utils/delay.d.ts.map +1 -0
- package/dist/utils/delay.js +9 -0
- package/dist/utils/delay.js.map +1 -0
- package/dist/utils/delay.test.d.ts +2 -0
- package/dist/utils/delay.test.d.ts.map +1 -0
- package/dist/utils/delay.test.js +17 -0
- package/dist/utils/delay.test.js.map +1 -0
- package/dist/utils/error-message.d.ts +5 -0
- package/dist/utils/error-message.d.ts.map +1 -0
- package/dist/utils/error-message.js +9 -0
- package/dist/utils/error-message.js.map +1 -0
- package/dist/utils/error-message.test.d.ts +2 -0
- package/dist/utils/error-message.test.d.ts.map +1 -0
- package/dist/utils/error-message.test.js +28 -0
- package/dist/utils/error-message.test.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/loopback.d.ts +10 -0
- package/dist/utils/loopback.d.ts.map +1 -0
- package/dist/utils/loopback.js +28 -0
- package/dist/utils/loopback.js.map +1 -0
- package/dist/utils/loopback.test.d.ts +2 -0
- package/dist/utils/loopback.test.d.ts.map +1 -0
- package/dist/utils/loopback.test.js +34 -0
- package/dist/utils/loopback.test.js.map +1 -0
- package/package.json +13 -8
- package/dist/services/profile.d.ts +0 -44
- package/dist/services/profile.d.ts.map +0 -1
- package/dist/services/profile.js +0 -83
- package/dist/services/profile.js.map +0 -1
- package/dist/services/profile.test.d.ts +0 -2
- package/dist/services/profile.test.d.ts.map +0 -1
- package/dist/services/profile.test.js +0 -145
- package/dist/services/profile.test.js.map +0 -1
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { ActionNotFoundError, CampaignNotFoundError, } from "../errors.js";
|
|
4
|
+
/**
|
|
5
|
+
* Repository for campaign statistics and reset operations.
|
|
6
|
+
*
|
|
7
|
+
* Provides read operations (getStatistics) and write operations
|
|
8
|
+
* (resetForRerun) for campaign execution data.
|
|
9
|
+
*
|
|
10
|
+
* Write operations require the DatabaseClient to be opened with
|
|
11
|
+
* `{ readOnly: false }`.
|
|
12
|
+
*/
|
|
13
|
+
export class CampaignStatisticsRepository {
|
|
14
|
+
client;
|
|
15
|
+
stmtGetCampaign;
|
|
16
|
+
stmtGetCampaignActions;
|
|
17
|
+
stmtGetActionVersions;
|
|
18
|
+
// Write statements (prepared lazily to avoid issues with read-only mode)
|
|
19
|
+
writeStatements = null;
|
|
20
|
+
constructor(client) {
|
|
21
|
+
this.client = client;
|
|
22
|
+
const { db } = client;
|
|
23
|
+
this.stmtGetCampaign = db.prepare(`SELECT id, name, description, is_paused, is_archived, is_valid,
|
|
24
|
+
li_account_id, created_at
|
|
25
|
+
FROM campaigns WHERE id = ?`);
|
|
26
|
+
this.stmtGetCampaignActions = db.prepare(`SELECT a.id, a.campaign_id, a.name, a.description,
|
|
27
|
+
ac.id AS config_id, ac.actionType AS action_type,
|
|
28
|
+
ac.actionSettings AS action_settings, ac.coolDown AS cool_down,
|
|
29
|
+
ac.maxActionResultsPerIteration AS max_action_results_per_iteration,
|
|
30
|
+
ac.isDraft AS is_draft, av.id AS version_id
|
|
31
|
+
FROM actions a
|
|
32
|
+
JOIN action_versions av ON av.action_id = a.id
|
|
33
|
+
JOIN action_configs ac ON av.config_id = ac.id
|
|
34
|
+
WHERE a.campaign_id = ?
|
|
35
|
+
ORDER BY a.id`);
|
|
36
|
+
this.stmtGetActionVersions = db.prepare(`SELECT av.id, av.action_id
|
|
37
|
+
FROM action_versions av
|
|
38
|
+
JOIN actions a ON av.action_id = a.id
|
|
39
|
+
WHERE a.campaign_id = ?`);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get aggregated statistics for a campaign.
|
|
43
|
+
*
|
|
44
|
+
* Returns per-action result breakdowns (success/failure/skip/reply rates),
|
|
45
|
+
* top error codes with blame attribution, and processing timeline.
|
|
46
|
+
*
|
|
47
|
+
* @throws {CampaignNotFoundError} if no campaign exists with the given ID.
|
|
48
|
+
* @throws {ActionNotFoundError} if actionId is provided and not in the campaign.
|
|
49
|
+
*/
|
|
50
|
+
getStatistics(campaignId, options = {}) {
|
|
51
|
+
const { actionId, maxErrors = 5 } = options;
|
|
52
|
+
// Get actions (also validates campaign exists)
|
|
53
|
+
const actions = this.getCampaignActions(campaignId);
|
|
54
|
+
if (actionId !== undefined) {
|
|
55
|
+
if (!actions.some((a) => a.id === actionId)) {
|
|
56
|
+
throw new ActionNotFoundError(actionId, campaignId);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const filteredActions = actionId !== undefined
|
|
60
|
+
? actions.filter((a) => a.id === actionId)
|
|
61
|
+
: actions;
|
|
62
|
+
const { db } = this.client;
|
|
63
|
+
const stmtActionStats = db.prepare(`SELECT
|
|
64
|
+
SUM(CASE WHEN ar.result = 1 THEN 1 ELSE 0 END) AS successful,
|
|
65
|
+
SUM(CASE WHEN ar.result = 2 THEN 1 ELSE 0 END) AS replied,
|
|
66
|
+
SUM(CASE WHEN ar.result = -1 THEN 1 ELSE 0 END) AS failed,
|
|
67
|
+
SUM(CASE WHEN ar.result = -2 THEN 1 ELSE 0 END) AS skipped,
|
|
68
|
+
COUNT(*) AS total,
|
|
69
|
+
MIN(ar.created_at) AS first_result_at,
|
|
70
|
+
MAX(ar.created_at) AS last_result_at
|
|
71
|
+
FROM action_results ar
|
|
72
|
+
JOIN action_versions av ON ar.action_version_id = av.id
|
|
73
|
+
WHERE av.action_id = ?`);
|
|
74
|
+
const stmtTopErrors = db.prepare(`SELECT
|
|
75
|
+
arf.code,
|
|
76
|
+
COUNT(*) AS cnt,
|
|
77
|
+
arf.is_exception,
|
|
78
|
+
arf.who_to_blame
|
|
79
|
+
FROM action_result_flags arf
|
|
80
|
+
JOIN action_results ar ON arf.action_result_id = ar.id
|
|
81
|
+
JOIN action_versions av ON ar.action_version_id = av.id
|
|
82
|
+
WHERE av.action_id = ? AND arf.code IS NOT NULL
|
|
83
|
+
GROUP BY arf.code, arf.is_exception, arf.who_to_blame
|
|
84
|
+
ORDER BY cnt DESC
|
|
85
|
+
LIMIT ?`);
|
|
86
|
+
const actionStats = [];
|
|
87
|
+
let totalSuccessful = 0;
|
|
88
|
+
let totalReplied = 0;
|
|
89
|
+
let totalFailed = 0;
|
|
90
|
+
let totalSkipped = 0;
|
|
91
|
+
let grandTotal = 0;
|
|
92
|
+
for (const action of filteredActions) {
|
|
93
|
+
const stats = stmtActionStats.get(action.id);
|
|
94
|
+
const successful = stats.successful ?? 0;
|
|
95
|
+
const replied = stats.replied ?? 0;
|
|
96
|
+
const failed = stats.failed ?? 0;
|
|
97
|
+
const skipped = stats.skipped ?? 0;
|
|
98
|
+
const total = stats.total ?? 0;
|
|
99
|
+
const successRate = total > 0
|
|
100
|
+
? Math.round(((successful + replied) / total) * 1000) / 10
|
|
101
|
+
: 0;
|
|
102
|
+
const errorRows = stmtTopErrors.all(action.id, maxErrors);
|
|
103
|
+
const topErrors = errorRows.map((e) => ({
|
|
104
|
+
code: e.code,
|
|
105
|
+
count: e.cnt,
|
|
106
|
+
isException: e.is_exception === 1,
|
|
107
|
+
whoToBlame: e.who_to_blame,
|
|
108
|
+
}));
|
|
109
|
+
actionStats.push({
|
|
110
|
+
actionId: action.id,
|
|
111
|
+
actionName: action.name,
|
|
112
|
+
actionType: action.config.actionType,
|
|
113
|
+
successful,
|
|
114
|
+
replied,
|
|
115
|
+
failed,
|
|
116
|
+
skipped,
|
|
117
|
+
total,
|
|
118
|
+
successRate,
|
|
119
|
+
firstResultAt: stats.first_result_at,
|
|
120
|
+
lastResultAt: stats.last_result_at,
|
|
121
|
+
topErrors,
|
|
122
|
+
});
|
|
123
|
+
totalSuccessful += successful;
|
|
124
|
+
totalReplied += replied;
|
|
125
|
+
totalFailed += failed;
|
|
126
|
+
totalSkipped += skipped;
|
|
127
|
+
grandTotal += total;
|
|
128
|
+
}
|
|
129
|
+
const totalSuccessRate = grandTotal > 0
|
|
130
|
+
? Math.round(((totalSuccessful + totalReplied) / grandTotal) * 1000) / 10
|
|
131
|
+
: 0;
|
|
132
|
+
return {
|
|
133
|
+
campaignId,
|
|
134
|
+
actions: actionStats,
|
|
135
|
+
totals: {
|
|
136
|
+
successful: totalSuccessful,
|
|
137
|
+
replied: totalReplied,
|
|
138
|
+
failed: totalFailed,
|
|
139
|
+
skipped: totalSkipped,
|
|
140
|
+
total: grandTotal,
|
|
141
|
+
successRate: totalSuccessRate,
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Reset persons for re-run in a campaign.
|
|
147
|
+
*
|
|
148
|
+
* This performs the three-table reset pattern required by LinkedHelper:
|
|
149
|
+
* 1. Requeue person in action_target_people (state = 1)
|
|
150
|
+
* 2. Reset person_in_campaigns_history (result_status = -999)
|
|
151
|
+
* 3. Delete old action_results (and FK children)
|
|
152
|
+
*
|
|
153
|
+
* @throws {CampaignNotFoundError} if no campaign exists with the given ID.
|
|
154
|
+
*/
|
|
155
|
+
resetForRerun(campaignId, personIds) {
|
|
156
|
+
if (personIds.length === 0)
|
|
157
|
+
return;
|
|
158
|
+
// Verify campaign exists and get actions
|
|
159
|
+
const actions = this.getCampaignActions(campaignId);
|
|
160
|
+
if (actions.length === 0)
|
|
161
|
+
return;
|
|
162
|
+
// Get all action versions for this campaign
|
|
163
|
+
const actionVersionRows = this.stmtGetActionVersions.all(campaignId);
|
|
164
|
+
const stmts = this.getWriteStatements();
|
|
165
|
+
this.client.db.exec("BEGIN");
|
|
166
|
+
try {
|
|
167
|
+
for (const personId of personIds) {
|
|
168
|
+
// 1. Requeue person in action_target_people for each action
|
|
169
|
+
for (const action of actions) {
|
|
170
|
+
stmts.resetTargetPeople.run(action.id, personId);
|
|
171
|
+
}
|
|
172
|
+
// 2. Reset campaign history
|
|
173
|
+
stmts.resetHistory.run(campaignId, personId);
|
|
174
|
+
// 3. Delete old results for each action version
|
|
175
|
+
for (const version of actionVersionRows) {
|
|
176
|
+
stmts.deleteResultFlags.run(version.id, personId);
|
|
177
|
+
stmts.deleteResultMessages.run(version.id, personId);
|
|
178
|
+
stmts.deleteResults.run(version.id, personId);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
this.client.db.exec("COMMIT");
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
this.client.db.exec("ROLLBACK");
|
|
185
|
+
throw e;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Get all actions for a campaign.
|
|
190
|
+
*
|
|
191
|
+
* @throws {CampaignNotFoundError} if no campaign exists with the given ID.
|
|
192
|
+
*/
|
|
193
|
+
getCampaignActions(campaignId) {
|
|
194
|
+
// Verify campaign exists
|
|
195
|
+
this.verifyCampaignExists(campaignId);
|
|
196
|
+
const rows = this.stmtGetCampaignActions.all(campaignId);
|
|
197
|
+
return rows.map((r) => {
|
|
198
|
+
let actionSettings = {};
|
|
199
|
+
try {
|
|
200
|
+
actionSettings = JSON.parse(r.action_settings);
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
// Keep empty object if parsing fails
|
|
204
|
+
}
|
|
205
|
+
const config = {
|
|
206
|
+
id: r.config_id,
|
|
207
|
+
actionType: r.action_type,
|
|
208
|
+
actionSettings,
|
|
209
|
+
coolDown: r.cool_down,
|
|
210
|
+
maxActionResultsPerIteration: r.max_action_results_per_iteration,
|
|
211
|
+
isDraft: r.is_draft === 1,
|
|
212
|
+
};
|
|
213
|
+
return {
|
|
214
|
+
id: r.id,
|
|
215
|
+
campaignId: r.campaign_id,
|
|
216
|
+
name: r.name,
|
|
217
|
+
description: r.description,
|
|
218
|
+
config,
|
|
219
|
+
versionId: r.version_id,
|
|
220
|
+
};
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Prepare write statements lazily (only when needed).
|
|
225
|
+
* This avoids issues when the client is opened in read-only mode.
|
|
226
|
+
*/
|
|
227
|
+
getWriteStatements() {
|
|
228
|
+
if (this.writeStatements)
|
|
229
|
+
return this.writeStatements;
|
|
230
|
+
const { db } = this.client;
|
|
231
|
+
this.writeStatements = {
|
|
232
|
+
resetTargetPeople: db.prepare(`UPDATE action_target_people SET state = 1
|
|
233
|
+
WHERE action_id = ? AND person_id = ?`),
|
|
234
|
+
resetHistory: db.prepare(`UPDATE person_in_campaigns_history
|
|
235
|
+
SET result_status = -999,
|
|
236
|
+
result_id = NULL,
|
|
237
|
+
result_action_version_id = NULL,
|
|
238
|
+
result_action_iteration_id = NULL,
|
|
239
|
+
result_created_at = NULL,
|
|
240
|
+
result_data = NULL,
|
|
241
|
+
result_data_message = NULL,
|
|
242
|
+
result_code = NULL,
|
|
243
|
+
result_is_exception = NULL,
|
|
244
|
+
result_who_to_blame = NULL,
|
|
245
|
+
result_is_retryable = NULL,
|
|
246
|
+
result_flag_recipient_replied = NULL,
|
|
247
|
+
result_flag_sender_messaged = NULL,
|
|
248
|
+
result_invited_platform = NULL,
|
|
249
|
+
result_messaged_platform = NULL,
|
|
250
|
+
add_to_target_or_result_saved_date = add_to_target_date
|
|
251
|
+
WHERE campaign_id = ? AND person_id = ?`),
|
|
252
|
+
deleteResultFlags: db.prepare(`DELETE FROM action_result_flags
|
|
253
|
+
WHERE action_result_id IN (
|
|
254
|
+
SELECT id FROM action_results
|
|
255
|
+
WHERE action_version_id = ? AND person_id = ?
|
|
256
|
+
)`),
|
|
257
|
+
deleteResultMessages: db.prepare(`DELETE FROM action_result_messages
|
|
258
|
+
WHERE action_result_id IN (
|
|
259
|
+
SELECT id FROM action_results
|
|
260
|
+
WHERE action_version_id = ? AND person_id = ?
|
|
261
|
+
)`),
|
|
262
|
+
deleteResults: db.prepare(`DELETE FROM action_results
|
|
263
|
+
WHERE action_version_id = ? AND person_id = ?`),
|
|
264
|
+
};
|
|
265
|
+
return this.writeStatements;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Verify that a campaign exists.
|
|
269
|
+
*
|
|
270
|
+
* @throws {CampaignNotFoundError} if no campaign exists with the given ID.
|
|
271
|
+
*/
|
|
272
|
+
verifyCampaignExists(campaignId) {
|
|
273
|
+
const row = this.stmtGetCampaign.get(campaignId);
|
|
274
|
+
if (!row)
|
|
275
|
+
throw new CampaignNotFoundError(campaignId);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=campaign-statistics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"campaign-statistics.js","sourceRoot":"","sources":["../../../src/db/repositories/campaign-statistics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"campaign-statistics.test.d.ts","sourceRoot":"","sources":["../../../src/db/repositories/campaign-statistics.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
4
|
+
import { DatabaseClient } from "../client.js";
|
|
5
|
+
import { ActionNotFoundError, CampaignNotFoundError, } from "../errors.js";
|
|
6
|
+
import { openFixture } from "../testing/open-fixture.js";
|
|
7
|
+
import { CampaignStatisticsRepository } from "./campaign-statistics.js";
|
|
8
|
+
describe("CampaignStatisticsRepository", () => {
|
|
9
|
+
let db;
|
|
10
|
+
let client;
|
|
11
|
+
let repo;
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
db = openFixture();
|
|
14
|
+
client = { db };
|
|
15
|
+
repo = new CampaignStatisticsRepository(client);
|
|
16
|
+
});
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
db.close();
|
|
19
|
+
});
|
|
20
|
+
describe("getStatistics", () => {
|
|
21
|
+
// Campaign 1 fixture data:
|
|
22
|
+
// Action 1 ("Send Welcome Message", MessageToPerson) with 4 results:
|
|
23
|
+
// person 1: result=1 (successful)
|
|
24
|
+
// person 3: result=2 (replied)
|
|
25
|
+
// person 2: result=-1 (failed)
|
|
26
|
+
// person 4: result=-2 (skipped)
|
|
27
|
+
// Error flags (code != NULL):
|
|
28
|
+
// code=100, is_exception=0, who_to_blame='LinkedIn' (x2)
|
|
29
|
+
// code=200, is_exception=1, who_to_blame='LH' (x1)
|
|
30
|
+
it("returns per-action breakdown for a campaign", () => {
|
|
31
|
+
const stats = repo.getStatistics(1);
|
|
32
|
+
expect(stats.campaignId).toBe(1);
|
|
33
|
+
expect(stats.actions).toHaveLength(1);
|
|
34
|
+
const action = stats.actions.at(0);
|
|
35
|
+
expect(action).toBeDefined();
|
|
36
|
+
expect(action).toMatchObject({
|
|
37
|
+
actionId: 1,
|
|
38
|
+
actionName: "Send Welcome Message",
|
|
39
|
+
actionType: "MessageToPerson",
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
it("counts successful/replied/failed/skipped correctly", () => {
|
|
43
|
+
const stats = repo.getStatistics(1);
|
|
44
|
+
const action = stats.actions.at(0);
|
|
45
|
+
expect(action).toBeDefined();
|
|
46
|
+
expect(action?.successful).toBe(1);
|
|
47
|
+
expect(action?.replied).toBe(1);
|
|
48
|
+
expect(action?.failed).toBe(1);
|
|
49
|
+
expect(action?.skipped).toBe(1);
|
|
50
|
+
expect(action?.total).toBe(4);
|
|
51
|
+
});
|
|
52
|
+
it("calculates success rate correctly", () => {
|
|
53
|
+
const stats = repo.getStatistics(1);
|
|
54
|
+
const action = stats.actions.at(0);
|
|
55
|
+
expect(action).toBeDefined();
|
|
56
|
+
// successRate = round(((successful + replied) / total) * 1000) / 10
|
|
57
|
+
// = round(((1 + 1) / 4) * 1000) / 10 = round(500) / 10 = 50
|
|
58
|
+
expect(action?.successRate).toBe(50);
|
|
59
|
+
});
|
|
60
|
+
it("returns top errors with blame attribution", () => {
|
|
61
|
+
const stats = repo.getStatistics(1);
|
|
62
|
+
const action = stats.actions.at(0);
|
|
63
|
+
expect(action).toBeDefined();
|
|
64
|
+
const errors = action?.topErrors ?? [];
|
|
65
|
+
expect(errors).toHaveLength(2);
|
|
66
|
+
expect(errors.at(0)).toMatchObject({
|
|
67
|
+
code: 100,
|
|
68
|
+
count: 2,
|
|
69
|
+
isException: false,
|
|
70
|
+
whoToBlame: "LinkedIn",
|
|
71
|
+
});
|
|
72
|
+
expect(errors.at(1)).toMatchObject({
|
|
73
|
+
code: 200,
|
|
74
|
+
count: 1,
|
|
75
|
+
isException: true,
|
|
76
|
+
whoToBlame: "LH",
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
it("orders top errors by count descending", () => {
|
|
80
|
+
const stats = repo.getStatistics(1);
|
|
81
|
+
const action = stats.actions.at(0);
|
|
82
|
+
expect(action).toBeDefined();
|
|
83
|
+
const errors = action?.topErrors ?? [];
|
|
84
|
+
for (let i = 1; i < errors.length; i++) {
|
|
85
|
+
expect(errors[i - 1]?.count).toBeGreaterThanOrEqual(errors[i]?.count ?? 0);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
it("respects maxErrors option", () => {
|
|
89
|
+
const stats = repo.getStatistics(1, { maxErrors: 1 });
|
|
90
|
+
const action = stats.actions.at(0);
|
|
91
|
+
expect(action).toBeDefined();
|
|
92
|
+
const errors = action?.topErrors ?? [];
|
|
93
|
+
expect(errors).toHaveLength(1);
|
|
94
|
+
expect(errors.at(0)?.code).toBe(100);
|
|
95
|
+
});
|
|
96
|
+
it("filters by actionId when provided", () => {
|
|
97
|
+
const stats = repo.getStatistics(1, { actionId: 1 });
|
|
98
|
+
expect(stats.actions).toHaveLength(1);
|
|
99
|
+
expect(stats.actions.at(0)?.actionId).toBe(1);
|
|
100
|
+
});
|
|
101
|
+
it("throws CampaignNotFoundError for missing campaign", () => {
|
|
102
|
+
expect(() => repo.getStatistics(999)).toThrow(CampaignNotFoundError);
|
|
103
|
+
});
|
|
104
|
+
it("throws ActionNotFoundError for invalid actionId", () => {
|
|
105
|
+
expect(() => repo.getStatistics(1, { actionId: 999 })).toThrow(ActionNotFoundError);
|
|
106
|
+
});
|
|
107
|
+
it("handles campaign with no results", () => {
|
|
108
|
+
// Campaign 3 has no actions (archived)
|
|
109
|
+
const stats = repo.getStatistics(3);
|
|
110
|
+
expect(stats.campaignId).toBe(3);
|
|
111
|
+
expect(stats.actions).toHaveLength(0);
|
|
112
|
+
expect(stats.totals).toMatchObject({
|
|
113
|
+
successful: 0,
|
|
114
|
+
replied: 0,
|
|
115
|
+
failed: 0,
|
|
116
|
+
skipped: 0,
|
|
117
|
+
total: 0,
|
|
118
|
+
successRate: 0,
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
it("aggregates totals across all actions", () => {
|
|
122
|
+
const stats = repo.getStatistics(1);
|
|
123
|
+
expect(stats.totals).toMatchObject({
|
|
124
|
+
successful: 1,
|
|
125
|
+
replied: 1,
|
|
126
|
+
failed: 1,
|
|
127
|
+
skipped: 1,
|
|
128
|
+
total: 4,
|
|
129
|
+
successRate: 50,
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
it("includes first and last result timestamps", () => {
|
|
133
|
+
const stats = repo.getStatistics(1);
|
|
134
|
+
const action = stats.actions.at(0);
|
|
135
|
+
expect(action).toBeDefined();
|
|
136
|
+
expect(action?.firstResultAt).toBe("2025-01-15T12:30:00.000Z");
|
|
137
|
+
expect(action?.lastResultAt).toBe("2025-01-15T14:00:00.000Z");
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
describe("resetForRerun", () => {
|
|
141
|
+
it("resets person state for re-run", () => {
|
|
142
|
+
// Initial state: person 1 has state=2 (processed), person 3 has state=1 (queued)
|
|
143
|
+
const initialTargets = db
|
|
144
|
+
.prepare("SELECT person_id, state FROM action_target_people WHERE action_id = 1")
|
|
145
|
+
.all();
|
|
146
|
+
const initialPerson1 = initialTargets.find((t) => t.person_id === 1);
|
|
147
|
+
expect(initialPerson1).toBeDefined();
|
|
148
|
+
expect(initialPerson1?.state).toBe(2);
|
|
149
|
+
// Reset person 1
|
|
150
|
+
repo.resetForRerun(1, [1]);
|
|
151
|
+
// Verify state reset to 1 (queued)
|
|
152
|
+
const afterTargets = db
|
|
153
|
+
.prepare("SELECT person_id, state FROM action_target_people WHERE action_id = 1")
|
|
154
|
+
.all();
|
|
155
|
+
const afterPerson1 = afterTargets.find((t) => t.person_id === 1);
|
|
156
|
+
expect(afterPerson1).toBeDefined();
|
|
157
|
+
expect(afterPerson1?.state).toBe(1);
|
|
158
|
+
});
|
|
159
|
+
it("resets campaign history for re-run", () => {
|
|
160
|
+
// Initial state: person 1 has result_status=1 (success)
|
|
161
|
+
const initialHistory = db
|
|
162
|
+
.prepare("SELECT result_status FROM person_in_campaigns_history WHERE campaign_id = 1 AND person_id = 1")
|
|
163
|
+
.get();
|
|
164
|
+
expect(initialHistory).toBeDefined();
|
|
165
|
+
expect(initialHistory?.result_status).toBe(1);
|
|
166
|
+
// Reset person 1
|
|
167
|
+
repo.resetForRerun(1, [1]);
|
|
168
|
+
// Verify result_status reset to -999
|
|
169
|
+
const afterHistory = db
|
|
170
|
+
.prepare("SELECT result_status FROM person_in_campaigns_history WHERE campaign_id = 1 AND person_id = 1")
|
|
171
|
+
.get();
|
|
172
|
+
expect(afterHistory).toBeDefined();
|
|
173
|
+
expect(afterHistory?.result_status).toBe(-999);
|
|
174
|
+
});
|
|
175
|
+
it("deletes old action results and related records", () => {
|
|
176
|
+
// Verify initial state has results
|
|
177
|
+
const initialResults = db
|
|
178
|
+
.prepare("SELECT id FROM action_results WHERE action_version_id = 1 AND person_id = 1")
|
|
179
|
+
.all();
|
|
180
|
+
expect(initialResults).toHaveLength(1);
|
|
181
|
+
const initialFlags = db
|
|
182
|
+
.prepare("SELECT id FROM action_result_flags WHERE action_result_id = 1")
|
|
183
|
+
.all();
|
|
184
|
+
expect(initialFlags).toHaveLength(1);
|
|
185
|
+
const initialMessages = db
|
|
186
|
+
.prepare("SELECT id FROM action_result_messages WHERE action_result_id = 1")
|
|
187
|
+
.all();
|
|
188
|
+
expect(initialMessages).toHaveLength(1);
|
|
189
|
+
// Reset person 1
|
|
190
|
+
repo.resetForRerun(1, [1]);
|
|
191
|
+
// Verify all deleted
|
|
192
|
+
const afterResults = db
|
|
193
|
+
.prepare("SELECT id FROM action_results WHERE action_version_id = 1 AND person_id = 1")
|
|
194
|
+
.all();
|
|
195
|
+
expect(afterResults).toHaveLength(0);
|
|
196
|
+
const afterFlags = db
|
|
197
|
+
.prepare("SELECT id FROM action_result_flags WHERE action_result_id = 1")
|
|
198
|
+
.all();
|
|
199
|
+
expect(afterFlags).toHaveLength(0);
|
|
200
|
+
const afterMessages = db
|
|
201
|
+
.prepare("SELECT id FROM action_result_messages WHERE action_result_id = 1")
|
|
202
|
+
.all();
|
|
203
|
+
expect(afterMessages).toHaveLength(0);
|
|
204
|
+
});
|
|
205
|
+
it("handles multiple persons in a single reset", () => {
|
|
206
|
+
repo.resetForRerun(1, [1, 3]);
|
|
207
|
+
// Both persons should have state=1
|
|
208
|
+
const targets = db
|
|
209
|
+
.prepare("SELECT person_id, state FROM action_target_people WHERE action_id = 1")
|
|
210
|
+
.all();
|
|
211
|
+
const stateByPerson = new Map(targets.map((t) => [t.person_id, t.state]));
|
|
212
|
+
expect(stateByPerson.get(1)).toBe(1);
|
|
213
|
+
expect(stateByPerson.get(3)).toBe(1);
|
|
214
|
+
});
|
|
215
|
+
it("handles empty person list gracefully", () => {
|
|
216
|
+
// Should not throw
|
|
217
|
+
expect(() => repo.resetForRerun(1, [])).not.toThrow();
|
|
218
|
+
});
|
|
219
|
+
it("throws CampaignNotFoundError for missing campaign", () => {
|
|
220
|
+
expect(() => repo.resetForRerun(999, [1])).toThrow(CampaignNotFoundError);
|
|
221
|
+
});
|
|
222
|
+
it("handles campaign with no actions gracefully", () => {
|
|
223
|
+
// Campaign 3 has no actions
|
|
224
|
+
expect(() => repo.resetForRerun(3, [1])).not.toThrow();
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
describe("resetForRerun — rollback", () => {
|
|
228
|
+
it("rolls back transaction on error and preserves database state", () => {
|
|
229
|
+
// Snapshot initial state
|
|
230
|
+
const initialTargets = db
|
|
231
|
+
.prepare("SELECT person_id, state FROM action_target_people WHERE action_id = 1 ORDER BY person_id")
|
|
232
|
+
.all();
|
|
233
|
+
const initialHistory = db
|
|
234
|
+
.prepare("SELECT person_id, result_status FROM person_in_campaigns_history WHERE campaign_id = 1 ORDER BY person_id")
|
|
235
|
+
.all();
|
|
236
|
+
const initialResults = db
|
|
237
|
+
.prepare("SELECT id FROM action_results WHERE action_version_id = 1 ORDER BY id")
|
|
238
|
+
.all();
|
|
239
|
+
// Sabotage a write statement to force an error mid-transaction
|
|
240
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- private method access for rollback test
|
|
241
|
+
const stmts = repo.getWriteStatements();
|
|
242
|
+
const originalRun = stmts.resetHistory.run.bind(stmts.resetHistory);
|
|
243
|
+
stmts.resetHistory.run = () => {
|
|
244
|
+
throw new Error("Simulated DB error");
|
|
245
|
+
};
|
|
246
|
+
// Attempt reset — should throw the simulated error
|
|
247
|
+
expect(() => repo.resetForRerun(1, [1])).toThrow("Simulated DB error");
|
|
248
|
+
// Restore original to avoid side effects
|
|
249
|
+
stmts.resetHistory.run = originalRun;
|
|
250
|
+
// Verify database state is unchanged (ROLLBACK worked)
|
|
251
|
+
const afterTargets = db
|
|
252
|
+
.prepare("SELECT person_id, state FROM action_target_people WHERE action_id = 1 ORDER BY person_id")
|
|
253
|
+
.all();
|
|
254
|
+
const afterHistory = db
|
|
255
|
+
.prepare("SELECT person_id, result_status FROM person_in_campaigns_history WHERE campaign_id = 1 ORDER BY person_id")
|
|
256
|
+
.all();
|
|
257
|
+
const afterResults = db
|
|
258
|
+
.prepare("SELECT id FROM action_results WHERE action_version_id = 1 ORDER BY id")
|
|
259
|
+
.all();
|
|
260
|
+
expect(afterTargets).toEqual(initialTargets);
|
|
261
|
+
expect(afterHistory).toEqual(initialHistory);
|
|
262
|
+
expect(afterResults).toEqual(initialResults);
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
//# sourceMappingURL=campaign-statistics.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"campaign-statistics.test.js","sourceRoot":"","sources":["../../../src/db/repositories/campaign-statistics.test.ts"],"names":[],"mappings":"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"}
|