All files / services adminDocumentsApi.ts

39.13% Statements 9/23
0% Branches 0/4
43.75% Functions 7/16
39.13% Lines 9/23

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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117                                                                2x 2x     3x 3x 3x                             3x 3x 3x                                                                                                                       2x  
// src/services/adminDocumentsApi.ts
//
// Admin view of an investor's document progress (FSC-57):
//   - agreements:        outbound PandaDoc docs (investment + loan)
//   - provided documents: files the admin attaches for the investor
import {api} from './api';
import type {PandaDocDocument} from './documentsApi';
import type {ProvidedDocument, ProvidedDocumentsResponse} from './providedDocumentsApi';
 
// ============================================================================
// Types
// ============================================================================
 
export interface AdminAgreementsResponse {
	documents: PandaDocDocument[];
}
 
export interface ProvideDocumentArgs {
	investorId: number;
	title: string;
	description?: string;
	file: File;
}
 
export interface ProvidedDocumentResponse {
	document: ProvidedDocument;
}
 
// ============================================================================
// Endpoints
// ============================================================================
 
export const adminDocumentsApi = api.injectEndpoints({
	endpoints: (builder) => ({
		/** A specific investor's outbound PandaDoc agreements. */
		getInvestorAgreements: builder.query<AdminAgreementsResponse, number>({
			query: (investorId) => `/admin/investors/${String(investorId)}/agreements`,
			transformResponse: (response: {data: AdminAgreementsResponse}) => response.data,
			providesTags: (_result, _error, id) => [{type: 'Document', id: `investor-${String(id)}`}]
		}),
 
		/** Download an investor's agreement PDF as a blob. */
		downloadInvestorAgreement: builder.mutation<Blob, {investorId: number; documentId: string}>({
			query: ({investorId, documentId}) => ({
				url: `/admin/investors/${String(investorId)}/agreements/${documentId}/download`,
				method: 'GET',
				responseHandler: (response) => response.blob(),
				cache: 'no-store'
			})
		}),
 
		/** Documents the admin has provided to a specific investor. */
		listInvestorProvidedDocuments: builder.query<ProvidedDocumentsResponse, number>({
			query: (investorId) => `/admin/investors/${String(investorId)}/provided-documents`,
			transformResponse: (response: {data: ProvidedDocumentsResponse}) => response.data,
			providesTags: (_result, _error, id) => [
				{type: 'ProvidedDocument', id: `investor-${String(id)}`},
				'ProvidedDocument'
			]
		}),
 
		/** Provide (upload) a new document to an investor. */
		provideDocument: builder.mutation<ProvidedDocumentResponse, ProvideDocumentArgs>({
			query: ({investorId, title, description, file}) => {
				const form = new FormData();
				form.append('title', title);
				if (description !== undefined && description !== '') {
					form.append('description', description);
				}
				form.append('file', file, file.name);
 
				return {
					url: `/admin/investors/${String(investorId)}/provided-documents`,
					method: 'POST',
					body: form
				};
			},
			transformResponse: (response: {data: ProvidedDocumentResponse}) => response.data,
			invalidatesTags: (_result, _error, {investorId}) => [
				{type: 'ProvidedDocument', id: `investor-${String(investorId)}`},
				'ProvidedDocument'
			]
		}),
 
		/** Admin download of a provided document as a blob. */
		adminDownloadProvidedDocument: builder.mutation<Blob, {investorId: number; providedDocumentId: number}>({
			query: ({investorId, providedDocumentId}) => ({
				url: `/admin/investors/${String(investorId)}/provided-documents/${String(providedDocumentId)}/file`,
				method: 'GET',
				responseHandler: (response) => response.blob(),
				cache: 'no-store'
			})
		}),
 
		/** Remove a previously provided document. */
		deleteProvidedDocument: builder.mutation<void, {investorId: number; providedDocumentId: number}>({
			query: ({investorId, providedDocumentId}) => ({
				url: `/admin/investors/${String(investorId)}/provided-documents/${String(providedDocumentId)}`,
				method: 'DELETE'
			}),
			invalidatesTags: (_result, _error, {investorId}) => [
				{type: 'ProvidedDocument', id: `investor-${String(investorId)}`},
				'ProvidedDocument'
			]
		})
	})
});
 
export const {
	useGetInvestorAgreementsQuery,
	useDownloadInvestorAgreementMutation,
	useListInvestorProvidedDocumentsQuery,
	useProvideDocumentMutation,
	useAdminDownloadProvidedDocumentMutation,
	useDeleteProvidedDocumentMutation
} = adminDocumentsApi;