diff --git a/api/server/services/Schedules/index.js b/api/server/services/Schedules/index.js index f327445991..69f92a3444 100644 --- a/api/server/services/Schedules/index.js +++ b/api/server/services/Schedules/index.js @@ -17,6 +17,9 @@ const service = createSchedulesService({ { upsert: true, new: true }, ).lean(), resolveAgentFireAccess, + // Durable account-deletion barrier consulted at the fire dispatch boundary. Without + // this, engineDeps.isOwnerDeleting would throw on every scheduled fire. + isUserDeleting: methods.isUserDeleting, }); module.exports = { diff --git a/packages/api/src/schedules/service.ts b/packages/api/src/schedules/service.ts index 0be5ec5efc..24e9120f8f 100644 --- a/packages/api/src/schedules/service.ts +++ b/packages/api/src/schedules/service.ts @@ -176,6 +176,25 @@ export interface SchedulesService { export function createSchedulesService(deps: SchedulesServiceDeps): SchedulesService { const { methods } = deps; + // Fail LOUDLY at construction, not per-fire. The JS adapter (api/server/services/ + // Schedules) is not typechecked against SchedulesServiceDeps, so a missing dep would + // otherwise surface only as a `deps.X is not a function` deep inside a live fire — + // which is exactly how the deletion-barrier probe shipped unwired twice. + const REQUIRED_DEPS: Array = [ + 'methods', + 'getAppConfig', + 'findUserById', + 'findBalance', + 'upsertBalance', + 'resolveAgentFireAccess', + 'isUserDeleting', + ]; + for (const key of REQUIRED_DEPS) { + if (deps[key] == null) { + throw new Error(`createSchedulesService: missing required dependency "${key}"`); + } + } + /** * Resolves schedule limits, honoring per-principal (role/user) config overrides * when a user is supplied (routes pass req.user, the fire path passes the owner).