Bulk status/close: enforce Workflow Designer rules (#21)
Lint / PHP (phpcs PSR-12) (push) Successful in 23s
Lint / JS (eslint) (push) Successful in 9s
Lint / PHP requirements (version + extensions) (push) Successful in 30s
Lint / Notify on failure (push) Skipped
Security / PHP Security (semgrep) (push) Successful in 1m15s
Lint / Deploy (push) Successful in 2s
Lint / PHP (phpcs PSR-12) (push) Successful in 23s
Lint / JS (eslint) (push) Successful in 9s
Lint / PHP requirements (version + extensions) (push) Successful in 30s
Lint / Notify on failure (push) Skipped
Security / PHP Security (semgrep) (push) Successful in 1m15s
Lint / Deploy (push) Successful in 2s
Bulk status changes previously bypassed the workflow entirely — the model carried an explicit "admin-only escape hatch" note — so bulk edit could drive tickets through transitions the designer forbids and skip comments the designer requires. BulkOperationsModel now applies the same rules as the single-ticket path: - Transitions absent from status_transitions are refused per ticket and reported with a reason, instead of being forced through. - requires_comment is checked up front across the whole selection, so a batch is rejected before any ticket is mutated rather than half-applied. - The reason is persisted as a comment on each ticket changed, matching what a single-ticket close records. - Tickets already in the target status are a no-op success, not a failure. requires_admin needs no extra check: api/bulk_operation.php already gates the endpoint on admin. Client: both bulk modals now collect a reason, the close path gets a real modal instead of a bare confirm, and per-ticket skip reasons surface in the result toast instead of a bare failure count.
This commit is contained in:
@@ -107,10 +107,17 @@ $result = $bulkOpsModel->processBulkOperation($operationId);
|
||||
|
||||
if (isset($result['error'])) {
|
||||
$conn->close();
|
||||
echo json_encode([
|
||||
$response = [
|
||||
'success' => false,
|
||||
'error' => $result['error']
|
||||
]);
|
||||
];
|
||||
// Let the client know it should collect a comment and retry, rather than
|
||||
// showing the failure as a dead end.
|
||||
if (!empty($result['requires_comment'])) {
|
||||
$response['requires_comment'] = true;
|
||||
http_response_code(400);
|
||||
}
|
||||
echo json_encode($response);
|
||||
} else {
|
||||
// Invalidate stats cache so dashboard tiles reflect changes immediately
|
||||
require_once dirname(__DIR__) . '/models/StatsModel.php';
|
||||
|
||||
Reference in New Issue
Block a user