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 86 87 88 89 90 91 | 1x 10x 7x 3x 2x 2x 4x 1x | /**
* Speaker Outreach Service (Story 5.3)
*
* HTTP client for Speaker Outreach Tracking APIs
* Features:
* - Record speaker outreach attempt (POST /api/v1/events/{eventCode}/speakers/{speakerId}/outreach)
* - Get speaker outreach history (GET /api/v1/events/{eventCode}/speakers/{speakerId}/outreach)
* - Bulk record outreach for multiple speakers
* - JWT authentication via interceptors
* - Error handling with correlation IDs
*/
import apiClient from '@/services/api/apiClient';
import type {
OutreachHistory,
RecordOutreachRequest,
OutreachHistoryResponse,
} from '@/types/speakerOutreach.types';
// API base path
const EVENTS_API_PATH = '/events';
/**
* Speaker Outreach Service
*
* Handles all HTTP requests for speaker outreach tracking
*/
class SpeakerOutreachService {
/**
* Record speaker outreach attempt (AC2-3)
*
* @param eventCode Event code (e.g., "BATbern56")
* @param speakerId Speaker UUID
* @param request Outreach data (contact method, date, notes)
* @returns Created outreach history entry
* @throws Error if speaker not found, invalid state, or unauthorized
*/
async recordOutreach(
eventCode: string,
speakerId: string,
request: RecordOutreachRequest
): Promise<OutreachHistoryResponse> {
const response = await apiClient.post<OutreachHistoryResponse>(
`${EVENTS_API_PATH}/${eventCode}/speakers/${speakerId}/outreach`,
request
);
return response.data;
}
/**
* Get speaker outreach history (AC4)
*
* @param eventCode Event code (e.g., "BATbern56")
* @param speakerId Speaker UUID
* @returns Chronological list of outreach attempts (most recent first)
* @throws Error if speaker not found or unauthorized
*/
async getOutreachHistory(eventCode: string, speakerId: string): Promise<OutreachHistory[]> {
const response = await apiClient.get<OutreachHistory[]>(
`${EVENTS_API_PATH}/${eventCode}/speakers/${speakerId}/outreach`
);
return response.data;
}
/**
* Bulk record outreach for multiple speakers (AC6)
*
* @param eventCode Event code (e.g., "BATbern56")
* @param speakerIds Array of speaker UUIDs
* @param request Outreach data (same contact method/date/notes for all)
* @throws Error if any speaker not found or in invalid state
*/
async bulkRecordOutreach(
eventCode: string,
speakerIds: string[],
request: RecordOutreachRequest
): Promise<void> {
await Promise.all(
speakerIds.map((speakerId) => this.recordOutreach(eventCode, speakerId, request))
);
}
}
// Export singleton instance
export const speakerOutreachService = new SpeakerOutreachService();
// Export class for testing
export default SpeakerOutreachService;
|