app.post('/api/sign', async (req, res) => {
try {
const { eventId, document, auditTrail, documentFields, signerFields, signer } = req.body;
if (!document?.url) {
return res.status(400).json({ error: 'document.url is required' });
}
// 1. Fill document fields
const annotated = await fetch('https://api.superdoc.dev/v1/annotate?to=pdf', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.SUPERDOC_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
document: { url: document.url },
fields: [...documentFields, ...signerFields]
})
});
if (!annotated.ok) throw new Error('Annotation failed');
// 2. Apply digital signature
const annotatedData = await annotated.json();
const signed = await fetch('https://api.superdoc.dev/v1/sign', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.SUPERDOC_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
eventId,
document: { base64: annotatedData?.document?.base64 },
auditTrail,
signer
})
});
if (!signed.ok) throw new Error('Signing failed');
// 3. Save signed PDF
const signedData = await signed.json();
const signedPdfBase64 = signedData?.document?.base64;
await saveToS3(Buffer.from(signedPdfBase64, 'base64'), `signed/${eventId}.pdf`);
// 4. Log for compliance
await db.signatures.create({
eventId,
signerName: signerFields.find(f => f.id === '1')?.value,
signedAt: new Date(),
auditTrail: JSON.stringify(auditTrail)
});
res.json({ success: true, documentId: eventId });
} catch (error) {
console.error('Signing failed:', error);
res.status(500).json({ error: 'Failed to sign document' });
}
});