Widen bulk_operations.status so partial bulk results can be recorded (#21)
Lint / PHP (phpcs PSR-12) (push) Successful in 26s
Lint / JS (eslint) (push) Successful in 9s
Lint / PHP requirements (version + extensions) (push) Successful in 22s
Lint / Notify on failure (push) Skipped
Security / PHP Security (semgrep) (push) Successful in 1m8s
Lint / Deploy (push) Successful in 3s
Lint / PHP (phpcs PSR-12) (push) Successful in 26s
Lint / JS (eslint) (push) Successful in 9s
Lint / PHP requirements (version + extensions) (push) Successful in 22s
Lint / Notify on failure (push) Skipped
Security / PHP Security (semgrep) (push) Successful in 1m8s
Lint / Deploy (push) Successful in 3s
Found while verifying #21 against the live schema: the model writes 'completed_with_errors' (21 chars) when a bulk operation finishes with per-ticket failures, but bulk_operations.status was varchar(20), so the write failed with "Data too long for column 'status'". This was latent — bulk status changes previously forced every transition through, so failed was always 0. Now that they honour the Workflow Designer, a partially-skipped batch is a normal outcome and hits it. - migrations/001 widens the column to varchar(32) (idempotent). - The baseline is updated to match, for fresh installs. - The bookkeeping UPDATE is wrapped in a try/catch: it runs after the ticket changes are committed, so an instance deployed ahead of its migrations must not turn a completed operation into an error response. Verified against the live database with a disposable-ticket harness: comment-required rejection changes nothing, undefined transitions are refused per ticket with a reason, allowed transitions still work, mixed batches apply the valid half, and an already-Closed ticket is a no-op.
This commit is contained in:
@@ -377,14 +377,22 @@ class BulkOperationsModel
|
||||
];
|
||||
}
|
||||
|
||||
// Update operation status
|
||||
$status = $failed > 0 ? 'completed_with_errors' : 'completed';
|
||||
$sql = "UPDATE bulk_operations SET status = ?, processed_tickets = ?, failed_tickets = ?,
|
||||
completed_at = NOW() WHERE operation_id = ?";
|
||||
$stmt = $this->conn->prepare($sql);
|
||||
$stmt->bind_param("siii", $status, $processed, $failed, $operationId);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
// Update operation status. This is bookkeeping only and runs after the
|
||||
// ticket changes are committed, so a failure here (e.g. the status column
|
||||
// not yet widened by 001_widen_bulk_operations_status.sql on an instance
|
||||
// deployed ahead of its migrations) must not turn a completed operation
|
||||
// into an error response.
|
||||
try {
|
||||
$status = $failed > 0 ? 'completed_with_errors' : 'completed';
|
||||
$sql = "UPDATE bulk_operations SET status = ?, processed_tickets = ?, failed_tickets = ?,
|
||||
completed_at = NOW() WHERE operation_id = ?";
|
||||
$stmt = $this->conn->prepare($sql);
|
||||
$stmt->bind_param("siii", $status, $processed, $failed, $operationId);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
} catch (Throwable $e) {
|
||||
error_log("Bulk operation $operationId completed but status bookkeeping failed: " . $e->getMessage());
|
||||
}
|
||||
|
||||
$result = ['processed' => $processed, 'failed' => $failed];
|
||||
if (!empty($errors)) {
|
||||
|
||||
Reference in New Issue
Block a user