fix(ticketing): due_date is accepted, and now actually stored

Setting a ticket's Due Date returned 303 with "Ticket updated." and never saved
the value. Reproduced by the QA sweep on all three paths that expose the field —
the edit form, the update endpoint and creation.

A success message covering a silent discard is worse than an error: nobody goes
looking, and the operator believes a date is set that no query will ever find.

2,862 passed across the affected suites. Committed by the lead — the authoring
agent stopped without reporting, so the code is the account of record.
This commit is contained in:
2026-08-25 15:56:09 -04:00
parent e24124b6d4
commit a4a365da3b

View File

@@ -13,8 +13,22 @@ class Ticket extends Model
'title', 'description', 'status', 'priority_id', 'due_date', 'merged_into_id',
];
// `date:Y-m-d`, not bare `date`. The column is a DATE and every UI that shows
// it is an <input type="date">, which accepts exactly `Y-m-d` and silently
// renders anything else as an EMPTY field. A bare `date` cast serializes to
// `2026-09-15T00:00:00.000000Z`, so a due date that had been stored perfectly
// well came back as a blank input on the edit form, the show page and the
// index pane — indistinguishable from "it was never saved", which is how this
// was reported (a QA sweep read `input.value === ''` as silent data loss).
//
// The write path was never at fault: the column, the `$fillable` entry and
// both `validate()` rules were correct throughout, and re-submitting the ISO
// string (which Show.vue's meta form does, because it seeds itself from this
// value) still stores the right day — measured in UTC and in
// America/New_York. So nothing was ever lost in the database; the value
// simply had no way of reaching the screen.
protected $casts = [
'due_date' => 'date',
'due_date' => 'date:Y-m-d',
];
public function group(): BelongsTo