{"_id":"@edvisor/scheduler-service-sdk","_rev":"3-76441d81750ea386cf20c35aa7dcc844","name":"@edvisor/scheduler-service-sdk","dist-tags":{"latest":"0.0.4"},"versions":{"0.0.2":{"name":"@edvisor/scheduler-service-sdk","version":"0.0.2","keywords":["scheduler","aws","eventbridge","nestjs","sdk","cron"],"author":{"name":"Edvisor.io"},"license":"UNLICENSED","_id":"@edvisor/scheduler-service-sdk@0.0.2","maintainers":[{"name":"edvisorio","email":"devops+npm@edvisor.io"},{"name":"stringbeans_in_jeans","email":"john@edvisor.io"},{"name":"rafael.dias","email":"rafael.silva@edvisor.io"}],"dist":{"shasum":"024bf132549bf1168a69453ac01c13864fa9e548","tarball":"https://registry.npmjs.org/@edvisor/scheduler-service-sdk/-/scheduler-service-sdk-0.0.2.tgz","fileCount":44,"integrity":"sha512-HeY0/6Sv02ba4GzS1Q24m+TpS6GhAh5FlGGJnPDACH3RQEh7aQfKm/m5SPhWtGedUm2mngIr2ve5uxEGuuerTg==","signatures":[{"sig":"MEUCIQC6RxqNYYD1c0QwdmmKdJdFUjOlHLTBDxZzMxsP12QQoQIgffm0t5qbeK0V7Ks16vYuiRKCH10q2goW23p2sUzkrOA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":68865},"jest":{"rootDir":"src","testRegex":".*\\.spec\\.ts$","transform":{"^.+\\.(t|j)s$":"ts-jest"},"testEnvironment":"node","coverageDirectory":"../coverage","collectCoverageFrom":["**/*.(t|j)s"],"moduleFileExtensions":["js","json","ts"]},"main":"sdk-dist/sdk-entry.js","types":"sdk-dist/sdk-entry.d.ts","exports":{".":{"types":"./sdk-dist/sdk-entry.d.ts","import":"./sdk-dist/sdk-entry.js","require":"./sdk-dist/sdk-entry.js"}},"gitHead":"e47b723942bc62d9f8cf70d9f71a5abb2d0b4ff2","scripts":{"lint":"eslint \"{src,apps,libs,test}/**/*.ts\" --fix","test":"jest","build":"nest build","start":"nest start","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","test:cov":"jest --coverage","test:e2e":"jest --config ./test/jest-e2e.json","build:sdk":"tsc -p tsconfig.sdk.json","start:dev":"nest start --watch","start:prod":"node dist/main","test:debug":"node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand","test:watch":"jest --watch","start:debug":"nest start --debug --watch"},"_npmUser":{"name":"edvisorio","actor":{"name":"edvisorio","type":"user","email":"devops+npm@edvisor.io"},"email":"devops+npm@edvisor.io"},"_npmVersion":"10.2.3","description":"HTTP client SDK for the Edvisor Scheduler Service REST API","directories":{},"_nodeVersion":"20.10.0","dependencies":{"rxjs":"^7.8.1","axios":"^1.7.9","dayjs":"^1.11.13","cron-parser":"^5.3.0","@nestjs/core":"^11.0.1","@nestjs/common":"^11.0.1","@nestjs/config":"^4.0.2","class-validator":"^0.14.2","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1","@aws-sdk/client-sqs":"^3.835.0","@nestjs/platform-express":"^11.0.1","@aws-sdk/client-scheduler":"^3.835.0"},"_hasShrinkwrap":false,"devDependencies":{"zx":"^8.6.0","jest":"^29.7.0","eslint":"^9.18.0","globals":"^16.0.0","ts-jest":"^29.2.5","ts-node":"^10.9.2","@swc/cli":"^0.6.0","prettier":"^3.4.2","@swc/core":"^1.10.7","supertest":"^7.0.0","ts-loader":"^9.5.2","@eslint/js":"^9.18.0","typescript":"^5.7.3","@nestjs/cli":"^11.0.0","@types/jest":"^29.5.14","@types/node":"^22.15.33","@types/express":"^5.0.0","tsconfig-paths":"^4.2.0","@nestjs/testing":"^11.0.1","@eslint/eslintrc":"^3.2.0","@types/supertest":"^6.0.2","typescript-eslint":"^8.20.0","@nestjs/schematics":"^11.0.0","source-map-support":"^0.5.21","eslint-config-prettier":"^10.0.1","eslint-plugin-prettier":"^5.2.2"},"_npmOperationalInternal":{"tmp":"tmp/scheduler-service-sdk_0.0.2_1751322792672_0.40065661590536705","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@edvisor/scheduler-service-sdk","version":"0.0.3","keywords":["scheduler","aws","eventbridge","nestjs","sdk","cron"],"author":{"name":"Edvisor.io"},"license":"UNLICENSED","_id":"@edvisor/scheduler-service-sdk@0.0.3","maintainers":[{"name":"edvisorio","email":"devops+npm@edvisor.io"},{"name":"stringbeans_in_jeans","email":"john@edvisor.io"},{"name":"rafael.dias","email":"rafael.silva@edvisor.io"}],"dist":{"shasum":"45e4587a48c3f6fb276257b16762ca01c90077f2","tarball":"https://registry.npmjs.org/@edvisor/scheduler-service-sdk/-/scheduler-service-sdk-0.0.3.tgz","fileCount":44,"integrity":"sha512-G9vFPfg6mSNfKLz/++fpHv9NcghN7Cz5eEsUyZN7Ppc5Hv60prAIs5PWGeiymckmv7nHVV7Mpq9KLeaInD+nAg==","signatures":[{"sig":"MEUCIDhmMIdL5b29Pqb9QnpFluBKgLCXDzR+OyKIiZVmveDlAiEAjBkwNB3DS2dF6P3n38un0kJuoCs+9aQmW5ENeVVwI7w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":69550},"jest":{"rootDir":"src","testRegex":".*\\.spec\\.ts$","transform":{"^.+\\.(t|j)s$":"ts-jest"},"testEnvironment":"node","coverageDirectory":"../coverage","collectCoverageFrom":["**/*.(t|j)s"],"moduleFileExtensions":["js","json","ts"]},"main":"sdk-dist/sdk-entry.js","types":"sdk-dist/sdk-entry.d.ts","exports":{".":{"types":"./sdk-dist/sdk-entry.d.ts","import":"./sdk-dist/sdk-entry.js","require":"./sdk-dist/sdk-entry.js"}},"gitHead":"5115f12a471e673fff40205026a9b90c2041e3d0","scripts":{"lint":"eslint \"{src,apps,libs,test}/**/*.ts\" --fix","test":"jest","build":"nest build","start":"nest start","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","release":"release-it","sst:dev":"sst dev","test:cov":"jest --coverage","test:e2e":"jest --config ./test/jest-e2e.json","build:sdk":"tsc -p tsconfig.sdk.json","start:dev":"nest start --watch","release:ci":"release-it --ci --no-git.push --no-git.commit --no-git.tag --no-github.release","sst:deploy":"sst deploy","start:prod":"node dist/main","test:debug":"node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand","test:watch":"jest --watch","start:debug":"nest start --debug --watch"},"_npmUser":{"name":"edvisorio","actor":{"name":"edvisorio","type":"user","email":"devops+npm@edvisor.io"},"email":"devops+npm@edvisor.io"},"_npmVersion":"10.8.2","description":"HTTP client SDK for the Edvisor Scheduler Service REST API","directories":{},"_nodeVersion":"20.18.0","dependencies":{"sst":"3.17.8","rxjs":"^7.8.1","axios":"^1.7.9","dayjs":"^1.11.13","aws-lambda":"^1.0.7","cron-parser":"^5.3.0","@nestjs/core":"^11.0.1","@nestjs/common":"^11.0.1","@nestjs/config":"^4.0.2","class-validator":"^0.14.2","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1","@aws-sdk/client-sqs":"^3.835.0","@nestjs/platform-express":"^11.0.1","@aws-sdk/client-scheduler":"^3.835.0","@codegenie/serverless-express":"^4.16.0"},"_hasShrinkwrap":false,"devDependencies":{"zx":"^8.6.0","sst":"^3.17.8","jest":"^29.7.0","eslint":"^9.18.0","globals":"^16.0.0","ts-jest":"^29.2.5","ts-node":"^10.9.2","@swc/cli":"^0.6.0","prettier":"^3.4.2","@swc/core":"^1.10.7","supertest":"^7.0.0","ts-loader":"^9.5.2","@eslint/js":"^9.18.0","release-it":"^19.0.3","typescript":"^5.7.3","@nestjs/cli":"^11.0.0","@types/jest":"^29.5.14","@types/node":"^22.15.33","@types/express":"^5.0.0","tsconfig-paths":"^4.2.0","@nestjs/testing":"^11.0.1","@eslint/eslintrc":"^3.2.0","@types/supertest":"^6.0.2","@types/aws-lambda":"8.10.150","typescript-eslint":"^8.20.0","@nestjs/schematics":"^11.0.0","source-map-support":"^0.5.21","eslint-config-prettier":"^10.0.1","eslint-plugin-prettier":"^5.2.2","@anatine/esbuild-decorators":"^0.2.19","@release-it/conventional-changelog":"^10.0.1"},"_npmOperationalInternal":{"tmp":"tmp/scheduler-service-sdk_0.0.3_1751478887953_0.7465043394743034","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@edvisor/scheduler-service-sdk","version":"0.0.4","description":"HTTP client SDK for the Edvisor Scheduler Service REST API","author":{"name":"Edvisor.io"},"license":"UNLICENSED","main":"sdk-dist/sdk-entry.js","types":"sdk-dist/sdk-entry.d.ts","exports":{".":{"import":"./sdk-dist/sdk-entry.js","require":"./sdk-dist/sdk-entry.js","types":"./sdk-dist/sdk-entry.d.ts"}},"keywords":["scheduler","aws","eventbridge","nestjs","sdk","cron"],"scripts":{"build":"nest build","build:sdk":"tsc -p tsconfig.sdk.json","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","lint":"eslint \"{src,apps,libs,test}/**/*.ts\" --fix","release":"release-it","release:ci":"release-it --ci --no-git.push --no-github.release","sst:deploy":"sst deploy","sst:dev":"sst dev","start":"nest start","start:debug":"nest start --debug --watch","start:dev":"nest start --watch","start:prod":"node dist/main","test":"jest","test:cov":"jest --coverage","test:debug":"node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand","test:e2e":"jest --config ./test/jest-e2e.json","test:watch":"jest --watch"},"dependencies":{"@aws-sdk/client-scheduler":"^3.835.0","@aws-sdk/client-sqs":"^3.835.0","@codegenie/serverless-express":"^4.16.0","@nestjs/common":"^11.0.1","@nestjs/config":"^4.0.2","@nestjs/core":"^11.0.1","@nestjs/platform-express":"^11.0.1","aws-lambda":"^1.0.7","axios":"^1.7.9","class-transformer":"^0.5.1","class-validator":"^0.14.2","cron-parser":"^5.3.0","dayjs":"^1.11.13","reflect-metadata":"^0.2.2","rxjs":"^7.8.1"},"devDependencies":{"@anatine/esbuild-decorators":"^0.2.19","@eslint/eslintrc":"^3.2.0","@eslint/js":"^9.18.0","@nestjs/cli":"^11.0.0","@nestjs/schematics":"^11.0.0","@nestjs/testing":"^11.0.1","@release-it/conventional-changelog":"^10.0.1","@swc/cli":"^0.6.0","@swc/core":"^1.10.7","@types/aws-lambda":"8.10.150","@types/express":"^5.0.0","@types/jest":"^29.5.14","@types/node":"^22.15.33","@types/supertest":"^6.0.2","eslint":"^9.18.0","eslint-config-prettier":"^10.0.1","eslint-plugin-prettier":"^5.2.2","globals":"^16.0.0","jest":"^29.7.0","prettier":"^3.4.2","release-it":"^19.0.3","source-map-support":"^0.5.21","sst":"^3.17.8","supertest":"^7.0.0","ts-jest":"^29.2.5","ts-loader":"^9.5.2","ts-node":"^10.9.2","tsconfig-paths":"^4.2.0","typescript":"^5.7.3","typescript-eslint":"^8.20.0","zx":"^8.6.0"},"jest":{"collectCoverageFrom":["**/*.(t|j)s"],"coverageDirectory":"../coverage","moduleFileExtensions":["js","json","ts"],"rootDir":"src","testEnvironment":"node","testRegex":".*\\.spec\\.ts$","transform":{"^.+\\.(t|j)s$":"ts-jest"}},"_id":"@edvisor/scheduler-service-sdk@0.0.4","gitHead":"b239613089471d1362171fac6329ca9289a079d3","_nodeVersion":"20.18.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-3cndOCIT9KLlIGkRN4PLawrYHCXNYBGxDf71LcD27H/R7O1iYlg31SlAfLlJLqU7QP3iMBcaoYDbFV7g6lREyA==","shasum":"1ee4fa0bd0bd5faedde5dba7fdf3f0ed80f529ad","tarball":"https://registry.npmjs.org/@edvisor/scheduler-service-sdk/-/scheduler-service-sdk-0.0.4.tgz","fileCount":44,"unpackedSize":69500,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCID7oZM+E1DtArK/oy/Pp3NoJAJGXGg9W8k4pUVG+y3oDAiEA5uA20Axp605f+7w7Bb8jWthlNtQWrmHtbhN6C5/LV5o="}]},"_npmUser":{"name":"edvisorio","email":"devops+npm@edvisor.io","actor":{"name":"edvisorio","email":"devops+npm@edvisor.io","type":"user"}},"directories":{},"maintainers":[{"name":"edvisorio","email":"devops+npm@edvisor.io"},{"name":"stringbeans_in_jeans","email":"john@edvisor.io"},{"name":"rafael.dias","email":"rafael.silva@edvisor.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/scheduler-service-sdk_0.0.4_1751479902659_0.7178085859518843"},"_hasShrinkwrap":false}},"time":{"created":"2025-06-30T22:33:12.540Z","modified":"2025-07-02T18:11:43.106Z","0.0.2":"2025-06-30T22:33:12.849Z","0.0.3":"2025-07-02T17:54:48.149Z","0.0.4":"2025-07-02T18:11:42.871Z"},"author":{"name":"Edvisor.io"},"license":"UNLICENSED","keywords":["scheduler","aws","eventbridge","nestjs","sdk","cron"],"description":"HTTP client SDK for the Edvisor Scheduler Service REST API","maintainers":[{"name":"edvisorio","email":"devops+npm@edvisor.io"},{"name":"stringbeans_in_jeans","email":"john@edvisor.io"},{"name":"rafael.dias","email":"rafael.silva@edvisor.io"}],"readme":"# Scheduler Service\n\nA NestJS-based microservice that handles task scheduling through AWS EventBridge Scheduler, with automatic message delivery to SQS queues when schedules trigger.\n\n## Overview\n\nThis service provides a RESTful API for managing scheduled tasks using AWS EventBridge Scheduler. It allows you to:\n\n- Create and manage schedule groups with dedicated SQS queues\n- Create schedules with cron or rate expressions\n- Automatically route messages to group-specific SQS queues when schedules trigger\n- Update and delete existing schedules\n- List schedules with pagination support\n- Support multiple SQS queues with flexible group-to-queue mapping\n\n## Prerequisites\n\n- Node.js 18+\n- AWS Account with appropriate permissions\n- AWS EventBridge Scheduler access\n- Multiple SQS queues created (one per schedule group)\n- IAM role for EventBridge to send messages to SQS\n\n## Environment Configuration\n\nCreate a `.env` file in the root directory:\n\n```bash\n# AWS Configuration\nAWS_REGION=us-east-1\nEVENTBRIDGE_ROLE_ARN=arn:aws:iam::123456789012:role/EventBridgeSchedulerRole\n\n# AWS Credentials (choose one method)\nAWS_ACCESS_KEY_ID=your-access-key-id\nAWS_SECRET_ACCESS_KEY=your-secret-access-key\n\n# SQS Queue Mappings (format: GROUP_NAME:QUEUE_URL,GROUP_NAME2:QUEUE_URL2)\nSQS_QUEUE_MAPPINGS=notifications:https://sqs.us-east-1.amazonaws.com/123456789012/notifications-queue,reports:https://sqs.us-east-1.amazonaws.com/123456789012/reports-queue,tasks:https://sqs.us-east-1.amazonaws.com/123456789012/tasks-queue\n\n# Application\nPORT=3000\n```\n\n## AWS Credential Configuration\n\nThe service supports multiple methods for AWS authentication:\n\n### Method 1: Environment Variables (Development/Testing)\nSet credentials directly in your `.env` file:\n```bash\nAWS_ACCESS_KEY_ID=your-access-key-id\nAWS_SECRET_ACCESS_KEY=your-secret-access-key\n```\n\n### Method 2: AWS Credentials File (Development)\nUse AWS CLI profiles instead of environment variables:\n```bash\nAWS_PROFILE=your-profile-name\n```\nThis uses credentials from `~/.aws/credentials`:\n```ini\n[your-profile-name]\naws_access_key_id = your-access-key-id\naws_secret_access_key = your-secret-access-key\n```\n\n### Method 3: IAM Roles (Recommended for Production)\nWhen running on AWS infrastructure (EC2, ECS, Lambda), no additional configuration is needed. The service will automatically use the IAM role attached to the compute resource.\n\n### Method 4: EC2 Instance Metadata\nWhen running on EC2 instances with attached IAM roles, credentials are automatically retrieved from the instance metadata service.\n\n## Installation\n\n```bash\n$ npm install\n```\n\n## Running the application\n\n```bash\n# development\n$ npm run start:dev\n\n# production mode\n$ npm run start:prod\n```\n\n## Testing\n\n```bash\n# unit tests\n$ npm run test\n\n# test coverage\n$ npm run test:cov\n```\n\n## API Endpoints\n\n### Create Schedule\n```\nPOST /groups/{groupName}/schedules\n```\n\nExample request:\n```json\n{\n  \"name\": \"daily-report\",\n  \"expression\": \"cron(0 9 * * ? *)\",\n  \"payload\": {\n    \"taskType\": \"generate-report\",\n    \"reportId\": \"123\"\n  },\n  \"startDate\": \"2024-01-01T00:00:00Z\",\n  \"endDate\": \"2024-12-31T23:59:59Z\"\n}\n```\n\n### Get Schedule\n```\nGET /groups/{groupName}/schedules/{scheduleName}\n```\n\n### Update Schedule\n```\nPATCH /groups/{groupName}/schedules/{scheduleName}\n```\n\n### Delete Schedule\n```\nDELETE /groups/{groupName}/schedules/{scheduleName}\n```\n\n### List Schedules\n```\nGET /groups/{groupName}/schedules?nextToken={token}\n```\n\n### Delete Schedule Group\n```\nDELETE /groups/{groupName}\n```\n\n## SQS Queue Mapping\n\nEach schedule group can be mapped to a specific SQS queue. When a schedule triggers, the message will be sent to the queue associated with that group.\n\n### Configuration\n\nQueue mappings are configured via the `SQS_QUEUE_MAPPINGS` environment variable:\n\n```bash\nSQS_QUEUE_MAPPINGS=group1:queue-url-1,group2:queue-url-2,group3:queue-url-3\n```\n\n### Error Handling\n\n- If a group has no specific queue mapping, schedule creation will fail with a 400 error\n\n### Examples\n\n```bash\n# Three groups with specific queues\nSQS_QUEUE_MAPPINGS=notifications:https://sqs.us-east-1.amazonaws.com/123456789012/notifications-queue,reports:https://sqs.us-east-1.amazonaws.com/123456789012/reports-queue,tasks:https://sqs.us-east-1.amazonaws.com/123456789012/tasks-queue\n\n```\n\n## Schedule Expression Formats\n\n### Rate Expressions\n- `rate(5 minutes)` - Every 5 minutes\n- `rate(1 hour)` - Every hour\n- `rate(1 day)` - Every day\n\n### Cron Expressions\n- `cron(0 10 * * ? *)` - Every day at 10:00 AM UTC\n- `cron(0 18 ? * MON-FRI *)` - Every weekday at 6:00 PM UTC\n- `cron(0 8 1 * ? *)` - First day of every month at 8:00 AM UTC\n\n## AWS IAM Requirements\n\nThe EventBridge role needs the following permissions:\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"sqs:SendMessage\"\n      ],\n      \"Resource\": \"arn:aws:sqs:*:*:*\"\n    }\n  ]\n}\n```\n\nThe application needs these AWS permissions:\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"scheduler:CreateSchedule\",\n        \"scheduler:UpdateSchedule\",\n        \"scheduler:DeleteSchedule\",\n        \"scheduler:GetSchedule\",\n        \"scheduler:ListSchedules\",\n        \"scheduler:CreateScheduleGroup\",\n        \"scheduler:DeleteScheduleGroup\",\n        \"iam:PassRole\"\n      ],\n      \"Resource\": \"*\"\n    }\n  ]\n}\n```\n\n## Architecture\n\nThe service follows a clean architecture pattern:\n\n- **Controllers** - Handle HTTP requests and responses\n- **Services** - Contain business logic\n- **AWS Services** - Handle AWS SDK interactions\n- **DTOs** - Data validation and transformation\n\n## Error Handling\n\nThe service provides proper error responses:\n\n- `400` - Bad Request (invalid parameters)\n- `404` - Not Found (schedule or group doesn't exist)\n- `409` - Conflict (schedule name already exists)\n- `500` - Internal Server Error\n\n## License\n\nThis project is [MIT licensed](LICENSE).\n","readmeFilename":"README.md"}