Silent Project Status Revert - Fixed
Saving a Core Milestone project from the admin form no longer silently regresses its status to Unprocessed
Overview
Admins reported that saving a project in Core Milestone from the admin detail form would sometimes silently revert the status to Unprocessed, with no audit trail attributing the change. The regression was reproducible on preprod (Trello qXZZmJcI). Release 3.9 closes the loop.
Root cause
Three interacting defects combined to produce the silent revert:
-
Sidecar mutation behind the form. Expanding a checklist accordion fired
POST /api/project/update-assessment-commencement-date/{id}, which recorded the commencement timestamp and also mutatedproject.statusto Commenced Assessment. The admin form's in-memory model was now out of sync with the DB. -
Disabled status field. For Core Milestone projects, the admin Project Status field was rendered as a
disabled<select>. Disabled form controls are not submitted. Combined with the out-of-sync model, Symfony Form boundstatustonullon save. -
Recovery without attribution.
ProjectManager::handleDefaultStatus()correctly defaults a null status to Unprocessed on partial-data-update paths. But because the asyncProcessProjectHandlerruns without an authenticated user, that recovery write left nosystem_logrow - making the regression look like an unattributed platform action.
Fix
- Drop the behind-the-form status mutation. The assessment-commencement endpoint now only records the timestamp; it no longer touches
project.status. The pairedprojectStatus.setValue([11])incustom-ea.jsis also removed. Applied in bothapp/andordering/. - Replace the disabled select. For Core Milestone projects, the admin Project Status field now renders as an unmapped read-only TextField, so Symfony Form never binds a status value for those projects. Editable
AssociationFieldis kept for every other state, with the Core Milestone option filtered out of the dropdown (it remains system-assigned viaProjectOrderListener). - Preserve the auto-transition for non-Core-Milestone projects. The intended auto-transition to Commenced Assessment when expanding a checklist accordion is retained for projects that are not in Core Milestone, where the status field is editable and the behind-the-form mutation never caused a null write. Frontend JS keeps a null-check on
#Project_statusso it stays a no-op for Core Milestone projects.
ProjectManager::handleDefaultStatus() is left untouched: its behaviour on genuine partial-data submissions is still wanted.
Behaviour after the fix
| Project status | Admin form status field | On save |
|---|---|---|
| Core Milestone (44) | Read-only TextField, unmapped | Status is not submitted; DB value is preserved |
| Any other status | Editable AssociationField | Admin-chosen value is saved as before |
| Any status, checklist-accordion click | (unchanged) | Non-Core-Milestone: auto-transition to Commenced Assessment. Core Milestone: no-op |
Preprod verification
Traced and reproduced against a Core Milestone project on preprod before and after the fix. Post-deploy, saving the admin detail form no longer regresses status; the auto-transition on checklist expansion still fires for eligible projects.
Related
- PR #840.
- Trello
qXZZmJcI- reproduction and tracing notes.
Clone RFI Template - Per-Category Checklist Status
Cloning an RFI template now stamps a category-specific default status on each new checklist item so the checklist reflects the RFI request
Ordering Portal LOT Address Canonicalisation
Picking a "Lot on Street" suggestion on the ordering portal now rewrites the input to canonical LOT N (streetNo) STREET SUBURB shape instead of the raw ArcGIS label