KamoCRM

Schedule triggers, job-change trigger, training on join; switch scheduling on

FeatureDocsService
Shipped
November 13, 2026 at 2:17 AM UTC
Author
Kamo
Commit
7f9bd03

Scheduling. DocsService never had @EnableScheduling, so none of its @Scheduled jobs had ever run. Each was checked against live data and made safe for a first run before switching it on: - careers retention sweep: singleton-locked, 200 per night; 0 applications are past retention today. - talent-alert digest (hourly, SENDS EMAIL): singleton-locked, and a digest now only ever offers roles listed in the last 7 days, so a first run (or any run after an outage) can never mail subscribers a backlog. 0 confirmed subscribers today. - talent-alert purge: singleton-locked and now bounded (500 per night); 1 unconfirmed row today. - careers funnel flush: pod-local counters, deliberately unlocked. - the Compliance engine's own private scheduler is GONE: its jobs are ordinary @Scheduled methods now, so nothing runs on two clocks. Scheduler pool 3 threads (configmap). Schedule triggers ("every January", "every 3 months from January"), stored as every:<months>:<startMonth>, are now run by a nightly singleton-locked sweep (04:10). Each round is a row in hr_compliance_schedule_run, claimed with round happens once whatever the pods or restarts do and resumes where it stopped. Per member it reuses ensureAssigned with the round's first day: on file, already sent, in review, or sent this round (even if since voided) is left alone. Only the org's active human team members are read, a page at a time; never leads. A schedule SAVED mid-round starts with its next round (the round under way is recorded as a baseline), so adding one never mails anybody that night. The editor's save refuses a schedule the sweep cannot run. member.job_changed: heard on security.member.job_changed.> (queue group docs-compliance). Only requirements that carry the trigger are considered, and only when the change brings the member NEWLY into the audience (judged from the previous department / job title in the event) — an everyone audience, or one that already reached them, is not re-sent. TrainingCourse.autoAssignOnJoin is real: on member.activated, ONE assignment row for that member per ACTIVE "assign on join" course whose saved audience includes them and that they have never held. HR's whole-audience Assign is never called, so nobody else is touched. Also: - An executed copy older than the requirement's validity no longer reads as "on file" (the record flipped SATISFIED/EXPIRED and hid a renewal), and the record's assignedAt follows the current assignment, not only the first. - The W-9 library preset row is brought in line with the bundled one (payout setup ONLY, owner 2026-11-12). The stored row still carried commission.credited, which every NEW org would have adopted. No edition bump, so no org is offered anything.

All changes

Like what you see shipping?

All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.

Start Free ForeverView Pricing