Conversation
* feat(COMPT-75): define typed scheduled job contracts and IScheduler port - Add ScheduledJob type: name, handler, and one of cron | interval | timeout - Add IScheduler interface: schedule, unschedule, reschedule, list - Add ScheduledJobStatus type: name, cron, lastRun, nextRun, isRunning - Add DuplicateJobError thrown when registering a duplicate job name - Enforce cron/interval/timeout mutual exclusivity via discriminated union - Add CronExpression named constants for human-readable schedules - Add cron fluent builder: dailyAt, weeklyOn, monthlyOn, every().minutes() - Update tsconfig.build.json: CommonJS output, Task 1 files only - Update package.json: name @ciscode/scheduler-kit, version 0.0.0 * test(COMPT-75): add unit tests for CronExpression and cron builder * feat(COMPT-75): add ScheduledJobStatus type and status/listStatus methods - Add ScheduledJobStatus type: name, cron, lastRun, nextRun, isRunning - Add status(name) and listStatus() to IScheduler interface and SchedulerService - Track lastRun timestamp after each execution - Store cronJob reference for nextRun via cronJob.nextDate() - Export ScheduledJobStatus from public API - Fix lint: no-misused-promises, no-floating-promises, prettier formatting * style(COMPT-75): format all files with prettier --------- Co-authored-by: saad moumou <saad.moumou.coder@gmail.com>
* feat(COMPT-76): NestJS SchedulerModule and SchedulerService integration - SchedulerModule.register() and registerAsync() dynamic module factories - SchedulerService: schedule(), reschedule(), unschedule(), list(), status(), listStatus() - @Cron, @interval, @timeout decorators with optional job name - MetadataScanner auto-discovers decorated provider methods on onModuleInit - DuplicateJobError guard against double registration - IScheduler interface and ScheduledJobStatus type - CronExpression constants and cron fluent builder - Full unit test coverage across module, service and decorators * test(COMPT-76): add unit tests for CronExpression and cron builder --------- Co-authored-by: saad moumou <saad.moumou.coder@gmail.com>
* chore(COMPT-77): scope index.ts and tsconfig.build.json to COMPT-77 files only * test(COMPT-77): add tests for status, listStatus, cron jobs and default onJobError * chore(COMPT-77): restore index.ts and tsconfig.build.json to develop baseline --------- Co-authored-by: saad moumou <saad.moumou.coder@gmail.com>
#7) * test(COMPT-78): full coverage with Jest fake timers for all scheduling behaviors - jest.useFakeTimers() for all time-based tests — no real waiting - @interval: fires every N ms, stops after unschedule, does not fire before interval - @timeout: fires exactly once, removes itself from registry, does not fire early - schedule(): job added and fires on tick - unschedule(): timer cleared, handler not called after removal - reschedule(): new schedule applied atomically, old timer cancelled - Job error: caught via onJobError, scheduler continues — other jobs unaffected - Concurrent guard: second execution skipped when first still running (isRunning lock) - status() / listStatus(): reflect isRunning and lastRun correctly - @Cron: registered and unscheduled without throwing - Default onJobError: delegates to Logger.error - Coverage: 98.63% statements, 98.11% branches, 95.34% functions (threshold 85%) * fix(COMPT-78): resolve SonarCloud S1186 and S4524 issues - cron-builder.ts: parseInt -> Number.parseInt (Sonar S4524 x3) - scheduler.decorators.spec.ts: add comments to empty stub methods (Sonar S1186 x6) - scheduler.module.spec.ts: add comments to empty stub methods and class (Sonar S1186 x6) --------- Co-authored-by: saad moumou <saad.moumou.coder@gmail.com>
…et (#8) - package.json: 0.0.0 -> 0.1.0 - README: full documentation (decorators, dynamic API, concurrency guard, error handling, async config, cron helpers, API reference) - .changeset/scheduler-kit-v0-1-0.md: minor bump for initial feature release Co-authored-by: saad moumou <saad.moumou.coder@gmail.com>
* release(COMPT-79): bump version to 0.1.0, rewrite README, add changeset - package.json: 0.0.0 -> 0.1.0 - README: full documentation (decorators, dynamic API, concurrency guard, error handling, async config, cron helpers, API reference) - .changeset/scheduler-kit-v0-1-0.md: minor bump for initial feature release * fix(COMPT-79): add sonar-project.properties to fix SonarCloud quality gate - sonar.exclusions: exclude spec files from source analysis - sonar.tests + sonar.test.inclusions: declare spec files as test code - fixes 31.9% coverage on new code and 4.8% duplication failures --------- Co-authored-by: saad moumou <saad.moumou.coder@gmail.com>
|
There was a problem hiding this comment.
Pull request overview
This PR repurposes the template package into @ciscode/scheduler-kit, introducing a NestJS scheduling module/service with decorator-based job registration, runtime job control, and cron helper utilities, along with updated build/lint/CI metadata for publishing and code quality scanning.
Changes:
- Added
SchedulerService+SchedulerModulewith@Cron/@Interval/@Timeoutdecorators, job registry, concurrency guard, and status introspection. - Added cron helper exports (
CronExpression,cronbuilder) and aDuplicateJobError, with accompanying unit tests. - Updated package/CI/tooling configuration (tsconfig build inputs, ESLint config, Husky hooks, workflows, Sonar config, README, package metadata).
Reviewed changes
Copilot reviewed 2 out of 4 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.eslint.json | Expands ESLint TS project include patterns to cover .mjs. |
| tsconfig.build.json | Adjusts build output/module settings and narrows root include entries. |
| src/services/scheduler.service.ts | Implements in-memory scheduler with cron/interval/timeout support + concurrency guard + status APIs. |
| src/services/scheduler.service.spec.ts | Adds unit tests for scheduling APIs, concurrency guard, and error handling. |
| src/scheduler.module.ts | Adds dynamic Nest module that discovers decorated provider methods and registers jobs. |
| src/scheduler.module.spec.ts | Tests module discovery behavior and dynamic module factories. |
| src/interfaces/scheduler.interface.ts | Defines discriminated-union job timing types and scheduler contract/status types. |
| src/index.ts | Replaces template exports with scheduler-kit public API exports. |
| src/errors/duplicate-job.error.ts | Adds a public error type for duplicate job registration. |
| src/errors/duplicate-job.error.spec.ts | Tests DuplicateJobError. |
| src/decorators/scheduler.decorators.ts | Adds method decorators and metadata key/types for job discovery. |
| src/decorators/scheduler.decorators.spec.ts | Tests decorator metadata behavior. |
| src/cron-expression.ts | Adds named cron expression constants. |
| src/cron-expression.spec.ts | Tests cron expression constants. |
| src/cron-builder.ts | Adds fluent cron expression builder helpers. |
| src/cron-builder.spec.ts | Tests cron builder outputs and time parsing. |
| sonar-project.properties | Adds Sonar project configuration (sources/tests/coverage paths). |
| README.md | Updates documentation from template to scheduler-kit usage and API reference. |
| package.json | Renames/reversions package, adjusts peers/devDeps, and updates scripts for build/verify/release. |
| package-lock.json | Updates lockfile for renamed package and dependency graph changes. |
| lint-staged.config.js | Switches lint-staged config to CommonJS export. |
| eslint.config.mjs | Updates ESLint configuration (ignores + TypeScript project reference + rules). |
| eslint.config.js | Removes prior ESLint config file. |
| .husky/pre-push | Updates pre-push hook commands (but removes Husky bootstrap). |
| .github/workflows/release-check.yml | Enables PR checks against master and updates environment/config formatting. |
| .github/workflows/publish.yml | Enables publish workflow on pushes to master and updates formatting. |
| .github/dependabot.yml | Normalizes quoting/formatting. |
| .changeset/scheduler-kit-v0-1-0.md | Adds a changeset describing the initial scheduler-kit release. |
| "peerDependencies": { | ||
| "@nestjs/common": "^10 || ^11", | ||
| "@nestjs/core": "^10 || ^11", | ||
| "@nestjs/schedule": "^4 || ^5", | ||
| "reflect-metadata": "^0.2.2", | ||
| "rxjs": "^7" | ||
| }, | ||
| "devDependencies": { | ||
| "@changesets/cli": "^2.30.0", | ||
| "@eslint/js": "^10.0.1", | ||
| "@nestjs/common": "^11.1.18", | ||
| "@nestjs/core": "^11.1.18", | ||
| "@nestjs/mapped-types": "^2.1.1", | ||
| "@nestjs/platform-express": "^11.1.18", | ||
| "@changesets/cli": "^2.27.7", | ||
| "@eslint/js": "^9.18.0", | ||
| "@nestjs/common": "^10.4.0", | ||
| "@nestjs/core": "^10.4.0", | ||
| "@nestjs/mapped-types": "^2.0.0", | ||
| "@nestjs/platform-express": "^10.4.0", | ||
| "@nestjs/schedule": "^6.1.1", | ||
| "@nestjs/testing": "^11.1.18", | ||
| "@types/jest": "^30.0.0", | ||
| "@types/node": "^25.6.0", | ||
| "@nestjs/testing": "^10.4.0", | ||
| "@types/jest": "^29.5.14", | ||
| "@types/node": "^22.10.7", | ||
| "cron": "^4.4.0", | ||
| "eslint": "^10.2.0", | ||
| "eslint": "^9.18.0", | ||
| "eslint-config-prettier": "^10.1.8", |
There was a problem hiding this comment.
SchedulerService imports CronJob from the cron package at runtime, but cron is only listed under devDependencies. This can break consumers (especially with pnpm/Yarn PnP) because transitive deps from a peer dependency are not guaranteed to be resolvable. Add cron as a runtime dependency (or a direct peerDependency) so it’s always available when the library is installed.
| "peerDependencies": { | ||
| "@nestjs/common": "^10 || ^11", | ||
| "@nestjs/core": "^10 || ^11", | ||
| "@nestjs/schedule": "^4 || ^5", | ||
| "reflect-metadata": "^0.2.2", | ||
| "rxjs": "^7" | ||
| }, | ||
| "devDependencies": { | ||
| "@changesets/cli": "^2.30.0", | ||
| "@eslint/js": "^10.0.1", | ||
| "@nestjs/common": "^11.1.18", | ||
| "@nestjs/core": "^11.1.18", | ||
| "@nestjs/mapped-types": "^2.1.1", | ||
| "@nestjs/platform-express": "^11.1.18", | ||
| "@changesets/cli": "^2.27.7", | ||
| "@eslint/js": "^9.18.0", | ||
| "@nestjs/common": "^10.4.0", | ||
| "@nestjs/core": "^10.4.0", | ||
| "@nestjs/mapped-types": "^2.0.0", | ||
| "@nestjs/platform-express": "^10.4.0", | ||
| "@nestjs/schedule": "^6.1.1", | ||
| "@nestjs/testing": "^11.1.18", | ||
| "@types/jest": "^30.0.0", | ||
| "@types/node": "^25.6.0", | ||
| "@nestjs/testing": "^10.4.0", |
There was a problem hiding this comment.
@nestjs/schedule is declared as a peer dependency with range ^4 || ^5, but the dev dependency uses ^6.1.1. This mismatch will generate peer warnings and can mask compatibility issues. Align the peer range with the version you test against (or downgrade the dev dependency to a supported peer range).



Summary
Why
Checklist
npm run lintpassesnpm run typecheckpassesnpm testpassesnpm run buildpassesnpx changeset) if this affects consumersNotes