Feature 3: Implement Status Transitions with Workflow Validation

Add comprehensive workflow management system for ticket status transitions:

- Created WorkflowModel.php for managing status transition rules
- Updated TicketController.php to load allowed transitions for each ticket
- Modified TicketView.php to display dynamic status dropdown with only allowed transitions
- Enhanced api/update_ticket.php with server-side workflow validation
- Added updateTicketStatus() JavaScript function for client-side status changes
- Included CSS styling for status select dropdown with color-coded states
- Transitions can require comments or admin privileges
- Status changes are validated against status_transitions table

This feature enforces proper ticket workflows and prevents invalid status changes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-01 18:57:23 -05:00
parent 99e60795c9
commit 683420cdb9
6 changed files with 310 additions and 13 deletions

View File

@@ -45,11 +45,13 @@ try {
$ticketModelPath = dirname(__DIR__) . '/models/TicketModel.php';
$commentModelPath = dirname(__DIR__) . '/models/CommentModel.php';
$auditLogModelPath = dirname(__DIR__) . '/models/AuditLogModel.php';
$workflowModelPath = dirname(__DIR__) . '/models/WorkflowModel.php';
debug_log("Loading models from: $ticketModelPath and $commentModelPath");
require_once $ticketModelPath;
require_once $commentModelPath;
require_once $auditLogModelPath;
require_once $workflowModelPath;
debug_log("Models loaded successfully");
// Check authentication via session
@@ -59,22 +61,27 @@ try {
}
$currentUser = $_SESSION['user'];
$userId = $currentUser['user_id'];
debug_log("User authenticated: " . $currentUser['username']);
$isAdmin = $currentUser['is_admin'] ?? false;
debug_log("User authenticated: " . $currentUser['username'] . " (admin: " . ($isAdmin ? 'yes' : 'no') . ")");
// Updated controller class that handles partial updates
class ApiTicketController {
private $ticketModel;
private $commentModel;
private $auditLog;
private $workflowModel;
private $envVars;
private $userId;
private $isAdmin;
public function __construct($conn, $envVars = [], $userId = null) {
public function __construct($conn, $envVars = [], $userId = null, $isAdmin = false) {
$this->ticketModel = new TicketModel($conn);
$this->commentModel = new CommentModel($conn);
$this->auditLog = new AuditLogModel($conn);
$this->workflowModel = new WorkflowModel($conn);
$this->envVars = $envVars;
$this->userId = $userId;
$this->isAdmin = $isAdmin;
}
public function update($id, $data) {
@@ -120,13 +127,20 @@ try {
];
}
// Validate status
$validStatuses = ['Open', 'Closed', 'In Progress', 'Pending'];
if (!in_array($updateData['status'], $validStatuses)) {
return [
'success' => false,
'error' => 'Invalid status value'
];
// Validate status transition using workflow model
if ($currentTicket['status'] !== $updateData['status']) {
$allowed = $this->workflowModel->isTransitionAllowed(
$currentTicket['status'],
$updateData['status'],
$this->isAdmin
);
if (!$allowed) {
return [
'success' => false,
'error' => 'Status transition not allowed: ' . $currentTicket['status'] . ' → ' . $updateData['status']
];
}
}
debug_log("Validation passed, calling ticketModel->updateTicket");
@@ -286,7 +300,7 @@ try {
// Initialize controller
debug_log("Initializing controller");
$controller = new ApiTicketController($conn, $envVars, $userId);
$controller = new ApiTicketController($conn, $envVars, $userId, $isAdmin);
debug_log("Controller initialized");
// Update ticket