INSURANCE_FEATURES_SPEC §1. The office printed and mailed renewal letters from the legacy CONTROL <ramo> RENEW[2/3] paper log; 91% of policyholders have an email on file, so send the notice instead and keep the paper log as the fallback. A daily cron (06:00 America/Tijuana) sweeps three generations off policyTo — 30 and 15 days before expiry, 7 days after — sends each through SES, and upserts RenewalNotice by [policyId, generation] so a policy is never notified twice for the same milestone. RenewalNotice now records providerMessageId, so a later bounce or complaint webhook can be traced back to the row that sent it. - customers.emailOptOut excludes a customer from every sweep; editable from the customer form - scheduled_job_states holds the sweep's lock and last successful run; the window is widened to cover days the job did not run, so a weekend outage does not silently drop a generation - SES unconfigured is not an error outside production — messages are logged and skipped, so dev and CI never send - /renovaciones (renewal:send, MANAGER+) lists what is pending per generation, runs the sweep by hand, and marks a notice sent by mail for the customers with no email - POST /policies/:id/renewal-notices records that manual mark - the aviso-renovacion report and the emails now share one projection (reports/renewal-letter.ts) instead of two copies of the mapping
50 lines
1.3 KiB
JSON
50 lines
1.3 KiB
JSON
{
|
|
"name": "@jorgecuadros/api",
|
|
"version": "1.0.6",
|
|
"private": true,
|
|
"scripts": {
|
|
"build": "nest build",
|
|
"start": "nest start",
|
|
"start:dev": "nest start --watch",
|
|
"start:prod": "node dist/main",
|
|
"lint": "eslint \"src/**/*.ts\"",
|
|
"test": "jest"
|
|
},
|
|
"dependencies": {
|
|
"@aws-sdk/client-s3": "^3.665.0",
|
|
"@aws-sdk/client-sesv2": "^3.1101.0",
|
|
"@jorgecuadros/database": "workspace:*",
|
|
"@nestjs/common": "^10.4.4",
|
|
"@nestjs/config": "^3.3.0",
|
|
"@nestjs/core": "^10.4.4",
|
|
"@nestjs/passport": "^10.0.3",
|
|
"@nestjs/platform-express": "^10.4.4",
|
|
"@nestjs/schedule": "^4.1.2",
|
|
"argon2": "^0.41.1",
|
|
"class-transformer": "^0.5.1",
|
|
"class-validator": "^0.14.1",
|
|
"exceljs": "^4.4.0",
|
|
"express-session": "^1.18.0",
|
|
"passport": "^0.7.0",
|
|
"passport-local": "^1.0.0",
|
|
"pdfkit": "^0.15.1",
|
|
"reflect-metadata": "^0.2.2",
|
|
"rxjs": "^7.8.1"
|
|
},
|
|
"devDependencies": {
|
|
"@nestjs/cli": "^10.4.5",
|
|
"@nestjs/testing": "^10.4.4",
|
|
"@types/express": "^4.17.21",
|
|
"@types/express-session": "^1.18.0",
|
|
"@types/jest": "^29.5.13",
|
|
"@types/node": "^20.16.11",
|
|
"@types/passport": "^1.0.17",
|
|
"@types/passport-local": "^1.0.38",
|
|
"@types/pdfkit": "^0.13.5",
|
|
"jest": "^29.7.0",
|
|
"ts-jest": "^29.2.5",
|
|
"ts-node": "^10.9.2",
|
|
"typescript": "^5.6.3"
|
|
}
|
|
}
|