- Schema III: per-user notifications (broadcast fan-out migration, category, link, requiredPermissions filter), notification preferences and settings endpoints, calendar withdrawal switch, occupiedFrames - Suggestions API: list/summary with permission visibility and paging, accept/dismiss/reopen incl. bulk, SuggestionView on all responses - Varroa traffic light by season and method, young colonies, treatment effect window, sample-based percentage; shared withdrawal-window helper on Berlin calendar days; GET /varroa-measurements/thresholds - ColonySplit and QueenAssigned domain events with calendar and webhook handlers - Outbox claims compare against now() rounded to timestamp(3); fixes the flaky e2e claims of rows written with SQL now() Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
12 KiB
12 KiB
FAIL test/webhooks.e2e-spec.ts
● Test suite failed to run
Cannot find module './varroa-threshold.service' from '../src/varroa/varroa.controller.ts'
Require stack:
C:/Users/Nick.Szaunig/OneDrive - EnCry/Documents/VS Code/ApiCore/ApiCore-Backend/src/varroa/varroa.controller.ts
C:/Users/Nick.Szaunig/OneDrive - EnCry/Documents/VS Code/ApiCore/ApiCore-Backend/src/varroa/varroa.module.ts
C:/Users/Nick.Szaunig/OneDrive - EnCry/Documents/VS Code/ApiCore/ApiCore-Backend/src/app.module.ts
utils/create-test-app.ts
webhooks.e2e-spec.ts
8 | import { UpdateVarroaMeasurementDto } from './dto/update-varroa-measurement.dto';
9 | import { VarroaService } from './varroa.service';
> 10 | import { VarroaThresholdService } from './varroa-threshold.service';
| ^
11 | import { Idempotent } from '../common/idempotency/idempotent.decorator';
12 |
13 | @ApiTags('varroa-measurements')
at Resolver._throwModNotFoundError (../node_modules/jest-resolve/build/index.js:895:11)
at Object.<anonymous> (../src/varroa/varroa.controller.ts:10:1)
at Object.<anonymous> (../src/varroa/varroa.module.ts:2:1)
at Object.<anonymous> (../src/app.module.ts:20:1)
at Object.<anonymous> (utils/create-test-app.ts:6:1)
at Object.<anonymous> (webhooks.e2e-spec.ts:9:1)
[Nest] 17844 - 14/10/2026, 13:53:09 ERROR [DomainEventDispatcher] Domain events FAILED, an expired claim used up their attempts: cmv81wj4d001xroijcqgc9y09
FAIL test/domain-event-dispatcher.e2e-spec.ts
● Console
console.log
◇ injected env (8) from .env.test // tip: ⌁ auth for agents [www.vestauth.com]
at _log (../node_modules/dotenv/lib/main.js:131:11)
● DomainEventDispatcher (e2e) › two dispatchers in parallel produce exactly one effect per event and handler
TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
109 | const d = await db.$queryRaw<unknown[]>(Prisma.sql`SELECT "id","status","availableAt", now() AS n, clock_timestamp() AS c, ("availableAt" <= now()) AS due, pg_backend_pid() AS pid FROM ${name} WHERE ${options.filter}`);
110 | // eslint-disable-next-line
> 111 | require('node:fs').appendFileSync(process.env.DBG_LOG as string, new Date().toISOString() + ' ' + table + ' empty claim; rows=' + JSON.stringify(d) + '\n');
| ^
112 | }
113 | return __res;
114 | }
at claimBatch (../src/common/outbox/outbox-claims.ts:111:24)
at DomainEventDispatcher.runOnce (../src/domain-events/domain-event-dispatcher.ts:69:20)
at DomainEventDispatcher.drain (../src/domain-events/domain-event-dispatcher.ts:101:23)
at async Promise.all (index 1)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:211:20)
● DomainEventDispatcher (e2e) › hands the handler the stored event and its correlation id
TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
109 | const d = await db.$queryRaw<unknown[]>(Prisma.sql`SELECT "id","status","availableAt", now() AS n, clock_timestamp() AS c, ("availableAt" <= now()) AS due, pg_backend_pid() AS pid FROM ${name} WHERE ${options.filter}`);
110 | // eslint-disable-next-line
> 111 | require('node:fs').appendFileSync(process.env.DBG_LOG as string, new Date().toISOString() + ' ' + table + ' empty claim; rows=' + JSON.stringify(d) + '\n');
| ^
112 | }
113 | return __res;
114 | }
at claimBatch (../src/common/outbox/outbox-claims.ts:111:24)
at DomainEventDispatcher.runOnce (../src/domain-events/domain-event-dispatcher.ts:69:20)
at DomainEventDispatcher.drain (../src/domain-events/domain-event-dispatcher.ts:101:23)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:245:5)
● DomainEventDispatcher (e2e) › a stale release that ends in FAILED also fails the open deliveries
expect(received).resolves.toBe()
Received promise rejected instead of resolved
Rejected to value: [TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined]
320 | deliveries: [{ handler: 'test.counter', status: 'FAILED', attempts: 7 }],
321 | });
> 322 | await expect(appA.get(DomainEventDispatcher).drain(filter)).resolves.toBe(
| ^
323 | 0,
324 | );
325 | });
at expect (../node_modules/expect/build/index.js:2116:15)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:322:11)
● DomainEventDispatcher (e2e) › drains a backlog of 120 events in batches of at most 50
TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
109 | const d = await db.$queryRaw<unknown[]>(Prisma.sql`SELECT "id","status","availableAt", now() AS n, clock_timestamp() AS c, ("availableAt" <= now()) AS due, pg_backend_pid() AS pid FROM ${name} WHERE ${options.filter}`);
110 | // eslint-disable-next-line
> 111 | require('node:fs').appendFileSync(process.env.DBG_LOG as string, new Date().toISOString() + ' ' + table + ' empty claim; rows=' + JSON.stringify(d) + '\n');
| ^
112 | }
113 | return __res;
114 | }
at claimBatch (../src/common/outbox/outbox-claims.ts:111:24)
at DomainEventDispatcher.runOnce (../src/domain-events/domain-event-dispatcher.ts:69:20)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:333:19)
● DomainEventDispatcher (e2e) › drainDomainEvents processes only the events of the given root aggregates
TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
109 | const d = await db.$queryRaw<unknown[]>(Prisma.sql`SELECT "id","status","availableAt", now() AS n, clock_timestamp() AS c, ("availableAt" <= now()) AS due, pg_backend_pid() AS pid FROM ${name} WHERE ${options.filter}`);
110 | // eslint-disable-next-line
> 111 | require('node:fs').appendFileSync(process.env.DBG_LOG as string, new Date().toISOString() + ' ' + table + ' empty claim; rows=' + JSON.stringify(d) + '\n');
| ^
112 | }
113 | return __res;
114 | }
at claimBatch (../src/common/outbox/outbox-claims.ts:111:24)
at DomainEventDispatcher.runOnce (../src/domain-events/domain-event-dispatcher.ts:69:20)
at DomainEventDispatcher.drain (../src/domain-events/domain-event-dispatcher.ts:101:23)
at drainDomainEvents (utils/domain-events.ts:24:3)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:344:5)
● DomainEventDispatcher (e2e) › a stale-released event does not repeat a handler that already committed
TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
109 | const d = await db.$queryRaw<unknown[]>(Prisma.sql`SELECT "id","status","availableAt", now() AS n, clock_timestamp() AS c, ("availableAt" <= now()) AS due, pg_backend_pid() AS pid FROM ${name} WHERE ${options.filter}`);
110 | // eslint-disable-next-line
> 111 | require('node:fs').appendFileSync(process.env.DBG_LOG as string, new Date().toISOString() + ' ' + table + ' empty claim; rows=' + JSON.stringify(d) + '\n');
| ^
112 | }
113 | return __res;
114 | }
at claimBatch (../src/common/outbox/outbox-claims.ts:111:24)
at DomainEventDispatcher.runOnce (../src/domain-events/domain-event-dispatcher.ts:69:20)
at DomainEventDispatcher.drain (../src/domain-events/domain-event-dispatcher.ts:101:23)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:391:5)
● DomainEventDispatcher (e2e) › schedules a failed event about 30 s ahead by the database clock
expect(received).resolves.toBe()
Received promise rejected instead of resolved
Rejected to value: [TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined]
508 | const filter = await filterFor('failing');
509 |
> 510 | await expect(appA.get(DomainEventDispatcher).drain(filter)).resolves.toBe(
| ^
511 | 1,
512 | );
513 |
at expect (../node_modules/expect/build/index.js:2116:15)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:510:11)
Test Suites: 2 failed, 2 total
Tests: 7 failed, 2 passed, 9 total
Snapshots: 0 total
Time: 3.973 s, estimated 7 s
Ran all test suites matching test/webhooks.e2e-spec.ts|test/domain-event-dispatcher.e2e-spec.ts.
Jest did not exit one second after the test run has completed.
'This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.
● Test suite failed to run
Cannot find module './varroa-threshold.service' from '../src/varroa/varroa.controller.ts'
Require stack:
C:/Users/Nick.Szaunig/OneDrive - EnCry/Documents/VS Code/ApiCore/ApiCore-Backend/src/varroa/varroa.controller.ts
C:/Users/Nick.Szaunig/OneDrive - EnCry/Documents/VS Code/ApiCore/ApiCore-Backend/src/varroa/varroa.module.ts
C:/Users/Nick.Szaunig/OneDrive - EnCry/Documents/VS Code/ApiCore/ApiCore-Backend/src/app.module.ts
utils/create-test-app.ts
webhooks.e2e-spec.ts
8 | import { UpdateVarroaMeasurementDto } from './dto/update-varroa-measurement.dto';
9 | import { VarroaService } from './varroa.service';
> 10 | import { VarroaThresholdService } from './varroa-threshold.service';
| ^
11 | import { Idempotent } from '../common/idempotency/idempotent.decorator';
12 |
13 | @ApiTags('varroa-measurements')
at Resolver._throwModNotFoundError (../node_modules/jest-resolve/build/index.js:895:11)
at Object.<anonymous> (../src/varroa/varroa.controller.ts:10:1)
at Object.<anonymous> (../src/varroa/varroa.module.ts:2:1)
at Object.<anonymous> (../src/app.module.ts:20:1)
at Object.<anonymous> (utils/create-test-app.ts:6:1)
at Object.<anonymous> (webhooks.e2e-spec.ts:9:1)
[Nest] 17844 - 14/10/2026, 13:53:09 ERROR [DomainEventDispatcher] Domain events FAILED, an expired claim used up their attempts: cmv81wj4d001xroijcqgc9y09
FAIL test/domain-event-dispatcher.e2e-spec.ts
● Console
console.log
◇ injected env (8) from .env.test // tip: ⌁ auth for agents [www.vestauth.com]
at _log (../node_modules/dotenv/lib/main.js:131:11)
● DomainEventDispatcher (e2e) › two dispatchers in parallel produce exactly one effect per event and handler
TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
109 | const d = await db.$queryRaw<unknown[]>(Prisma.sql`SELECT "id","status","availableAt", now() AS n, clock_timestamp() AS c, ("availableAt" <= now()) AS due, pg_backend_pid() AS pid FROM ${name} WHERE ${options.filter}`);
110 | // eslint-disable-next-line
> 111 | require('node:fs').appendFileSync(process.env.DBG_LOG as string, new Date().toISOString() + ' ' + table + ' empty claim; rows=' + JSON.stringify(d) + '\n');
| ^
112 | }
113 | return __res;
114 | }
at claimBatch (../src/common/outbox/outbox-claims.ts:111:24)
at DomainEventDispatcher.runOnce (../src/domain-events/domain-event-dispatcher.ts:69:20)
at DomainEventDispatcher.drain (../src/domain-events/domain-event-dispatcher.ts:101:23)
at async Promise.all (index 1)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:211:20)
● DomainEventDispatcher (e2e) › hands the handler the stored event and its correlation id
TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
109 | const d = await db.$queryRaw<unknown[]>(Prisma.sql`SELECT "id","status","availableAt", now() AS n, clock_timestamp() AS c, ("availableAt" <= now()) AS due, pg_backend_pid() AS pid FROM ${name} WHERE ${options.filter}`);
110 | // eslint-disable-next-line
> 111 | require('node:fs').appendFileSync(process.env.DBG_LOG as string, new Date().toISOString() + ' ' + table + ' empty claim; rows=' + JSON.stringify(d) + '\n');
| ^
112 | }
113 | return __res;
114 | }
at claimBatch (../src/common/outbox/outbox-claims.ts:111:24)
at DomainEventDispatcher.runOnce (../src/domain-events/domain-event-dispatcher.ts:69:20)
at DomainEventDispatcher.drain (../src/domain-events/domain-event-dispatcher.ts:101:23)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:245:5)
● DomainEventDispatcher (e2e) › a stale release that ends in FAILED also fails the open deliveries
expect(received).resolves.toBe()
Received promise rejected instead of resolved
Rejected to value: [TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined]
320 | deliveries: [{ handler: 'test.counter', status: 'FAILED', attempts: 7 }],
321 | });
> 322 | await expect(appA.get(DomainEventDispatcher).drain(filter)).resolves.toBe(
| ^
323 | 0,
324 | );
325 | });
at expect (../node_modules/expect/build/index.js:2116:15)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:322:11)
● DomainEventDispatcher (e2e) › drains a backlog of 120 events in batches of at most 50
TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
109 | const d = await db.$queryRaw<unknown[]>(Prisma.sql`SELECT "id","status","availableAt", now() AS n, clock_timestamp() AS c, ("availableAt" <= now()) AS due, pg_backend_pid() AS pid FROM ${name} WHERE ${options.filter}`);
110 | // eslint-disable-next-line
> 111 | require('node:fs').appendFileSync(process.env.DBG_LOG as string, new Date().toISOString() + ' ' + table + ' empty claim; rows=' + JSON.stringify(d) + '\n');
| ^
112 | }
113 | return __res;
114 | }
at claimBatch (../src/common/outbox/outbox-claims.ts:111:24)
at DomainEventDispatcher.runOnce (../src/domain-events/domain-event-dispatcher.ts:69:20)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:333:19)
● DomainEventDispatcher (e2e) › drainDomainEvents processes only the events of the given root aggregates
TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
109 | const d = await db.$queryRaw<unknown[]>(Prisma.sql`SELECT "id","status","availableAt", now() AS n, clock_timestamp() AS c, ("availableAt" <= now()) AS due, pg_backend_pid() AS pid FROM ${name} WHERE ${options.filter}`);
110 | // eslint-disable-next-line
> 111 | require('node:fs').appendFileSync(process.env.DBG_LOG as string, new Date().toISOString() + ' ' + table + ' empty claim; rows=' + JSON.stringify(d) + '\n');
| ^
112 | }
113 | return __res;
114 | }
at claimBatch (../src/common/outbox/outbox-claims.ts:111:24)
at DomainEventDispatcher.runOnce (../src/domain-events/domain-event-dispatcher.ts:69:20)
at DomainEventDispatcher.drain (../src/domain-events/domain-event-dispatcher.ts:101:23)
at drainDomainEvents (utils/domain-events.ts:24:3)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:344:5)
● DomainEventDispatcher (e2e) › a stale-released event does not repeat a handler that already committed
TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
109 | const d = await db.$queryRaw<unknown[]>(Prisma.sql`SELECT "id","status","availableAt", now() AS n, clock_timestamp() AS c, ("availableAt" <= now()) AS due, pg_backend_pid() AS pid FROM ${name} WHERE ${options.filter}`);
110 | // eslint-disable-next-line
> 111 | require('node:fs').appendFileSync(process.env.DBG_LOG as string, new Date().toISOString() + ' ' + table + ' empty claim; rows=' + JSON.stringify(d) + '\n');
| ^
112 | }
113 | return __res;
114 | }
at claimBatch (../src/common/outbox/outbox-claims.ts:111:24)
at DomainEventDispatcher.runOnce (../src/domain-events/domain-event-dispatcher.ts:69:20)
at DomainEventDispatcher.drain (../src/domain-events/domain-event-dispatcher.ts:101:23)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:391:5)
● DomainEventDispatcher (e2e) › schedules a failed event about 30 s ahead by the database clock
expect(received).resolves.toBe()
Received promise rejected instead of resolved
Rejected to value: [TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined]
508 | const filter = await filterFor('failing');
509 |
> 510 | await expect(appA.get(DomainEventDispatcher).drain(filter)).resolves.toBe(
| ^
511 | 1,
512 | );
513 |
at expect (../node_modules/expect/build/index.js:2116:15)
at Object.<anonymous> (domain-event-dispatcher.e2e-spec.ts:510:11)
Test Suites: 2 failed, 2 total
Tests: 7 failed, 2 passed, 9 total
Snapshots: 0 total
Time: 3.973 s, estimated 7 s
Ran all test suites matching test/webhooks.e2e-spec.ts|test/domain-event-dispatcher.e2e-spec.ts.
Jest did not exit one second after the test run has completed.
'This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.