Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM, PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source files covering clients, berths, interests/pipeline, documents/EOI, expenses/invoices, email, notifications, dashboard, admin, and client portal. CI/CD via Gitea Actions with Docker builds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
88
src/lib/services/documenso-client.ts
Normal file
88
src/lib/services/documenso-client.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { env } from '@/lib/env';
|
||||
import { logger } from '@/lib/logger';
|
||||
|
||||
const BASE_URL = env.DOCUMENSO_API_URL;
|
||||
const API_KEY = env.DOCUMENSO_API_KEY;
|
||||
|
||||
async function documensoFetch(path: string, options?: RequestInit): Promise<unknown> {
|
||||
const res = await fetch(`${BASE_URL}${path}`, {
|
||||
...options,
|
||||
headers: {
|
||||
Authorization: `Bearer ${API_KEY}`,
|
||||
'Content-Type': 'application/json',
|
||||
...options?.headers,
|
||||
},
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const err = await res.text();
|
||||
logger.error({ path, status: res.status, err }, 'Documenso API error');
|
||||
throw new Error(`Documenso API error: ${res.status}`);
|
||||
}
|
||||
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export interface DocumensoRecipient {
|
||||
name: string;
|
||||
email: string;
|
||||
role: string;
|
||||
signingOrder: number;
|
||||
}
|
||||
|
||||
export interface DocumensoDocument {
|
||||
id: string;
|
||||
status: string;
|
||||
recipients: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
role: string;
|
||||
signingOrder: number;
|
||||
status: string;
|
||||
signingUrl?: string;
|
||||
embeddedUrl?: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export async function createDocument(
|
||||
title: string,
|
||||
pdfBase64: string,
|
||||
recipients: DocumensoRecipient[],
|
||||
): Promise<DocumensoDocument> {
|
||||
return documensoFetch('/api/v1/documents', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ title, document: pdfBase64, recipients }),
|
||||
}) as Promise<DocumensoDocument>;
|
||||
}
|
||||
|
||||
export async function sendDocument(docId: string): Promise<DocumensoDocument> {
|
||||
return documensoFetch(`/api/v1/documents/${docId}/send`, {
|
||||
method: 'POST',
|
||||
}) as Promise<DocumensoDocument>;
|
||||
}
|
||||
|
||||
export async function getDocument(docId: string): Promise<DocumensoDocument> {
|
||||
return documensoFetch(`/api/v1/documents/${docId}`) as Promise<DocumensoDocument>;
|
||||
}
|
||||
|
||||
export async function sendReminder(docId: string, signerId: string): Promise<void> {
|
||||
await documensoFetch(`/api/v1/documents/${docId}/recipients/${signerId}/remind`, {
|
||||
method: 'POST',
|
||||
});
|
||||
}
|
||||
|
||||
export async function downloadSignedPdf(docId: string): Promise<Buffer> {
|
||||
const res = await fetch(`${BASE_URL}/api/v1/documents/${docId}/download`, {
|
||||
headers: { Authorization: `Bearer ${API_KEY}` },
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const err = await res.text();
|
||||
logger.error({ docId, status: res.status, err }, 'Documenso download error');
|
||||
throw new Error(`Documenso download error: ${res.status}`);
|
||||
}
|
||||
|
||||
const arrayBuffer = await res.arrayBuffer();
|
||||
return Buffer.from(arrayBuffer);
|
||||
}
|
||||
Reference in New Issue
Block a user