feat(quota): implement monthly quota, role-based limits, reset mechanism and cron scheduler
Features & Enhancements: Monthly Quota, Role-Based Resource Limits, Zero-Loss Reset & Cron Scheduler
Summary
This PR introduces enterprise-grade resource quota management, role-based quota templating with automatic user synchronization, zero-data-loss quota reset capabilities, and an automated background job scheduler (Cron) with defense-in-depth permission resolution.
Key Changes
1. Database & Schema Updates (Prisma)
- Added
maxPagesPerMonthLimit(default10,000/1,000),maxJobsPerMonthLimit(default500/100), andquotaResetAt(DateTime?) to bothUserandRolemodels. - Applied PostgreSQL migration
20260909030359_add_role_and_monthly_quota.
2. Resource Quota Calculation & Zero-Loss Reset (auth & crawl-jobs)
-
UTC+7 Timezone Precision: Calculated
startOfDayandstartOfMonthusingAsia/Ho_Chi_Minh. -
Effective Horizon: Quota consumption is evaluated against
effectiveSince = Math.max(startOfDay/startOfMonth, quotaResetAt). -
Zero Data Loss: Resetting a quota updates
quotaResetAtrather than mutating or deleting historical crawl records. - Implemented
POST /api/v1/users/:id/reset-quotaandPOST /api/v1/roles/:id/reset-quotawith audit logging (AUDIT_ACTIONS.USER_QUOTA_RESET,AUDIT_ACTIONS.ROLE_QUOTA_RESET).
3. Role-Based Quota Templates & Auto-Sync (roles)
- Extended
CreateRoleDtoandUpdateRoleDtoto define default quota limits for roles. - Supported
syncUsersQuotaflag inUpdateRoleDtoto bulk update limits for all users assigned to the role.
4. Background Job Scheduler Module (cron)
- Built complete 5-layer scheduler system with BullMQ queue (
cron-scheduler-queue) and worker. - Supports periodic maintenance tasks: log cleanup, expired token purge, orphan asset cleanup, and summary email digests.
- Integrated automatic system permission bootstrapping (
permissionService.ensureSystemPermissions()) andADMINdefault permission inheritance inpermission.middleware.ts.
5. Environment Configuration
- Updated
.envand.env.examplewithUSER_MAX_PAGES_PER_MONTH=1000andUSER_MAX_JOBS_PER_MONTH=100.