All files / src/services workflowService.ts

100% Statements 9/9
100% Branches 4/4
100% Functions 2/2
100% Lines 9/9

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85                                          3x                               5x       3x                                     7x           7x 1x     7x         3x         3x        
/**
 * Workflow Service (Story 5.1a - Task 9)
 *
 * HTTP client for Event Workflow Status APIs
 * Features:
 * - Get workflow status (GET /api/v1/events/{code}/workflow/status)
 * - Transition workflow state (POST /api/v1/events/{code}/workflow/transition)
 * - JWT authentication via interceptors
 * - Error handling with correlation IDs
 */
 
import apiClient from '@/services/api/apiClient';
import type { components } from '@/types/generated/events-core-api.types';
 
// Type definitions from OpenAPI spec
export type WorkflowStatusDto = components['schemas']['WorkflowStatusDto'];
export type TransitionStateRequest = components['schemas']['TransitionStateRequest'];
export type EventWorkflowState = components['schemas']['EventWorkflowState'];
export type Event = components['schemas']['Event'];
 
// API base path for workflow endpoints
const WORKFLOW_API_PATH = '/events';
 
/**
 * Workflow Service
 *
 * Handles all HTTP requests for event workflow state management
 */
class WorkflowService {
  /**
   * Get current workflow status for an event
   *
   * @param eventCode The event code (e.g., "BATbern56")
   * @returns WorkflowStatusDto with current state, next states, blockers, and validation messages
   * @throws Error if event not found or network failure
   */
  async getWorkflowStatus(eventCode: string): Promise<WorkflowStatusDto> {
    const response = await apiClient.get<WorkflowStatusDto>(
      `${WORKFLOW_API_PATH}/${eventCode}/workflow/status`
    );
 
    return response.data;
  }
 
  /**
   * Transition event to target workflow state
   *
   * @param eventCode The event code (e.g., "BATbern56")
   * @param targetState The target workflow state (e.g., "TOPIC_SELECTION")
   * @param override Optional flag to bypass workflow validation (defaults to false)
   * @param reason Optional reason for overriding validation (for audit trail)
   * @returns Updated Event with new workflow state
   * @throws Error if invalid transition, validation fails, or unauthorized
   */
  async transitionWorkflowState(
    eventCode: string,
    targetState: EventWorkflowState,
    override?: boolean,
    reason?: string
  ): Promise<Event> {
    const requestBody: TransitionStateRequest = {
      targetState,
      overrideValidation: override ?? false,
    };
 
    // Add override reason if provided
    if (reason) {
      requestBody.overrideReason = reason;
    }
 
    const response = await apiClient.post<Event>(
      `${WORKFLOW_API_PATH}/${eventCode}/workflow/transition`,
      requestBody
    );
 
    return response.data;
  }
}
 
// Export singleton instance
export const workflowService = new WorkflowService();
 
// Export class for testing
export default WorkflowService;