Daily SPEAR Refresh Cron
Scheduled background refresh of SPEAR milestone data for non-closed untitled projects
Overview
SPEAR milestone data underpins every predicted-title-date calculation on the platform. Before 3.8 the data was only refreshed when something actively triggered an enrichment (project save, order creation, parcel lookup). Projects that sat idle for weeks kept stale SPEAR data, which meant stale predicted title dates.
Release 3.8 adds a daily cron endpoint that iterates all non-closed untitled projects and dispatches an async SPEAR refresh per project. Default schedule: 2pm server time.
What Changed
New endpoint: GET /api/cron/project/update-untitled-spear
Pulls project rows matching all of:
status.category.tag != 'closed'(project is active)titleStatusIS NULL, ortitleStatus.tag IN ('untitled', 'tba'), orpredictedTitleDate IS NULL
For each match, dispatches an UpdateUntitledSpearData message to the async messenger transport. Accepts ?limit=N to process only the top N for debugging; default is unbounded (processes everything).
Returns JSON with {dispatched: N} so the cron log shows how many projects got queued.
New async message: App\Message\UpdateUntitledSpearData
Simple DTO carrying projectId. Routed to async in messenger.yaml. The handler re-loads the project by id and calls:
ProjectInsightEnrichmentService::enrich($project)- re-fetches parcel insights from dossier-api with the estate-resolved title / street offsets.SpearMilestoneService::syncProjectMilestones($project)- refreshes the raw milestone rows.
Both calls are idempotent. If SPEAR has nothing new, the project is a no-op.
Why async per-project
Running all refreshes in the cron request itself would:
- Tie the HTTP request up for minutes and risk timeouts.
- Block other cron entries that land at the same wall-clock time.
- Serialise what should naturally parallelise across the two messenger workers on fts1.
Dispatching one message per project lets the messenger workers drain the queue at their own pace, and a failure on project X does not poison projects Y + Z.
Cron schedule
On fts1 (root crontab):
0 14 * * * /usr/bin/curl --silent https://platform.ftsonline.com.au/api/cron/project/update-untitled-spear &>/dev/nullDaily at 14:00 server time. The endpoint is idempotent so a re-trigger or overlap is safe.
Related
- Estate-Level Prediction Offsets - the offsets this refresh uses
- Enrichment Guard Rails - the filters that stop stale data from producing bad predictions