port-nimara-client-portal/server/utils/documeso.ts

140 lines
3.9 KiB
TypeScript
Raw Normal View History

import { resilientHttp } from './resilient-http';
interface DocumensoConfig {
apiKey: string;
baseUrl: string;
}
export const getDocumensoConfiguration = (): DocumensoConfig => {
const apiKey = process.env.NUXT_DOCUMENSO_API_KEY;
const baseUrl = process.env.NUXT_DOCUMENSO_BASE_URL;
if (!apiKey || !baseUrl) {
throw new Error('Documenso configuration missing');
}
return { apiKey, baseUrl };
};
// Helper function for resilient Documenso requests
async function documensoFetch<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
const config = getDocumensoConfiguration();
const url = `${config.baseUrl}${endpoint}`;
const response = await resilientHttp.fetchWithRetry(
url,
{
...options,
headers: {
'Authorization': `Bearer ${config.apiKey}`,
'Content-Type': 'application/json',
...options.headers
},
serviceName: 'documenso'
},
{
maxRetries: options.method === 'POST' || options.method === 'PUT' ? 2 : 3,
timeout: 20000, // 20 seconds for document operations
retryableStatuses: [408, 429, 500, 502, 503, 504]
}
);
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Documenso request failed: ${response.status} - ${errorText}`);
}
return response.json();
}
export const checkDocumentStatus = async (documentId: string): Promise<any> => {
console.log('[Documenso] Checking document status:', documentId);
try {
const result = await documensoFetch<any>(`/api/v1/documents/${documentId}`, {
method: 'GET'
});
console.log('[Documenso] Document status retrieved:', result.status);
return result;
} catch (error) {
console.error('[Documenso] Failed to check document status:', error);
throw error;
}
};
export const createDocument = async (templateId: string, data: any): Promise<any> => {
console.log('[Documenso] Creating document from template:', templateId);
try {
const result = await documensoFetch<any>('/api/v1/documents', {
method: 'POST',
body: JSON.stringify({
templateId,
...data
})
});
console.log('[Documenso] Document created with ID:', result.id);
return result;
} catch (error) {
console.error('[Documenso] Failed to create document:', error);
throw error;
}
};
export const sendDocument = async (documentId: string, signers: any[]): Promise<any> => {
console.log('[Documenso] Sending document:', documentId);
try {
const result = await documensoFetch<any>(`/api/v1/documents/${documentId}/send`, {
method: 'POST',
body: JSON.stringify({ signers })
});
console.log('[Documenso] Document sent successfully');
return result;
} catch (error) {
console.error('[Documenso] Failed to send document:', error);
throw error;
}
};
export const deleteDocument = async (documentId: string): Promise<any> => {
console.log('[Documenso] Deleting document:', documentId);
try {
const result = await documensoFetch<any>(`/api/v1/documents/${documentId}`, {
method: 'DELETE'
});
console.log('[Documenso] Document deleted successfully');
return result;
} catch (error) {
console.error('[Documenso] Failed to delete document:', error);
throw error;
}
};
export const verifyTemplate = async (templateId: string): Promise<boolean> => {
console.log('[Documenso] Verifying template:', templateId);
try {
await documensoFetch<any>(`/api/v1/templates/${templateId}`, {
method: 'GET'
});
console.log('[Documenso] Template verified successfully');
return true;
} catch (error) {
console.error('[Documenso] Template verification failed:', error);
return false;
}
};
// Get circuit breaker status for monitoring
export const getDocumensoHealthStatus = () => {
const status = resilientHttp.getCircuitBreakerStatus();
return status.documenso || { state: 'UNKNOWN', failures: 0 };
};