Fix avg resolution time using dedicated closed_at column
The dashboard's "Avg Resolution" stat was using updated_at, which gets overwritten on any post-close edit (title change, comment, etc.), inflating the metric. Also fixes "Closed Today" count for the same reason. - Add closed_at TIMESTAMP column to tickets table - Set closed_at on close, preserve on re-edit, clear on reopen - Update StatsModel queries to use closed_at instead of updated_at - Add migration script with audit log backfill for existing tickets Run: php scripts/add_closed_at_column.php Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -216,6 +216,9 @@ class TicketModel {
|
||||
* @return array ['success' => bool, 'error' => string|null, 'conflict' => bool]
|
||||
*/
|
||||
public function updateTicket(array $ticketData, ?int $updatedBy = null, ?string $expectedUpdatedAt = null): array {
|
||||
// closed_at: set on close (preserve if already set), clear on reopen
|
||||
$closedAtClause = "closed_at = CASE WHEN ? = 'Closed' THEN COALESCE(closed_at, NOW()) ELSE NULL END";
|
||||
|
||||
// Build query with optional optimistic locking
|
||||
if ($expectedUpdatedAt !== null) {
|
||||
// Optimistic locking enabled - check that updated_at hasn't changed
|
||||
@@ -227,7 +230,8 @@ class TicketModel {
|
||||
category = ?,
|
||||
type = ?,
|
||||
updated_by = ?,
|
||||
updated_at = NOW()
|
||||
updated_at = NOW(),
|
||||
$closedAtClause
|
||||
WHERE ticket_id = ? AND updated_at = ?";
|
||||
} else {
|
||||
// No optimistic locking
|
||||
@@ -239,7 +243,8 @@ class TicketModel {
|
||||
category = ?,
|
||||
type = ?,
|
||||
updated_by = ?,
|
||||
updated_at = NOW()
|
||||
updated_at = NOW(),
|
||||
$closedAtClause
|
||||
WHERE ticket_id = ?";
|
||||
}
|
||||
|
||||
@@ -250,7 +255,7 @@ class TicketModel {
|
||||
|
||||
if ($expectedUpdatedAt !== null) {
|
||||
$stmt->bind_param(
|
||||
"sissssiis",
|
||||
"sissssisis",
|
||||
$ticketData['title'],
|
||||
$ticketData['priority'],
|
||||
$ticketData['status'],
|
||||
@@ -258,12 +263,13 @@ class TicketModel {
|
||||
$ticketData['category'],
|
||||
$ticketData['type'],
|
||||
$updatedBy,
|
||||
$ticketData['status'],
|
||||
$ticketData['ticket_id'],
|
||||
$expectedUpdatedAt
|
||||
);
|
||||
} else {
|
||||
$stmt->bind_param(
|
||||
"sissssii",
|
||||
"sissssisi",
|
||||
$ticketData['title'],
|
||||
$ticketData['priority'],
|
||||
$ticketData['status'],
|
||||
@@ -271,6 +277,7 @@ class TicketModel {
|
||||
$ticketData['category'],
|
||||
$ticketData['type'],
|
||||
$updatedBy,
|
||||
$ticketData['status'],
|
||||
$ticketData['ticket_id']
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user