FEAT: Correct spelling of 'Documenso' in API utility functions and add connectivity test for Documenso API
This commit is contained in:
parent
8d378f5b53
commit
0b881a2588
|
|
@ -0,0 +1,57 @@
|
|||
export default defineEventHandler(async (event) => {
|
||||
console.log('[DEBUG] Testing Documenso connectivity...')
|
||||
|
||||
try {
|
||||
// Test basic connectivity to Documenso
|
||||
const documensoBaseUrl = process.env.NUXT_DOCUMENSO_BASE_URL;
|
||||
const documensoApiKey = process.env.NUXT_DOCUMENSO_API_KEY;
|
||||
|
||||
if (!documensoBaseUrl || !documensoApiKey) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Documenso configuration missing',
|
||||
error: {
|
||||
message: 'NUXT_DOCUMENSO_BASE_URL or NUXT_DOCUMENSO_API_KEY environment variables not set'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const testUrl = `${documensoBaseUrl}/api/v1/documents`
|
||||
|
||||
const response = await $fetch(testUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${documensoApiKey}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
params: {
|
||||
perPage: 1 // Just get 1 document to test connectivity
|
||||
},
|
||||
retry: 0
|
||||
}) as any
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Documenso connectivity successful',
|
||||
endpoint: testUrl,
|
||||
response: {
|
||||
total: response.total || 0,
|
||||
documentsFound: response.documents ? response.documents.length : 0,
|
||||
statusCode: 200
|
||||
}
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('[DEBUG] Documenso connectivity test failed:', error)
|
||||
|
||||
return {
|
||||
success: false,
|
||||
message: 'Documenso connectivity failed',
|
||||
error: {
|
||||
message: error.message,
|
||||
status: error.status,
|
||||
statusCode: error.statusCode,
|
||||
cause: error.cause?.message
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { getDocumesoDocumentByExternalId, checkDocumentSignatureStatus } from '~/server/utils/documeso';
|
||||
import { getDocumensoDocumentByExternalId, checkDocumentSignatureStatus } from '~/server/utils/documeso';
|
||||
import { getInterestById, updateInterest } from '~/server/utils/nocodb';
|
||||
import { requireAuth } from '~/server/utils/auth';
|
||||
import type { InterestSalesProcessLevel, EOIStatus } from '~/utils/types';
|
||||
|
|
@ -89,7 +89,7 @@ export default defineEventHandler(async (event) => {
|
|||
// Otherwise, try to find by external ID (using interestId) - fallback method
|
||||
console.log('[check-signature-status] No documensoID stored, trying external ID fallback');
|
||||
const externalId = `loi-${interestId}`;
|
||||
const document = await getDocumesoDocumentByExternalId(externalId);
|
||||
const document = await getDocumensoDocumentByExternalId(externalId);
|
||||
|
||||
if (!document) {
|
||||
console.log('[check-signature-status] No document found by external ID either');
|
||||
|
|
|
|||
|
|
@ -55,8 +55,13 @@ export default defineEventHandler(async (event) => {
|
|||
}
|
||||
} catch (error: any) {
|
||||
console.error('[Delete Generated EOI] Failed to check signature status:', error);
|
||||
// If we can't check status, we'll proceed with deletion but warn
|
||||
console.warn('[Delete Generated EOI] Proceeding with deletion despite signature status check failure');
|
||||
|
||||
// If it's a 404 error, the document is already gone from Documenso, so we can proceed with cleanup
|
||||
if (error.status === 404 || error.statusCode === 404 || error.message?.includes('404')) {
|
||||
console.log('[Delete Generated EOI] Document not found in Documenso (404) - proceeding with database cleanup');
|
||||
} else {
|
||||
console.warn('[Delete Generated EOI] Proceeding with deletion despite signature status check failure');
|
||||
}
|
||||
}
|
||||
|
||||
// Delete document from Documenso
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { requireAuth } from '~/server/utils/auth';
|
||||
import { getDocumesoDocument, checkDocumentSignatureStatus, formatRecipientName } from '~/server/utils/documeso';
|
||||
import { getDocumensoDocument, checkDocumentSignatureStatus, formatRecipientName } from '~/server/utils/documeso';
|
||||
import { getInterestById } from '~/server/utils/nocodb';
|
||||
import { sendEmail } from '~/server/utils/email';
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ export default defineEventHandler(async (event) => {
|
|||
}
|
||||
|
||||
// Get document and check signature status
|
||||
const document = await getDocumesoDocument(parseInt(documentId));
|
||||
const document = await getDocumensoDocument(parseInt(documentId));
|
||||
const status = await checkDocumentSignatureStatus(parseInt(documentId));
|
||||
|
||||
const emailsToSend: ReminderEmail[] = [];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { getInterestById, updateInterest } from '~/server/utils/nocodb';
|
||||
import { getDocumesoDocument } from '~/server/utils/documeso';
|
||||
import { getDocumensoDocument } from '~/server/utils/documeso';
|
||||
import { requireAuth } from '~/server/utils/auth';
|
||||
import type { InterestSalesProcessLevel, EOIStatus } from '~/utils/types';
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ export default defineEventHandler(async (event) => {
|
|||
|
||||
try {
|
||||
console.log('[Validate Document] Checking document existence in Documenso');
|
||||
const document = await getDocumesoDocument(parseInt(documensoID));
|
||||
const document = await getDocumensoDocument(parseInt(documensoID));
|
||||
documentStatus = document.status;
|
||||
console.log('[Validate Document] Document exists with status:', documentStatus);
|
||||
} catch (error: any) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
// Documeso API client utilities
|
||||
interface DocumesoConfig {
|
||||
// Documenso API client utilities
|
||||
interface DocumensoConfig {
|
||||
apiUrl: string;
|
||||
apiKey: string;
|
||||
}
|
||||
|
||||
interface DocumesoRecipient {
|
||||
interface DocumensoRecipient {
|
||||
id: number;
|
||||
documentId: number;
|
||||
email: string;
|
||||
|
|
@ -19,7 +19,7 @@ interface DocumesoRecipient {
|
|||
signingUrl: string;
|
||||
}
|
||||
|
||||
interface DocumesoDocument {
|
||||
interface DocumensoDocument {
|
||||
id: number;
|
||||
externalId: string;
|
||||
userId: number;
|
||||
|
|
@ -30,30 +30,40 @@ interface DocumesoDocument {
|
|||
createdAt: string;
|
||||
updatedAt: string;
|
||||
completedAt: string | null;
|
||||
recipients: DocumesoRecipient[];
|
||||
recipients: DocumensoRecipient[];
|
||||
}
|
||||
|
||||
interface DocumesoListResponse {
|
||||
documents: DocumesoDocument[];
|
||||
interface DocumensoListResponse {
|
||||
documents: DocumensoDocument[];
|
||||
total: number;
|
||||
page: number;
|
||||
perPage: number;
|
||||
}
|
||||
|
||||
// Get Documeso configuration
|
||||
const getDocumesoConfig = (): DocumesoConfig => {
|
||||
// Get Documenso configuration from environment variables
|
||||
const getDocumensoConfig = (): DocumensoConfig => {
|
||||
const apiUrl = process.env.NUXT_DOCUMENSO_BASE_URL;
|
||||
const apiKey = process.env.NUXT_DOCUMENSO_API_KEY;
|
||||
|
||||
if (!apiUrl || !apiKey) {
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Documenso configuration missing. Please check NUXT_DOCUMENSO_BASE_URL and NUXT_DOCUMENSO_API_KEY environment variables.'
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
apiUrl: 'https://signatures.portnimara.dev/api/v1',
|
||||
apiKey: 'Bearer api_malptg62zqyb0wrp'
|
||||
apiUrl: `${apiUrl}/api/v1`,
|
||||
apiKey: `Bearer ${apiKey}`
|
||||
};
|
||||
};
|
||||
|
||||
// Fetch a single document by ID
|
||||
export const getDocumesoDocument = async (documentId: number): Promise<DocumesoDocument> => {
|
||||
const config = getDocumesoConfig();
|
||||
export const getDocumensoDocument = async (documentId: number): Promise<DocumensoDocument> => {
|
||||
const config = getDocumensoConfig();
|
||||
|
||||
try {
|
||||
const response = await $fetch<DocumesoDocument>(`${config.apiUrl}/documents/${documentId}`, {
|
||||
const response = await $fetch<DocumensoDocument>(`${config.apiUrl}/documents/${documentId}`, {
|
||||
headers: {
|
||||
'Authorization': config.apiKey,
|
||||
'Content-Type': 'application/json'
|
||||
|
|
@ -62,17 +72,17 @@ export const getDocumesoDocument = async (documentId: number): Promise<DocumesoD
|
|||
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch Documeso document:', error);
|
||||
console.error('Failed to fetch Documenso document:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Search documents by external ID (e.g., 'loi-94')
|
||||
export const searchDocumesoDocuments = async (externalId?: string): Promise<DocumesoDocument[]> => {
|
||||
const config = getDocumesoConfig();
|
||||
export const searchDocumensoDocuments = async (externalId?: string): Promise<DocumensoDocument[]> => {
|
||||
const config = getDocumensoConfig();
|
||||
|
||||
try {
|
||||
const response = await $fetch<DocumesoListResponse>(`${config.apiUrl}/documents`, {
|
||||
const response = await $fetch<DocumensoListResponse>(`${config.apiUrl}/documents`, {
|
||||
headers: {
|
||||
'Authorization': config.apiKey,
|
||||
'Content-Type': 'application/json'
|
||||
|
|
@ -84,37 +94,37 @@ export const searchDocumesoDocuments = async (externalId?: string): Promise<Docu
|
|||
|
||||
// If externalId is provided, filter by it
|
||||
if (externalId) {
|
||||
return response.documents.filter(doc => doc.externalId === externalId);
|
||||
return response.documents.filter((doc: DocumensoDocument) => doc.externalId === externalId);
|
||||
}
|
||||
|
||||
return response.documents;
|
||||
} catch (error) {
|
||||
console.error('Failed to search Documeso documents:', error);
|
||||
console.error('Failed to search Documenso documents:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Get document by external ID (e.g., 'loi-94')
|
||||
export const getDocumesoDocumentByExternalId = async (externalId: string): Promise<DocumesoDocument | null> => {
|
||||
const documents = await searchDocumesoDocuments(externalId);
|
||||
export const getDocumensoDocumentByExternalId = async (externalId: string): Promise<DocumensoDocument | null> => {
|
||||
const documents = await searchDocumensoDocuments(externalId);
|
||||
return documents.length > 0 ? documents[0] : null;
|
||||
};
|
||||
|
||||
// Check signature status for a document
|
||||
export const checkDocumentSignatureStatus = async (documentId: number): Promise<{
|
||||
documentStatus: string;
|
||||
unsignedRecipients: DocumesoRecipient[];
|
||||
signedRecipients: DocumesoRecipient[];
|
||||
unsignedRecipients: DocumensoRecipient[];
|
||||
signedRecipients: DocumensoRecipient[];
|
||||
clientSigned: boolean;
|
||||
allSigned: boolean;
|
||||
}> => {
|
||||
const document = await getDocumesoDocument(documentId);
|
||||
const document = await getDocumensoDocument(documentId);
|
||||
|
||||
const unsignedRecipients = document.recipients.filter(r => r.signingStatus === 'NOT_SIGNED');
|
||||
const signedRecipients = document.recipients.filter(r => r.signingStatus === 'SIGNED');
|
||||
const unsignedRecipients = document.recipients.filter((r: DocumensoRecipient) => r.signingStatus === 'NOT_SIGNED');
|
||||
const signedRecipients = document.recipients.filter((r: DocumensoRecipient) => r.signingStatus === 'SIGNED');
|
||||
|
||||
// Check if client (signingOrder = 1) has signed
|
||||
const clientRecipient = document.recipients.find(r => r.signingOrder === 1);
|
||||
const clientRecipient = document.recipients.find((r: DocumensoRecipient) => r.signingOrder === 1);
|
||||
const clientSigned = clientRecipient ? clientRecipient.signingStatus === 'SIGNED' : false;
|
||||
|
||||
const allSigned = unsignedRecipients.length === 0;
|
||||
|
|
@ -129,7 +139,7 @@ export const checkDocumentSignatureStatus = async (documentId: number): Promise<
|
|||
};
|
||||
|
||||
// Get recipients who need to sign (excluding client)
|
||||
export const getRecipientsToRemind = async (documentId: number): Promise<DocumesoRecipient[]> => {
|
||||
export const getRecipientsToRemind = async (documentId: number): Promise<DocumensoRecipient[]> => {
|
||||
const status = await checkDocumentSignatureStatus(documentId);
|
||||
|
||||
// Only remind if client has signed
|
||||
|
|
@ -138,16 +148,16 @@ export const getRecipientsToRemind = async (documentId: number): Promise<Documes
|
|||
}
|
||||
|
||||
// Return unsigned recipients with signingOrder > 1
|
||||
return status.unsignedRecipients.filter(r => r.signingOrder > 1);
|
||||
return status.unsignedRecipients.filter((r: DocumensoRecipient) => r.signingOrder > 1);
|
||||
};
|
||||
|
||||
// Format recipient name for emails
|
||||
export const formatRecipientName = (recipient: DocumesoRecipient): string => {
|
||||
export const formatRecipientName = (recipient: DocumensoRecipient): string => {
|
||||
const firstName = recipient.name.split(' ')[0];
|
||||
return firstName;
|
||||
};
|
||||
|
||||
// Get signing URL for a recipient
|
||||
export const getSigningUrl = (recipient: DocumesoRecipient): string => {
|
||||
export const getSigningUrl = (recipient: DocumensoRecipient): string => {
|
||||
return recipient.signingUrl;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue