@neohm/nestend 3.0.5 → 3.1.0
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 +160 -36
- package/dist/admin/admin.module.d.ts.map +1 -1
- package/dist/admin/admin.module.js +0 -1
- package/dist/admin/admin.module.js.map +1 -1
- package/dist/admin/controllers/admin.scheduled.task.controller.d.ts +1 -1
- package/dist/admin/controllers/admin.scheduled.task.controller.d.ts.map +1 -1
- package/dist/admin/controllers/admin.scheduled.task.controller.js +4 -4
- package/dist/admin/controllers/admin.scheduled.task.controller.js.map +1 -1
- package/dist/admin/controllers/admin.tenant.controller.d.ts.map +1 -1
- package/dist/admin/controllers/admin.tenant.controller.js +2 -2
- package/dist/admin/controllers/admin.tenant.controller.js.map +1 -1
- package/dist/admin/dtos/add.admin.user.dto.d.ts +2 -1
- package/dist/admin/dtos/add.admin.user.dto.d.ts.map +1 -1
- package/dist/admin/dtos/add.admin.user.dto.js +2 -1
- package/dist/admin/dtos/add.admin.user.dto.js.map +1 -1
- package/dist/admin/dtos/add.scheduled.task.dto.d.ts +14 -3
- package/dist/admin/dtos/add.scheduled.task.dto.d.ts.map +1 -1
- package/dist/admin/dtos/add.scheduled.task.dto.js +109 -14
- package/dist/admin/dtos/add.scheduled.task.dto.js.map +1 -1
- package/dist/admin/dtos/add.tenant.dto.d.ts +2 -1
- package/dist/admin/dtos/add.tenant.dto.d.ts.map +1 -1
- package/dist/admin/dtos/add.tenant.dto.js +4 -1
- package/dist/admin/dtos/add.tenant.dto.js.map +1 -1
- package/dist/admin/dtos/base.user.dto.d.ts +2 -1
- package/dist/admin/dtos/base.user.dto.d.ts.map +1 -1
- package/dist/admin/dtos/base.user.dto.js +2 -1
- package/dist/admin/dtos/base.user.dto.js.map +1 -1
- package/dist/admin/es6.classes.d.ts +2 -2
- package/dist/admin/es6.classes.d.ts.map +1 -1
- package/dist/admin/es6.classes.js +1 -1
- package/dist/admin/es6.classes.js.map +1 -1
- package/dist/admin/libraries/scheduled.task.data.processor.d.ts +6 -1
- package/dist/admin/libraries/scheduled.task.data.processor.d.ts.map +1 -1
- package/dist/admin/libraries/scheduled.task.data.processor.js +98 -20
- package/dist/admin/libraries/scheduled.task.data.processor.js.map +1 -1
- package/dist/admin/libraries/scheduled.task.list.processor.d.ts.map +1 -1
- package/dist/admin/libraries/scheduled.task.list.processor.js +3 -0
- package/dist/admin/libraries/scheduled.task.list.processor.js.map +1 -1
- package/dist/admin/libraries/tenant.data.processor.d.ts +1 -1
- package/dist/admin/libraries/tenant.data.processor.d.ts.map +1 -1
- package/dist/admin/libraries/tenant.data.processor.js +36 -24
- package/dist/admin/libraries/tenant.data.processor.js.map +1 -1
- package/dist/admin/libraries/tenant.list.processor.d.ts.map +1 -1
- package/dist/admin/libraries/tenant.list.processor.js +1 -0
- package/dist/admin/libraries/tenant.list.processor.js.map +1 -1
- package/dist/auth/auth.module.d.ts.map +1 -1
- package/dist/auth/auth.module.js +4 -1
- package/dist/auth/auth.module.js.map +1 -1
- package/dist/auth/entities/admin.user.entity.d.ts.map +1 -1
- package/dist/auth/entities/admin.user.entity.js +0 -2
- package/dist/auth/entities/admin.user.entity.js.map +1 -1
- package/dist/auth/entities/api.key.entity.js +1 -1
- package/dist/auth/entities/api.key.entity.js.map +1 -1
- package/dist/auth/entities/scope.entity.d.ts.map +1 -1
- package/dist/auth/entities/scope.entity.js +0 -1
- package/dist/auth/entities/scope.entity.js.map +1 -1
- package/dist/auth/entities/system.auth.session.entity.d.ts.map +1 -1
- package/dist/auth/entities/system.auth.session.entity.js +0 -1
- package/dist/auth/entities/system.auth.session.entity.js.map +1 -1
- package/dist/auth/entities/system.role.entity.d.ts.map +1 -1
- package/dist/auth/entities/system.role.entity.js +0 -1
- package/dist/auth/entities/system.role.entity.js.map +1 -1
- package/dist/auth/entities/user.entity.d.ts.map +1 -1
- package/dist/auth/entities/user.entity.js +0 -1
- package/dist/auth/entities/user.entity.js.map +1 -1
- package/dist/auth/services/admin.auth.service.d.ts.map +1 -1
- package/dist/auth/services/admin.auth.service.js.map +1 -1
- package/dist/auth/services/auth.service.d.ts.map +1 -1
- package/dist/auth/services/auth.service.js.map +1 -1
- package/dist/common/consumers/job.consumer.d.ts.map +1 -1
- package/dist/common/consumers/job.consumer.js +3 -1
- package/dist/common/consumers/job.consumer.js.map +1 -1
- package/dist/common/entities/scheduled.event.entity.d.ts +3 -0
- package/dist/common/entities/scheduled.event.entity.d.ts.map +1 -1
- package/dist/common/entities/scheduled.event.entity.js +9 -0
- package/dist/common/entities/scheduled.event.entity.js.map +1 -1
- package/dist/common/entities/system.constant.type.entity.js +1 -1
- package/dist/common/entities/system.constant.type.entity.js.map +1 -1
- package/dist/common/entities/system.property.entity.js +1 -1
- package/dist/common/entities/system.property.entity.js.map +1 -1
- package/dist/common/entities/system.scheduled.task.entity.d.ts +9 -2
- package/dist/common/entities/system.scheduled.task.entity.d.ts.map +1 -1
- package/dist/common/entities/system.scheduled.task.entity.js +26 -1
- package/dist/common/entities/system.scheduled.task.entity.js.map +1 -1
- package/dist/common/enums/encryption.enum.d.ts.map +1 -1
- package/dist/common/enums/encryption.enum.js.map +1 -1
- package/dist/common/enums/filter.value.type.enum.d.ts.map +1 -1
- package/dist/common/enums/filter.value.type.enum.js.map +1 -1
- package/dist/common/enums/schedule.enum.d.ts +32 -0
- package/dist/common/enums/schedule.enum.d.ts.map +1 -0
- package/dist/common/enums/schedule.enum.js +40 -0
- package/dist/common/enums/schedule.enum.js.map +1 -0
- package/dist/common/es6.classes.d.ts +5 -2
- package/dist/common/es6.classes.d.ts.map +1 -1
- package/dist/common/es6.classes.js +34 -4
- package/dist/common/es6.classes.js.map +1 -1
- package/dist/common/jobs/common.job.d.ts +1 -1
- package/dist/common/jobs/common.job.d.ts.map +1 -1
- package/dist/common/jobs/common.job.js.map +1 -1
- package/dist/common/jobs/dispatch.scheduled.event.job.d.ts +3 -0
- package/dist/common/jobs/dispatch.scheduled.event.job.d.ts.map +1 -1
- package/dist/common/jobs/dispatch.scheduled.event.job.js +40 -11
- package/dist/common/jobs/dispatch.scheduled.event.job.js.map +1 -1
- package/dist/common/jobs/set.scheduled.event.job.d.ts +7 -1
- package/dist/common/jobs/set.scheduled.event.job.d.ts.map +1 -1
- package/dist/common/jobs/set.scheduled.event.job.js +117 -15
- package/dist/common/jobs/set.scheduled.event.job.js.map +1 -1
- package/dist/common/libraries/common.list.processor.js +2 -2
- package/dist/common/libraries/common.list.processor.js.map +1 -1
- package/dist/common/libraries/cron.schedule.resolver.d.ts +8 -0
- package/dist/common/libraries/cron.schedule.resolver.d.ts.map +1 -0
- package/dist/common/libraries/cron.schedule.resolver.js +36 -0
- package/dist/common/libraries/cron.schedule.resolver.js.map +1 -0
- package/dist/common/libraries/filter.operator.registry.d.ts.map +1 -1
- package/dist/common/libraries/filter.operator.registry.js +14 -2
- package/dist/common/libraries/filter.operator.registry.js.map +1 -1
- package/dist/common/libraries/interval.schedule.resolver.d.ts +7 -0
- package/dist/common/libraries/interval.schedule.resolver.d.ts.map +1 -0
- package/dist/common/libraries/interval.schedule.resolver.js +20 -0
- package/dist/common/libraries/interval.schedule.resolver.js.map +1 -0
- package/dist/common/libraries/once.schedule.resolver.d.ts +7 -0
- package/dist/common/libraries/once.schedule.resolver.d.ts.map +1 -0
- package/dist/common/libraries/once.schedule.resolver.js +14 -0
- package/dist/common/libraries/once.schedule.resolver.js.map +1 -0
- package/dist/common/queue.module.d.ts.map +1 -1
- package/dist/common/queue.module.js +3 -1
- package/dist/common/queue.module.js.map +1 -1
- package/dist/common/services/cache.service.js.map +1 -1
- package/dist/common/services/encryption.service.d.ts.map +1 -1
- package/dist/common/services/encryption.service.js +1 -1
- package/dist/common/services/encryption.service.js.map +1 -1
- package/dist/common/services/queue.service.d.ts +7 -5
- package/dist/common/services/queue.service.d.ts.map +1 -1
- package/dist/common/services/queue.service.js +7 -4
- package/dist/common/services/queue.service.js.map +1 -1
- package/dist/common/subscribers/common.subscriber.js +2 -2
- package/dist/common/subscribers/common.subscriber.js.map +1 -1
- package/dist/common/types/cache.types.d.ts +1 -1
- package/dist/common/types/cache.types.d.ts.map +1 -1
- package/dist/common/types/queue.types.d.ts +8 -5
- package/dist/common/types/queue.types.d.ts.map +1 -1
- package/dist/common/types/schedule.types.d.ts +30 -0
- package/dist/common/types/schedule.types.d.ts.map +1 -0
- package/dist/common/types/schedule.types.js +3 -0
- package/dist/common/types/schedule.types.js.map +1 -0
- package/dist/common/validators/schedule.validator.d.ts +4 -0
- package/dist/common/validators/schedule.validator.d.ts.map +1 -0
- package/dist/common/validators/schedule.validator.js +51 -0
- package/dist/common/validators/schedule.validator.js.map +1 -0
- package/dist/constants/schedule.maps.d.ts +6 -0
- package/dist/constants/schedule.maps.d.ts.map +1 -0
- package/dist/constants/schedule.maps.js +30 -0
- package/dist/constants/schedule.maps.js.map +1 -0
- package/dist/document/es6.classes.d.ts.map +1 -1
- package/dist/document/es6.classes.js +5 -1
- package/dist/document/es6.classes.js.map +1 -1
- package/dist/global/utilities/schedule.utility.d.ts +8 -2
- package/dist/global/utilities/schedule.utility.d.ts.map +1 -1
- package/dist/global/utilities/schedule.utility.js +33 -2
- package/dist/global/utilities/schedule.utility.js.map +1 -1
- package/dist/global/utilities/seeder.utility.d.ts.map +1 -1
- package/dist/global/utilities/seeder.utility.js +1 -2
- package/dist/global/utilities/seeder.utility.js.map +1 -1
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -5
- package/dist/index.js.map +1 -1
- package/dist/main.js +3 -2
- package/dist/main.js.map +1 -1
- package/dist/migrations/1749600000002.CreateSysTenantsTable.js +1 -1
- package/dist/migrations/1749600000002.CreateSysTenantsTable.js.map +1 -1
- package/dist/migrations/1749600000004.CreateSysRolesTable.d.ts.map +1 -1
- package/dist/migrations/1749600000004.CreateSysRolesTable.js +2 -1
- package/dist/migrations/1749600000004.CreateSysRolesTable.js.map +1 -1
- package/dist/migrations/1749600000006.CreateSysUserRolesJoinTable.js +1 -1
- package/dist/migrations/1749600000006.CreateSysUserRolesJoinTable.js.map +1 -1
- package/dist/migrations/1749600000007.CreateSysConstantTypesTable.d.ts.map +1 -1
- package/dist/migrations/1749600000007.CreateSysConstantTypesTable.js +2 -1
- package/dist/migrations/1749600000007.CreateSysConstantTypesTable.js.map +1 -1
- package/dist/migrations/1749600000010.CreateSysPropertiesTable.js +1 -1
- package/dist/migrations/1749600000010.CreateSysPropertiesTable.js.map +1 -1
- package/dist/migrations/1749600000014.CreateSysRefreshTokensTable.js +1 -1
- package/dist/migrations/1749600000014.CreateSysRefreshTokensTable.js.map +1 -1
- package/dist/migrations/1749600000016.CreateSysUserDeviceTokensTable.js +1 -1
- package/dist/migrations/1749600000016.CreateSysUserDeviceTokensTable.js.map +1 -1
- package/dist/migrations/1749600000017.CreateSysApiKeysTable.js +1 -1
- package/dist/migrations/1749600000017.CreateSysApiKeysTable.js.map +1 -1
- package/dist/migrations/1749600000018.CreateSysScheduledTasksTable.d.ts.map +1 -1
- package/dist/migrations/1749600000018.CreateSysScheduledTasksTable.js +24 -2
- package/dist/migrations/1749600000018.CreateSysScheduledTasksTable.js.map +1 -1
- package/dist/migrations/1749600000019.CreateSysScheduledEventsTable.d.ts.map +1 -1
- package/dist/migrations/1749600000019.CreateSysScheduledEventsTable.js +8 -1
- package/dist/migrations/1749600000019.CreateSysScheduledEventsTable.js.map +1 -1
- package/dist/migrations/1749600000020.CreateSysEmailTemplatesTable.js +1 -1
- package/dist/migrations/1749600000020.CreateSysEmailTemplatesTable.js.map +1 -1
- package/dist/migrations/1749600000022.CreateSysAdminRolesTable.d.ts.map +1 -1
- package/dist/migrations/1749600000022.CreateSysAdminRolesTable.js +2 -1
- package/dist/migrations/1749600000022.CreateSysAdminRolesTable.js.map +1 -1
- package/dist/migrations/1749600000023.CreateSysAdminUserRolesJoinTable.js +1 -1
- package/dist/migrations/1749600000023.CreateSysAdminUserRolesJoinTable.js.map +1 -1
- package/dist/migrations/1749600000024.CreateSysAuthSessionsTable.js +2 -2
- package/dist/migrations/1749600000024.CreateSysAuthSessionsTable.js.map +1 -1
- package/dist/migrations/1749600000025.CreateSysScopesTable.js +2 -2
- package/dist/migrations/1749600000025.CreateSysScopesTable.js.map +1 -1
- package/dist/migrations/1749600000026.CreateSysApiScopesTable.js +1 -1
- package/dist/migrations/1749600000026.CreateSysApiScopesTable.js.map +1 -1
- package/dist/tenant/entities/tenant.entity.js +1 -1
- package/dist/tenant/entities/tenant.entity.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ app.useGlobalInterceptors(
|
|
|
87
87
|
| Entities | `RootEntity`, `CommonEntity`, `CommonAdminEntity`, `UserEntity`, `AdminUserEntity`, `SystemRoleEntity`, `SystemAdminRoleEntity`, ... | uuid PK, soft deletes, `created_by`, jsonb `attributes`; entity-level `findOneOrNew`, `softDelete`, `hardDelete`, `restore`, `paginate` statics |
|
|
88
88
|
| Migrations | `CreateSysUsersTable...` (26 files, one per table), `MigrationUtility`, `SeederUtility` | fluent `this.string()`, `this.numeric()`, `addRecord()` seeding |
|
|
89
89
|
| Queue | `QueueModule`, `QueueService`, `CommonJob`, `JobConsumer` | BullMQ `@Processor`/`WorkerHost` consumer; auto-discovered jobs, duplicate prevention, recurring schedulers, 1-day TTL, retries, failures persisted to `sys_failed_jobs` |
|
|
90
|
-
| Scheduled events | `SystemScheduledTaskEntity`, `ScheduledEventEntity`, `SetScheduledEventJob`, `DispatchScheduledEventJob`
|
|
90
|
+
| Scheduled events | `SystemScheduledTaskEntity`, `ScheduledEventEntity`, `SetScheduledEventJob`, `DispatchScheduledEventJob`, `ScheduleResolver` | schedule definitions in `sys_scheduled_tasks` → events in `sys_scheduled_events`; interval / cron / once specs with timezones, drift-free slots, horizon materialisation, catch-up + overlap policies, fire-once dispatch with backoff, cadence via `SCHEDULED_EVENT_MIN` |
|
|
91
91
|
| Auth | `AuthModule`, `AuthService.validateRole()`, `Auth`, `JwtMiddleware`, `GoogleAuthService` | imperative auth (open by default); JwtMiddleware resolves the user into `Auth`'s AsyncLocalStorage context per request; access + rotating refresh tokens; session-based logout invalidation (`sys_auth_sessions`); Google SSO via ID token at `POST /auth/google` |
|
|
92
92
|
| Admin auth | `AdminAuthService.validateRole()`, `AdminAuth`, `AdminJwtMiddleware`, `AdminAuthController` (`/admin/auth`) | fully separate stack for back-office admins — own users table (`sys_admin_users`), own roles (`sys_admin_roles`/`sys_auser_roles`), own sessions/refresh tokens (shared tables, `is_admin` flag) |
|
|
93
93
|
| API keys | `ApiKeyService`, `ApiKeyGuard` / `ApiKeyMiddleware`, `@ApiKeyScopes()`, `ScopeEntity`, `ApiScopeEntity` | hashed keys in `sys_api_keys` (admin-owned), scopes, expiry/revocation, `x-api-key` header; normalized scopes catalogue in `sys_scopes`/`sys_api_scopes` |
|
|
@@ -270,6 +270,8 @@ admin with the `admin` role can grant `sys_admin_roles` to other admins via
|
|
|
270
270
|
| `BULL_JOB_TTL_SECONDS` | `86400` | Retention (seconds) for completed/failed jobs before removal from the queue + Redis (default 1 day) |
|
|
271
271
|
| `MAX_JOB_RETRIES` | `3` | Max attempts per job (BullMQ `attempts` default) and the scheduled-event retry ceiling |
|
|
272
272
|
| `SCHEDULED_EVENT_MIN` | `0` | `SetScheduledEventJob` cadence in minutes (every N minutes); `0`/unset disables self-scheduling |
|
|
273
|
+
| `SCHEDULED_EVENT_HORIZON_MIN` | _(derived)_ | How far ahead occurrences are materialised; defaults to 2× the cadence, floored at one minute |
|
|
274
|
+
| `SCHEDULED_EVENT_BATCH` | `500` | Occurrences dispatched per pass |
|
|
273
275
|
| `ENABLE_SCHEDULED_EVENTS_EXECUTION` | _unset_ | Must be exactly `true` to arm scheduled-event materialisation and dispatch |
|
|
274
276
|
|
|
275
277
|
#### Jobs
|
|
@@ -327,10 +329,10 @@ therefore invisible to `retryJob(jobId)`. API instances leave
|
|
|
327
329
|
Recurring work is event-driven (off the BullMQ worker), not a reconciliation
|
|
328
330
|
loop. Two tables back it:
|
|
329
331
|
|
|
330
|
-
| Table | Entity | Role
|
|
331
|
-
| ---------------------- | --------------------------- |
|
|
332
|
-
| `sys_scheduled_tasks` | `SystemScheduledTaskEntity` | a schedule definition (`identifier`, `name`, `start_from`, `
|
|
333
|
-
| `sys_scheduled_events` | `ScheduledEventEntity` | one row per fire time (`job_id` → task, `scheduled_at`, `started_at`, `failed_at`, `total_attempts`, `active`); one task → many events
|
|
332
|
+
| Table | Entity | Role |
|
|
333
|
+
| ---------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
334
|
+
| `sys_scheduled_tasks` | `SystemScheduledTaskEntity` | a schedule definition (`identifier`, `name`, `start_from`, `schedule`, `timezone`, `payload`, `catch_up_policy`, `max_catchup`, `overlap_policy`, `jitter_sec`, `enabled`, `next_upsert_at`) |
|
|
335
|
+
| `sys_scheduled_events` | `ScheduledEventEntity` | one row per fire time (`job_id` → task, `scheduled_at`, `status`, `next_attempt_at`, `started_at`, `failed_at`, `total_attempts`, `active`); one task → many events |
|
|
334
336
|
|
|
335
337
|
`JobConsumer` enrols `SetScheduledEventJob` as a recurring scheduler once **both**
|
|
336
338
|
the worker's Redis connection is ready and the application has bootstrapped —
|
|
@@ -343,37 +345,135 @@ the worker is ready rather than one cadence later.
|
|
|
343
345
|
|
|
344
346
|
Cadence comes from `SCHEDULED_EVENT_MIN` — every N minutes (`0`/unset disables it).
|
|
345
347
|
BullMQ keys the scheduler on the job identifier, so re-running on each boot
|
|
346
|
-
**upserts** rather than duplicates.
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
`
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
`
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
348
|
+
**upserts** rather than duplicates. Set `ENABLE_SCHEDULED_EVENTS_EXECUTION=true` to
|
|
349
|
+
arm materialisation and dispatch — the value must be exactly `true`.
|
|
350
|
+
|
|
351
|
+
##### Schedule kinds
|
|
352
|
+
|
|
353
|
+
Each task's `schedule` column is a discriminated JSONB spec, so expressing a new
|
|
354
|
+
kind of "when" never changes the schema:
|
|
355
|
+
|
|
356
|
+
| `kind` | Shape | Example |
|
|
357
|
+
| ---------- | ----------------------------------------- | ------------------------------------------- |
|
|
358
|
+
| `interval` | `{ kind, day?, hour?, min?, sec? }` | `{ kind: 'interval', hour: 6 }` |
|
|
359
|
+
| `cron` | `{ kind, expression }` (5- or 6-field) | `{ kind: 'cron', expression: '0 2 * * MON' }` |
|
|
360
|
+
| `once` | `{ kind }` — fires at `start_from`, then retires | `{ kind: 'once' }` |
|
|
361
|
+
|
|
362
|
+
`cron` is what expresses day-, weekday- and month-based schedules, evaluated in the
|
|
363
|
+
task's `timezone` (IANA name, default `UTC`) so a local wall time stays put across
|
|
364
|
+
DST. Each kind is advanced by a pure `ScheduleResolver` registered in
|
|
365
|
+
`baseScheduleResolverMaps`; adding a kind means adding a resolver, not touching the
|
|
366
|
+
materialiser. Rows written before `schedule` carried a `kind` are read as intervals
|
|
367
|
+
by `ScheduleUtility.normalise`, so no backfill is needed.
|
|
368
|
+
|
|
369
|
+
##### Slots are derived from slots, not from `now`
|
|
370
|
+
|
|
371
|
+
`next_upsert_at` is the cursor — the next slot not yet materialised — and every slot
|
|
372
|
+
is computed from the **previous slot**. Anchoring on `now` instead would fold each
|
|
373
|
+
pass's lateness into the next fire time permanently: an hourly task polled every
|
|
374
|
+
five minutes would slide by up to five minutes per occurrence, roughly two hours a
|
|
375
|
+
day. `start_from` is itself the first candidate slot, so a task fires at the time it
|
|
376
|
+
was asked to start rather than one interval later.
|
|
377
|
+
|
|
378
|
+
##### Horizon materialisation
|
|
379
|
+
|
|
380
|
+
A pass materialises every slot up to `now + horizon`, not one slot at a time. The
|
|
381
|
+
horizon defaults to twice the driver cadence (`SCHEDULED_EVENT_HORIZON_MIN`
|
|
382
|
+
overrides it, floored at a minute), so an occurrence always exists before it comes
|
|
383
|
+
due. The cadence therefore bounds only how far ahead work is prepared — it is **not
|
|
384
|
+
a floor on schedule granularity**. A `{ sec: 30 }` task materialises every
|
|
385
|
+
30-second slot even when the driver polls every few minutes.
|
|
386
|
+
|
|
387
|
+
##### Catch-up, overlap and jitter
|
|
388
|
+
|
|
389
|
+
What happens to fire times missed while the scheduler was down is a per-task
|
|
390
|
+
decision (`catch_up_policy`), not an accident:
|
|
391
|
+
|
|
392
|
+
| Policy | Behaviour |
|
|
393
|
+
| -------------- | -------------------------------------------------------------------------- |
|
|
394
|
+
| `skip_missed` | advance past them, materialise nothing |
|
|
395
|
+
| `fire_once` | **default** — materialise only the most recent elapsed slot |
|
|
396
|
+
| `fire_all` | materialise every elapsed slot, retaining the most recent `max_catchup` |
|
|
397
|
+
|
|
398
|
+
Discarded slots are counted and logged; a silent gap would read as "nothing was
|
|
399
|
+
scheduled". The elapsed-slot walk is bounded by `ScheduleDefault.MAX_SCAN`, and a
|
|
400
|
+
fast-forward is logged too.
|
|
401
|
+
|
|
402
|
+
`overlap_policy: skip_when_due_pending` holds the cursor while an already-due
|
|
403
|
+
occurrence of the same task is still undispatched. It suppresses **dispatch
|
|
404
|
+
backlog**, not overlapping runs — once an occurrence is on the queue its completion
|
|
405
|
+
lives in BullMQ and is invisible here. Nothing is discarded when it engages: the
|
|
406
|
+
slots stay unmaterialised and the catch-up policy decides later. `jitter_sec` adds a
|
|
407
|
+
random spread to each fire time so tasks sharing a schedule do not stampede; the
|
|
408
|
+
jitter lands on the occurrence, never on the cursor, so it cannot accumulate.
|
|
409
|
+
|
|
410
|
+
##### Creating and editing a task
|
|
411
|
+
|
|
412
|
+
`POST /api/admin/scheduled-tasks` is an upsert. `AddScheduledTaskDto` extends
|
|
413
|
+
`CommonPayloadDto`, so it carries an optional `id`: send one to edit that task, omit
|
|
414
|
+
it to create. `identifier`, `name` and `schedule` are required by the DTO either way;
|
|
415
|
+
`identifier` uniqueness is checked in the processor, excluding the row being edited.
|
|
416
|
+
|
|
417
|
+
Changing what the schedule **means** — `schedule`, `timezone` or `start_from` —
|
|
418
|
+
additionally re-seats the cursor and soft-deletes occurrences that are `pending` and
|
|
419
|
+
not yet due, both in one transaction with the save so a materialisation pass landing
|
|
420
|
+
mid-edit cannot leave stale slots behind. Already-due occurrences are kept (the old
|
|
421
|
+
schedule genuinely asked for that work), and anything `claimed`/`enqueued`/`failed`/
|
|
422
|
+
`abandoned` is left alone. Schedules are compared by meaning — interval millisecond
|
|
423
|
+
sum, cron expression — so renaming a task or editing its payload never moves its
|
|
424
|
+
fire times.
|
|
425
|
+
|
|
426
|
+
The cursor is seeded by `seedScheduleCursor`, not set to `start_from` directly: the
|
|
427
|
+
materialiser trusts the cursor to be a real slot of the series. `start_from` is only
|
|
428
|
+
a valid slot for `interval` (which re-anchors onto it) and `once` (whose only slot it
|
|
429
|
+
is); a cron series snaps forward to its first real slot at or after the anchor, so a
|
|
430
|
+
`0 2 * * MON` task doesn't fire once at whatever minute it was saved. A past
|
|
431
|
+
`start_from` is clamped to `now` for the recurring kinds, so creating a task doesn't
|
|
432
|
+
hand the catch-up policy a backlog it never asked for.
|
|
433
|
+
|
|
434
|
+
##### Occurrence lifecycle
|
|
435
|
+
|
|
436
|
+
`status` carries where an occurrence is; `active` is orthogonal and carries
|
|
437
|
+
suppression by the parent task.
|
|
438
|
+
|
|
439
|
+
| Status | Meaning |
|
|
440
|
+
| ----------- | ------------------------------------------------------------------------------------ |
|
|
441
|
+
| `pending` | awaiting dispatch; `next_attempt_at` gates eligibility |
|
|
442
|
+
| `claimed` | a pass owns it — a row stuck here means the process died between claim and enqueue |
|
|
443
|
+
| `enqueued` | handed to the queue (terminal); BullMQ's own `attempts` governs it from there |
|
|
444
|
+
| `failed` | last enqueue failed; retried once `next_attempt_at` passes |
|
|
445
|
+
| `abandoned` | attempts exhausted — terminal and queryable, not merely absent from the due set |
|
|
446
|
+
|
|
447
|
+
Each occurrence fires **once**. A pass claims an event by moving it to `claimed`
|
|
448
|
+
under a still-dispatchable condition, incrementing `total_attempts` in the same
|
|
449
|
+
statement, and only enqueues if that claim affected a row — so two concurrent passes
|
|
450
|
+
cannot both dispatch it. Because the claim is written before the enqueue, dispatch
|
|
451
|
+
is **at-most-once**: if the process dies between them the occurrence is skipped
|
|
452
|
+
rather than dispatched twice, and it stays visible as `claimed`.
|
|
453
|
+
|
|
454
|
+
A failed enqueue releases the claim, records `failed_at`/`error`, and pushes
|
|
455
|
+
`next_attempt_at` out by an exponential backoff (60s doubling per attempt, capped at
|
|
456
|
+
an hour), so a broken task is not retried on every tick. Once `total_attempts`
|
|
457
|
+
reaches `MAX_JOB_RETRIES` (default 3) the occurrence is moved to `abandoned`.
|
|
458
|
+
Dispatch reads oldest-first, bounded by `SCHEDULED_EVENT_BATCH` (default 500); the
|
|
459
|
+
`(status, scheduled_at)` index seeks to the due set and already yields it in
|
|
460
|
+
`ORDER BY` order.
|
|
367
461
|
|
|
368
462
|
Materialisation is safe to run concurrently — `BULL_WORKERS` defaults to 2, and
|
|
369
|
-
several worker instances may share one queue. Each
|
|
370
|
-
|
|
371
|
-
while advancing
|
|
372
|
-
The claim and the
|
|
373
|
-
advance the
|
|
374
|
-
`SystemScheduledTaskJob` (via `SystemScheduledTaskSubscriber`)
|
|
375
|
-
step with task changes — toggling `active` when a task is
|
|
376
|
-
soft-deleting events when a task is removed.
|
|
463
|
+
several worker instances may share one queue. Each task's slots are **claimed**
|
|
464
|
+
before their events are created: a conditional `UPDATE` re-asserts
|
|
465
|
+
`next_upsert_at < horizonEnd` while advancing the cursor, so a second racing pass
|
|
466
|
+
matches zero rows and skips the task. The claim and the inserts share a transaction,
|
|
467
|
+
so a crash between them cannot advance the cursor without creating the occurrences
|
|
468
|
+
it accounted for. `SystemScheduledTaskJob` (via `SystemScheduledTaskSubscriber`)
|
|
469
|
+
keeps events in step with task changes — toggling `active` when a task is
|
|
470
|
+
enabled/disabled and soft-deleting events when a task is removed.
|
|
471
|
+
|
|
472
|
+
> `sys_scheduled_events` is append-only — nothing in the package prunes it, and
|
|
473
|
+
> horizon materialisation writes a row per slot. Bounding it with a retention sweep
|
|
474
|
+
> over terminal rows (`enqueued`, `abandoned`) older than a cutoff is left to the
|
|
475
|
+
> application; the `(status, scheduled_at)` index covers that delete. Never prune
|
|
476
|
+
> `pending` or `failed` rows — those are live work.
|
|
377
477
|
|
|
378
478
|
`DispatchScheduledEventJob` enqueues each due event under **the scheduled task's
|
|
379
479
|
own `identifier`**, so register a job in your app whose identifier matches the
|
|
@@ -643,12 +743,12 @@ pass the actor to a processor.
|
|
|
643
743
|
|
|
644
744
|
| Route | Min. role | Processor |
|
|
645
745
|
| ---------------------------------- | --------------- | ---------------------------- |
|
|
646
|
-
| `POST /admin/tenants` | super admin | `TenantDataProcessor`
|
|
746
|
+
| `POST /admin/tenants` | super admin | `TenantDataProcessor` (upsert — send `id` to update) |
|
|
647
747
|
| `POST /admin/tenants/list` | admin | `TenantListProcessor` |
|
|
648
748
|
| `POST /admin/users/clients` | super admin | `ClientUserDataProcessor` |
|
|
649
749
|
| `POST /admin/users/clients/bulk` | super admin | `BulkUserDataProcessor` |
|
|
650
750
|
| `POST /admin/users/admins` | admin | `AdminUserDataProcessor` |
|
|
651
|
-
| `POST /admin/scheduled-tasks` | content manager | `ScheduledTaskDataProcessor` |
|
|
751
|
+
| `POST /admin/scheduled-tasks` | content manager | `ScheduledTaskDataProcessor` (upsert — send `id` to update) |
|
|
652
752
|
| `POST /admin/scheduled-tasks/list` | content reader | `ScheduledTaskListProcessor` |
|
|
653
753
|
|
|
654
754
|
List endpoints are `POST .../list` with the filter payload in the body (a
|
|
@@ -678,6 +778,30 @@ Onboarding a tenant (`tenant-onboarded`) or a single client user
|
|
|
678
778
|
`AdminModule` imports `NotificationModule` and `SystemPropertyModule`; bulk
|
|
679
779
|
registration deliberately sends nothing.
|
|
680
780
|
|
|
781
|
+
##### Create vs. update
|
|
782
|
+
|
|
783
|
+
Creation DTOs extend `CommonPayloadDto`, which carries an optional UUID `id`. Where a
|
|
784
|
+
processor supports it, sending an `id` turns the same `POST` into an update.
|
|
785
|
+
|
|
786
|
+
The processor loads the row when an `id` is present, falls back to `Entity.create()`
|
|
787
|
+
when it isn't, then assigns every field and saves — one path, no create/update
|
|
788
|
+
branching. Required fields stay **required in the DTO** (`@IsNotEmpty()`, `@IsString()`,
|
|
789
|
+
…), so the payload always describes the whole record and validation stays where the
|
|
790
|
+
decorators are. Omitting an *optional* field leaves it unchanged on an edit, since
|
|
791
|
+
TypeORM skips `undefined` properties on update.
|
|
792
|
+
|
|
793
|
+
Processors only validate what decorators cannot see: whether the `id` exists, and
|
|
794
|
+
uniqueness against other rows. Uniqueness checks (tenant `slug`, scheduled-task
|
|
795
|
+
`identifier`) exclude the row being edited — they run in code rather than as DB
|
|
796
|
+
constraints, so resaving a record must not collide with itself.
|
|
797
|
+
|
|
798
|
+
| Processor | Update | Notes |
|
|
799
|
+
| --------- | ------ | ----- |
|
|
800
|
+
| `TenantDataProcessor` | yes | Never re-runs onboarding: `onboarded_at`, `created_by` and the welcome email belong to first registration |
|
|
801
|
+
| `ScheduledTaskDataProcessor` | yes | Changing `schedule`/`timezone`/`start_from` also re-seats the cursor and drops not-yet-due occurrences |
|
|
802
|
+
| `ClientUserDataProcessor`, `AdminUserDataProcessor` | not yet | Their DTOs carry `id`, but the processors are still create-only. Password and role changes are intended to get their own endpoints rather than riding on an upsert |
|
|
803
|
+
| `BulkUserDataProcessor` | n/a | `AddBulkUsersDto` is a batch wrapper, not a record; each `BulkUserItemDto` carries an `id` |
|
|
804
|
+
|
|
681
805
|
Data processors extend `CommonDataProcessor` and are created per request
|
|
682
806
|
(`new XxxDataProcessor(...deps).process(dto)`); list processors return a
|
|
683
807
|
`PaginatedResult`. Bulk registration validates the entire batch before any insert.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.module.d.ts","sourceRoot":"","sources":["../../src/admin/admin.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAIvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAG9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"admin.module.d.ts","sourceRoot":"","sources":["../../src/admin/admin.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAIvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAG9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAY9D,qBAMa,WAAW;IACtB,MAAM,CAAC,QAAQ,CAAC,OAAO,GAAE,kBAAuB,GAAG,aAAa;CAcjE"}
|
|
@@ -14,7 +14,6 @@ const tenant_module_1 = require("../tenant/tenant.module");
|
|
|
14
14
|
const es6_classes_1 = require("./es6.classes");
|
|
15
15
|
const notification_module_1 = require("../notification/notification.module");
|
|
16
16
|
const system_property_module_1 = require("../common/system.property.module");
|
|
17
|
-
const [AdminAccessService] = es6_classes_1.es6Classes.services;
|
|
18
17
|
let AdminModule = AdminModule_1 = class AdminModule {
|
|
19
18
|
static register(options = {}) {
|
|
20
19
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.module.js","sourceRoot":"","sources":["../../src/admin/admin.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AACvD,qDAAiD;AACjD,2DAAuD;AACvD,+CAA2C;AAE3C,6EAAyE;AACzE,6EAAwE;
|
|
1
|
+
{"version":3,"file":"admin.module.js","sourceRoot":"","sources":["../../src/admin/admin.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AACvD,qDAAiD;AACjD,2DAAuD;AACvD,+CAA2C;AAE3C,6EAAyE;AACzE,6EAAwE;AAmBjE,IAAM,WAAW,mBAAjB,MAAM,WAAW;IACtB,MAAM,CAAC,QAAQ,CAAC,UAA8B,EAAE;QAC9C,OAAO;YACL,MAAM,EAAE,aAAW;YACnB,OAAO,EAAE;gBACP,wBAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC5B,4BAAY,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC9B,wCAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACpC,6CAAoB,CAAC,QAAQ,CAAC,OAAO,CAAC;aACvC;YACD,WAAW,EAAE,CAAC,GAAG,wBAAU,CAAC,WAAW,CAAC;YACxC,SAAS,EAAE,CAAC,GAAG,wBAAU,CAAC,QAAQ,CAAC;YACnC,OAAO,EAAE,CAAC,GAAG,wBAAU,CAAC,QAAQ,CAAC;SAClC,CAAC;IACJ,CAAC;CACF,CAAA;AAfY,kCAAW;sBAAX,WAAW;IANvB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,wBAAU,EAAE,4BAAY,EAAE,wCAAkB,EAAE,6CAAoB,CAAC;QAC7E,WAAW,EAAE,CAAC,GAAG,wBAAU,CAAC,WAAW,CAAC;QACxC,SAAS,EAAE,CAAC,GAAG,wBAAU,CAAC,QAAQ,CAAC;QACnC,OAAO,EAAE,CAAC,GAAG,wBAAU,CAAC,QAAQ,CAAC;KAClC,CAAC;GACW,WAAW,CAevB"}
|
|
@@ -6,7 +6,7 @@ export declare class AdminScheduledTaskController {
|
|
|
6
6
|
private readonly adminAccessService;
|
|
7
7
|
private readonly sqlService;
|
|
8
8
|
constructor(adminAccessService: AdminAccessService, sqlService: SqlService);
|
|
9
|
-
|
|
9
|
+
save(dto: AddScheduledTaskDto): Promise<import("../..").SystemScheduledTaskEntity>;
|
|
10
10
|
list(dto: ScheduledTaskListDto): Promise<{
|
|
11
11
|
records: import("../..").SqlRow[];
|
|
12
12
|
total: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.scheduled.task.controller.d.ts","sourceRoot":"","sources":["../../../src/admin/controllers/admin.scheduled.task.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAGtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,qBAGa,4BAA4B;IAErC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU;gBADV,kBAAkB,EAAE,kBAAkB,EACtC,UAAU,EAAE,UAAU;
|
|
1
|
+
{"version":3,"file":"admin.scheduled.task.controller.d.ts","sourceRoot":"","sources":["../../../src/admin/controllers/admin.scheduled.task.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAGtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,qBAGa,4BAA4B;IAErC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU;gBADV,kBAAkB,EAAE,kBAAkB,EACtC,UAAU,EAAE,UAAU;IASnC,IAAI,CAAS,GAAG,EAAE,mBAAmB;IAUrC,IAAI,CAAS,GAAG,EAAE,oBAAoB;;;;;;;CAI7C"}
|
|
@@ -26,7 +26,7 @@ let AdminScheduledTaskController = class AdminScheduledTaskController {
|
|
|
26
26
|
this.adminAccessService = adminAccessService;
|
|
27
27
|
this.sqlService = sqlService;
|
|
28
28
|
}
|
|
29
|
-
async
|
|
29
|
+
async save(dto) {
|
|
30
30
|
const { user } = await this.adminAccessService.validateContentManager();
|
|
31
31
|
return new scheduled_task_data_processor_1.ScheduledTaskDataProcessor(user).process(dto);
|
|
32
32
|
}
|
|
@@ -39,14 +39,14 @@ exports.AdminScheduledTaskController = AdminScheduledTaskController;
|
|
|
39
39
|
__decorate([
|
|
40
40
|
(0, common_1.Post)(),
|
|
41
41
|
(0, swagger_1.ApiOperation)({
|
|
42
|
-
summary: 'Add a scheduled task.',
|
|
43
|
-
description: 'Requires at least the global content manager role.',
|
|
42
|
+
summary: 'Add or update a scheduled task.',
|
|
43
|
+
description: 'Send an `id` to edit that task, or omit it to create one; omitted optional fields keep their stored value. Changing `schedule`, `timezone` or `start_from` re-seats the cursor and discards occurrences that were materialised under the old schedule but are not yet due. Requires at least the global content manager role.',
|
|
44
44
|
}),
|
|
45
45
|
__param(0, (0, common_1.Body)()),
|
|
46
46
|
__metadata("design:type", Function),
|
|
47
47
|
__metadata("design:paramtypes", [add_scheduled_task_dto_1.AddScheduledTaskDto]),
|
|
48
48
|
__metadata("design:returntype", Promise)
|
|
49
|
-
], AdminScheduledTaskController.prototype, "
|
|
49
|
+
], AdminScheduledTaskController.prototype, "save", null);
|
|
50
50
|
__decorate([
|
|
51
51
|
(0, common_1.Post)('list'),
|
|
52
52
|
(0, swagger_1.ApiOperation)({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.scheduled.task.controller.js","sourceRoot":"","sources":["../../../src/admin/controllers/admin.scheduled.task.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAwD;AACxD,6CAAuE;AACvE,mEAA+D;AAC/D,2EAAsE;AACtE,8FAAwF;AACxF,8FAAwF;AACxF,2EAAqE;AACrE,6EAAuE;AAKhE,IAAM,4BAA4B,GAAlC,MAAM,4BAA4B;IACvC,YACmB,kBAAsC,EACtC,UAAsB;QADtB,uBAAkB,GAAlB,kBAAkB,CAAoB;QACtC,eAAU,GAAV,UAAU,CAAY;IACtC,CAAC;
|
|
1
|
+
{"version":3,"file":"admin.scheduled.task.controller.js","sourceRoot":"","sources":["../../../src/admin/controllers/admin.scheduled.task.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAwD;AACxD,6CAAuE;AACvE,mEAA+D;AAC/D,2EAAsE;AACtE,8FAAwF;AACxF,8FAAwF;AACxF,2EAAqE;AACrE,6EAAuE;AAKhE,IAAM,4BAA4B,GAAlC,MAAM,4BAA4B;IACvC,YACmB,kBAAsC,EACtC,UAAsB;QADtB,uBAAkB,GAAlB,kBAAkB,CAAoB;QACtC,eAAU,GAAV,UAAU,CAAY;IACtC,CAAC;IAQE,AAAN,KAAK,CAAC,IAAI,CAAS,GAAwB;QACzC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,sBAAsB,EAAE,CAAC;QACxE,OAAO,IAAI,0DAA0B,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3D,CAAC;IAOK,AAAN,KAAK,CAAC,IAAI,CAAS,GAAyB;QAC1C,MAAM,IAAI,CAAC,kBAAkB,CAAC,qBAAqB,EAAE,CAAC;QACtD,OAAO,IAAI,0DAA0B,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtE,CAAC;CACF,CAAA;AA1BY,oEAA4B;AAYjC;IANL,IAAA,aAAI,GAAE;IACN,IAAA,sBAAY,EAAC;QACZ,OAAO,EAAE,iCAAiC;QAC1C,WAAW,EACT,+TAA+T;KAClU,CAAC;IACU,WAAA,IAAA,aAAI,GAAE,CAAA;;qCAAM,4CAAmB;;wDAG1C;AAOK;IALL,IAAA,aAAI,EAAC,MAAM,CAAC;IACZ,IAAA,sBAAY,EAAC;QACZ,OAAO,EAAE,0CAA0C;QACnD,WAAW,EAAE,mDAAmD;KACjE,CAAC;IACU,WAAA,IAAA,aAAI,GAAE,CAAA;;qCAAM,8CAAoB;;wDAG3C;uCAzBU,4BAA4B;IAHxC,IAAA,iBAAO,EAAC,yBAAyB,CAAC;IAClC,IAAA,uBAAa,GAAE;IACf,IAAA,mBAAU,EAAC,2BAA2B,CAAC;qCAGC,yCAAkB;QAC1B,wBAAU;GAH9B,4BAA4B,CA0BxC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.tenant.controller.d.ts","sourceRoot":"","sources":["../../../src/admin/controllers/admin.tenant.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAGtE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wDAAwD,CAAC;AAClG,OAAO,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC;AAEtF,qBAGa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,wBAAwB;IACzC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBAHrB,kBAAkB,EAAE,kBAAkB,EACtC,UAAU,EAAE,UAAU,EACtB,wBAAwB,EAAE,wBAAwB,EAClD,qBAAqB,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"admin.tenant.controller.d.ts","sourceRoot":"","sources":["../../../src/admin/controllers/admin.tenant.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAGtE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wDAAwD,CAAC;AAClG,OAAO,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC;AAEtF,qBAGa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,wBAAwB;IACzC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBAHrB,kBAAkB,EAAE,kBAAkB,EACtC,UAAU,EAAE,UAAU,EACtB,wBAAwB,EAAE,wBAAwB,EAClD,qBAAqB,EAAE,qBAAqB;IASzD,OAAO,CAAS,GAAG,EAAE,YAAY;IAejC,IAAI,CAAS,GAAG,EAAE,aAAa;;;;;;;CAItC"}
|
|
@@ -43,8 +43,8 @@ exports.AdminTenantController = AdminTenantController;
|
|
|
43
43
|
__decorate([
|
|
44
44
|
(0, common_1.Post)(),
|
|
45
45
|
(0, swagger_1.ApiOperation)({
|
|
46
|
-
summary: 'Onboard
|
|
47
|
-
description: 'Requires the global super admin role.',
|
|
46
|
+
summary: 'Onboard a new client tenant, or update an existing one.',
|
|
47
|
+
description: 'Send an `id` to edit that tenant; omit it to onboard a new one. Omitted optional fields keep their stored value. An edit never re-runs onboarding — `onboarded_at`, `created_by` and the welcome email belong to first registration. Requires the global super admin role.',
|
|
48
48
|
}),
|
|
49
49
|
__param(0, (0, common_1.Body)()),
|
|
50
50
|
__metadata("design:type", Function),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.tenant.controller.js","sourceRoot":"","sources":["../../../src/admin/controllers/admin.tenant.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAwD;AACxD,6CAAuE;AACvE,mEAA+D;AAC/D,2EAAsE;AACtE,8EAAyE;AACzE,8EAAyE;AACzE,2DAAsD;AACtD,6DAAwD;AACxD,uGAAkG;AAClG,2FAAsF;AAK/E,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAChC,YACmB,kBAAsC,EACtC,UAAsB,EACtB,wBAAkD,EAClD,qBAA4C;QAH5C,uBAAkB,GAAlB,kBAAkB,CAAoB;QACtC,eAAU,GAAV,UAAU,CAAY;QACtB,6BAAwB,GAAxB,wBAAwB,CAA0B;QAClD,0BAAqB,GAArB,qBAAqB,CAAuB;IAC5D,CAAC;
|
|
1
|
+
{"version":3,"file":"admin.tenant.controller.js","sourceRoot":"","sources":["../../../src/admin/controllers/admin.tenant.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAwD;AACxD,6CAAuE;AACvE,mEAA+D;AAC/D,2EAAsE;AACtE,8EAAyE;AACzE,8EAAyE;AACzE,2DAAsD;AACtD,6DAAwD;AACxD,uGAAkG;AAClG,2FAAsF;AAK/E,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAChC,YACmB,kBAAsC,EACtC,UAAsB,EACtB,wBAAkD,EAClD,qBAA4C;QAH5C,uBAAkB,GAAlB,kBAAkB,CAAoB;QACtC,eAAU,GAAV,UAAU,CAAY;QACtB,6BAAwB,GAAxB,wBAAwB,CAA0B;QAClD,0BAAqB,GAArB,qBAAqB,CAAuB;IAC5D,CAAC;IAQE,AAAN,KAAK,CAAC,OAAO,CAAS,GAAiB;QACrC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC;QAEpE,OAAO,IAAI,2CAAmB,CAC5B,IAAI,EACJ,IAAI,CAAC,wBAAwB,EAC7B,IAAI,CAAC,qBAAqB,CAC3B,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;IAOK,AAAN,KAAK,CAAC,IAAI,CAAS,GAAkB;QACnC,MAAM,IAAI,CAAC,kBAAkB,CAAC,aAAa,EAAE,CAAC;QAC9C,OAAO,IAAI,2CAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/D,CAAC;CACF,CAAA;AAjCY,sDAAqB;AAc1B;IANL,IAAA,aAAI,GAAE;IACN,IAAA,sBAAY,EAAC;QACZ,OAAO,EAAE,yDAAyD;QAClE,WAAW,EACT,4QAA4Q;KAC/Q,CAAC;IACa,WAAA,IAAA,aAAI,GAAE,CAAA;;qCAAM,6BAAY;;oDAQtC;AAOK;IALL,IAAA,aAAI,EAAC,MAAM,CAAC;IACZ,IAAA,sBAAY,EAAC;QACZ,OAAO,EAAE,kCAAkC;QAC3C,WAAW,EAAE,0CAA0C;KACxD,CAAC;IACU,WAAA,IAAA,aAAI,GAAE,CAAA;;qCAAM,+BAAa;;iDAGpC;gCAhCU,qBAAqB;IAHjC,IAAA,iBAAO,EAAC,iBAAiB,CAAC;IAC1B,IAAA,uBAAa,GAAE;IACf,IAAA,mBAAU,EAAC,mBAAmB,CAAC;qCAGS,yCAAkB;QAC1B,wBAAU;QACI,qDAAwB;QAC3B,+CAAqB;GALpD,qBAAqB,CAiCjC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.admin.user.dto.d.ts","sourceRoot":"","sources":["../../../src/admin/dtos/add.admin.user.dto.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"add.admin.user.dto.d.ts","sourceRoot":"","sources":["../../../src/admin/dtos/add.admin.user.dto.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAGxE,qBAAa,eAAgB,SAAQ,gBAAgB;IAInD,IAAI,EAAE,MAAM,CAAC;IAKb,KAAK,EAAE,MAAM,CAAC;IAKd,QAAQ,EAAE,MAAM,CAAC;IAMjB,QAAQ,EAAE,MAAM,CAAC;IAUjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IAKnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC"}
|
|
@@ -12,7 +12,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.AddAdminUserDto = void 0;
|
|
13
13
|
const class_validator_1 = require("class-validator");
|
|
14
14
|
const swagger_1 = require("@nestjs/swagger");
|
|
15
|
-
|
|
15
|
+
const common_payload_dto_1 = require("../../common/dtos/common.payload.dto");
|
|
16
|
+
class AddAdminUserDto extends common_payload_dto_1.CommonPayloadDto {
|
|
16
17
|
}
|
|
17
18
|
exports.AddAdminUserDto = AddAdminUserDto;
|
|
18
19
|
__decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.admin.user.dto.js","sourceRoot":"","sources":["../../../src/admin/dtos/add.admin.user.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAUyB;AACzB,6CAAmE;
|
|
1
|
+
{"version":3,"file":"add.admin.user.dto.js","sourceRoot":"","sources":["../../../src/admin/dtos/add.admin.user.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAUyB;AACzB,6CAAmE;AACnE,6EAAwE;AAGxE,MAAa,eAAgB,SAAQ,qCAAgB;CAoCpD;AApCD,0CAoCC;AAhCC;IAHC,IAAA,qBAAW,EAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IACpC,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,GAAG,CAAC;;6CACF;AAKb;IAHC,IAAA,qBAAW,EAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC5C,IAAA,yBAAO,GAAE;IACT,IAAA,2BAAS,EAAC,GAAG,CAAC;;8CACD;AAKd;IAHC,IAAA,qBAAW,EAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IACpC,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,GAAG,CAAC;;iDACE;AAMjB;IAJC,IAAA,qBAAW,EAAC,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IACrD,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,CAAC,CAAC;IACZ,IAAA,2BAAS,EAAC,EAAE,CAAC;;iDACG;AAUjB;IARC,IAAA,qBAAW,EAAC;QACX,IAAI,EAAE,CAAC,MAAM,CAAC;QACd,MAAM,EAAE,MAAM;QACd,WAAW,EAAE,gDAAgD;KAC9D,CAAC;IACD,IAAA,yBAAO,GAAE;IACT,IAAA,8BAAY,EAAC,CAAC,CAAC;IACf,IAAA,wBAAM,EAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;;iDACX;AAKnB;IAHC,IAAA,6BAAmB,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;IACnE,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;mDACsB"}
|
|
@@ -1,13 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
import { CommonPayloadDto } from '../../common/dtos/common.payload.dto';
|
|
2
|
+
import { CatchUpPolicy, OverlapPolicy, ScheduleKind } from '../../common/enums/schedule.enum';
|
|
3
|
+
export declare class ScheduleDto {
|
|
4
|
+
kind: ScheduleKind;
|
|
5
|
+
day?: number;
|
|
2
6
|
hour?: number;
|
|
3
7
|
min?: number;
|
|
4
8
|
sec?: number;
|
|
9
|
+
expression?: string;
|
|
5
10
|
}
|
|
6
|
-
export declare class AddScheduledTaskDto {
|
|
11
|
+
export declare class AddScheduledTaskDto extends CommonPayloadDto {
|
|
7
12
|
identifier: string;
|
|
8
13
|
name: string;
|
|
9
14
|
start_from?: string;
|
|
10
|
-
|
|
15
|
+
schedule: ScheduleDto;
|
|
16
|
+
timezone?: string;
|
|
17
|
+
payload?: Record<string, unknown>;
|
|
18
|
+
catch_up_policy?: CatchUpPolicy;
|
|
19
|
+
max_catchup?: number;
|
|
20
|
+
overlap_policy?: OverlapPolicy;
|
|
21
|
+
jitter_sec?: number;
|
|
11
22
|
enabled?: boolean;
|
|
12
23
|
}
|
|
13
24
|
//# sourceMappingURL=add.scheduled.task.dto.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.scheduled.task.dto.d.ts","sourceRoot":"","sources":["../../../src/admin/dtos/add.scheduled.task.dto.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"add.scheduled.task.dto.d.ts","sourceRoot":"","sources":["../../../src/admin/dtos/add.scheduled.task.dto.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACxE,OAAO,EACL,aAAa,EACb,aAAa,EAEb,YAAY,EACb,MAAM,kCAAkC,CAAC;AAW1C,qBAAa,WAAW;IAGtB,IAAI,EAAE,YAAY,CAAC;IAOnB,GAAG,CAAC,EAAE,MAAM,CAAC;IAOb,IAAI,CAAC,EAAE,MAAM,CAAC;IAOd,GAAG,CAAC,EAAE,MAAM,CAAC;IAOb,GAAG,CAAC,EAAE,MAAM,CAAC;IASb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAOD,qBAAa,mBAAoB,SAAQ,gBAAgB;IAQvD,UAAU,EAAE,MAAM,CAAC;IAMnB,IAAI,EAAE,MAAM,CAAC;IASb,UAAU,CAAC,EAAE,MAAM,CAAC;IAUpB,QAAQ,EAAE,WAAW,CAAC;IAStB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAQlB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAUlC,eAAe,CAAC,EAAE,aAAa,CAAC;IAUhC,WAAW,CAAC,EAAE,MAAM,CAAC;IAKrB,cAAc,CAAC,EAAE,aAAa,CAAC;IAU/B,UAAU,CAAC,EAAE,MAAM,CAAC;IAKpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
|
|
@@ -9,64 +9,159 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.AddScheduledTaskDto = exports.
|
|
12
|
+
exports.AddScheduledTaskDto = exports.ScheduleDto = void 0;
|
|
13
13
|
const class_transformer_1 = require("class-transformer");
|
|
14
14
|
const class_validator_1 = require("class-validator");
|
|
15
15
|
const swagger_1 = require("@nestjs/swagger");
|
|
16
|
-
|
|
16
|
+
const common_payload_dto_1 = require("../../common/dtos/common.payload.dto");
|
|
17
|
+
const schedule_enum_1 = require("../../common/enums/schedule.enum");
|
|
18
|
+
const schedule_validator_1 = require("../../common/validators/schedule.validator");
|
|
19
|
+
class ScheduleDto {
|
|
17
20
|
}
|
|
18
|
-
exports.
|
|
21
|
+
exports.ScheduleDto = ScheduleDto;
|
|
22
|
+
__decorate([
|
|
23
|
+
(0, swagger_1.ApiProperty)({ enum: schedule_enum_1.ScheduleKind, example: schedule_enum_1.ScheduleKind.INTERVAL }),
|
|
24
|
+
(0, class_validator_1.IsEnum)(schedule_enum_1.ScheduleKind),
|
|
25
|
+
__metadata("design:type", String)
|
|
26
|
+
], ScheduleDto.prototype, "kind", void 0);
|
|
27
|
+
__decorate([
|
|
28
|
+
(0, swagger_1.ApiPropertyOptional)({ default: 0, minimum: 0 }),
|
|
29
|
+
(0, class_validator_1.ValidateIf)((dto) => dto.kind === schedule_enum_1.ScheduleKind.INTERVAL),
|
|
30
|
+
(0, class_validator_1.IsOptional)(),
|
|
31
|
+
(0, class_validator_1.IsInt)(),
|
|
32
|
+
(0, class_validator_1.Min)(0),
|
|
33
|
+
__metadata("design:type", Number)
|
|
34
|
+
], ScheduleDto.prototype, "day", void 0);
|
|
19
35
|
__decorate([
|
|
20
36
|
(0, swagger_1.ApiPropertyOptional)({ default: 0, minimum: 0 }),
|
|
37
|
+
(0, class_validator_1.ValidateIf)((dto) => dto.kind === schedule_enum_1.ScheduleKind.INTERVAL),
|
|
21
38
|
(0, class_validator_1.IsOptional)(),
|
|
22
39
|
(0, class_validator_1.IsInt)(),
|
|
23
40
|
(0, class_validator_1.Min)(0),
|
|
24
41
|
__metadata("design:type", Number)
|
|
25
|
-
],
|
|
42
|
+
], ScheduleDto.prototype, "hour", void 0);
|
|
26
43
|
__decorate([
|
|
27
44
|
(0, swagger_1.ApiPropertyOptional)({ default: 0, minimum: 0 }),
|
|
45
|
+
(0, class_validator_1.ValidateIf)((dto) => dto.kind === schedule_enum_1.ScheduleKind.INTERVAL),
|
|
28
46
|
(0, class_validator_1.IsOptional)(),
|
|
29
47
|
(0, class_validator_1.IsInt)(),
|
|
30
48
|
(0, class_validator_1.Min)(0),
|
|
31
49
|
__metadata("design:type", Number)
|
|
32
|
-
],
|
|
50
|
+
], ScheduleDto.prototype, "min", void 0);
|
|
33
51
|
__decorate([
|
|
34
52
|
(0, swagger_1.ApiPropertyOptional)({ default: 0, minimum: 0 }),
|
|
53
|
+
(0, class_validator_1.ValidateIf)((dto) => dto.kind === schedule_enum_1.ScheduleKind.INTERVAL),
|
|
35
54
|
(0, class_validator_1.IsOptional)(),
|
|
36
55
|
(0, class_validator_1.IsInt)(),
|
|
37
56
|
(0, class_validator_1.Min)(0),
|
|
38
57
|
__metadata("design:type", Number)
|
|
39
|
-
],
|
|
40
|
-
|
|
58
|
+
], ScheduleDto.prototype, "sec", void 0);
|
|
59
|
+
__decorate([
|
|
60
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
61
|
+
description: 'Required when kind is cron. 5-field or 6-field expression.',
|
|
62
|
+
example: '0 2 * * MON',
|
|
63
|
+
}),
|
|
64
|
+
(0, class_validator_1.ValidateIf)((dto) => dto.kind === schedule_enum_1.ScheduleKind.CRON),
|
|
65
|
+
(0, class_validator_1.IsString)(),
|
|
66
|
+
(0, schedule_validator_1.IsCronExpression)(),
|
|
67
|
+
__metadata("design:type", String)
|
|
68
|
+
], ScheduleDto.prototype, "expression", void 0);
|
|
69
|
+
class AddScheduledTaskDto extends common_payload_dto_1.CommonPayloadDto {
|
|
41
70
|
}
|
|
42
71
|
exports.AddScheduledTaskDto = AddScheduledTaskDto;
|
|
43
72
|
__decorate([
|
|
44
|
-
(0, swagger_1.ApiProperty)({
|
|
73
|
+
(0, swagger_1.ApiProperty)({
|
|
74
|
+
description: 'Must match the identifier of a registered job.',
|
|
75
|
+
example: 'cleanup.expired.tokens',
|
|
76
|
+
}),
|
|
45
77
|
(0, class_validator_1.IsString)(),
|
|
78
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
46
79
|
(0, class_validator_1.MaxLength)(255),
|
|
47
80
|
__metadata("design:type", String)
|
|
48
81
|
], AddScheduledTaskDto.prototype, "identifier", void 0);
|
|
49
82
|
__decorate([
|
|
50
83
|
(0, swagger_1.ApiProperty)({ example: 'Cleanup expired tokens' }),
|
|
51
84
|
(0, class_validator_1.IsString)(),
|
|
85
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
52
86
|
(0, class_validator_1.MaxLength)(255),
|
|
53
87
|
__metadata("design:type", String)
|
|
54
88
|
], AddScheduledTaskDto.prototype, "name", void 0);
|
|
55
89
|
__decorate([
|
|
56
90
|
(0, swagger_1.ApiPropertyOptional)({
|
|
57
|
-
description: '
|
|
58
|
-
example: '2026-
|
|
91
|
+
description: 'First candidate fire time (ISO 8601), and the slot a `once` task uses. Defaults to now.',
|
|
92
|
+
example: '2026-08-01T02:00:00.000Z',
|
|
59
93
|
}),
|
|
60
94
|
(0, class_validator_1.IsOptional)(),
|
|
61
95
|
(0, class_validator_1.IsISO8601)(),
|
|
62
96
|
__metadata("design:type", String)
|
|
63
97
|
], AddScheduledTaskDto.prototype, "start_from", void 0);
|
|
64
98
|
__decorate([
|
|
65
|
-
(0, swagger_1.ApiProperty)({
|
|
99
|
+
(0, swagger_1.ApiProperty)({
|
|
100
|
+
type: ScheduleDto,
|
|
101
|
+
description: 'Changing it re-seats the cursor and discards not-yet-due occurrences.',
|
|
102
|
+
}),
|
|
103
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
66
104
|
(0, class_validator_1.ValidateNested)(),
|
|
67
|
-
(0, class_transformer_1.Type)(() =>
|
|
68
|
-
__metadata("design:type",
|
|
69
|
-
], AddScheduledTaskDto.prototype, "
|
|
105
|
+
(0, class_transformer_1.Type)(() => ScheduleDto),
|
|
106
|
+
__metadata("design:type", ScheduleDto)
|
|
107
|
+
], AddScheduledTaskDto.prototype, "schedule", void 0);
|
|
108
|
+
__decorate([
|
|
109
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
110
|
+
description: 'IANA zone the schedule is evaluated in.',
|
|
111
|
+
default: schedule_enum_1.ScheduleDefault.TIMEZONE,
|
|
112
|
+
example: 'Asia/Kathmandu',
|
|
113
|
+
}),
|
|
114
|
+
(0, class_validator_1.IsOptional)(),
|
|
115
|
+
(0, schedule_validator_1.IsTimezone)(),
|
|
116
|
+
__metadata("design:type", String)
|
|
117
|
+
], AddScheduledTaskDto.prototype, "timezone", void 0);
|
|
118
|
+
__decorate([
|
|
119
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
120
|
+
description: 'Passed to the dispatched job as its payload.',
|
|
121
|
+
example: { batch_size: 500 },
|
|
122
|
+
}),
|
|
123
|
+
(0, class_validator_1.IsOptional)(),
|
|
124
|
+
(0, class_validator_1.IsObject)(),
|
|
125
|
+
__metadata("design:type", Object)
|
|
126
|
+
], AddScheduledTaskDto.prototype, "payload", void 0);
|
|
127
|
+
__decorate([
|
|
128
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
129
|
+
enum: schedule_enum_1.CatchUpPolicy,
|
|
130
|
+
default: schedule_enum_1.CatchUpPolicy.FIRE_ONCE,
|
|
131
|
+
description: 'What happens to fire times missed while the scheduler was down.',
|
|
132
|
+
}),
|
|
133
|
+
(0, class_validator_1.IsOptional)(),
|
|
134
|
+
(0, class_validator_1.IsEnum)(schedule_enum_1.CatchUpPolicy),
|
|
135
|
+
__metadata("design:type", String)
|
|
136
|
+
], AddScheduledTaskDto.prototype, "catch_up_policy", void 0);
|
|
137
|
+
__decorate([
|
|
138
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
139
|
+
default: schedule_enum_1.ScheduleDefault.MAX_CATCHUP,
|
|
140
|
+
minimum: 1,
|
|
141
|
+
description: 'Slots this task may materialise in one pass.',
|
|
142
|
+
}),
|
|
143
|
+
(0, class_validator_1.IsOptional)(),
|
|
144
|
+
(0, class_validator_1.IsInt)(),
|
|
145
|
+
(0, class_validator_1.Min)(1),
|
|
146
|
+
__metadata("design:type", Number)
|
|
147
|
+
], AddScheduledTaskDto.prototype, "max_catchup", void 0);
|
|
148
|
+
__decorate([
|
|
149
|
+
(0, swagger_1.ApiPropertyOptional)({ enum: schedule_enum_1.OverlapPolicy, default: schedule_enum_1.OverlapPolicy.ALLOW }),
|
|
150
|
+
(0, class_validator_1.IsOptional)(),
|
|
151
|
+
(0, class_validator_1.IsEnum)(schedule_enum_1.OverlapPolicy),
|
|
152
|
+
__metadata("design:type", String)
|
|
153
|
+
], AddScheduledTaskDto.prototype, "overlap_policy", void 0);
|
|
154
|
+
__decorate([
|
|
155
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
156
|
+
default: 0,
|
|
157
|
+
minimum: 0,
|
|
158
|
+
description: 'Random spread added to each fire time, in seconds.',
|
|
159
|
+
}),
|
|
160
|
+
(0, class_validator_1.IsOptional)(),
|
|
161
|
+
(0, class_validator_1.IsInt)(),
|
|
162
|
+
(0, class_validator_1.Min)(0),
|
|
163
|
+
__metadata("design:type", Number)
|
|
164
|
+
], AddScheduledTaskDto.prototype, "jitter_sec", void 0);
|
|
70
165
|
__decorate([
|
|
71
166
|
(0, swagger_1.ApiPropertyOptional)({ default: true }),
|
|
72
167
|
(0, class_validator_1.IsOptional)(),
|