Invoices arrive by email from many vendors, in many shapes. Someone has to open each PDF, type the numbers into the accounting system, figure out who has to approve it, chase that approval, and finally book the invoice.
This is slow, easy to get wrong, and impossible to audit later. When something goes missing or is paid twice, nobody can say exactly what happened.
dataflows watches the inbox. When an invoice comes in, AI extracts the key data: amount, date, vendor, cost center. The workflow then asks the right approver by email or Slack and waits up to seven days for an answer.
Once approved, the invoice is uploaded into the accounting system with all metadata attached. If something is missing or unclear, the workflow asks a human instead of guessing. Every step is logged so finance can always see what was done, by whom, and when.
// Invoice approval workflow
export const invoiceApproval = defineWorkflow({
id: 'invoice-approval',
trigger: email.onReceive({ subject: 'Invoice' }),
async run({ event, step }) {
const pdf = await step.run('extract-pdf', () =>
attachments.firstPdf(event)
)
const data = await step.run('ai-extract', () =>
ai.extract(pdf, {
amount: 'number',
date: 'date',
vendor: 'string',
costCenter: 'string'
})
)
const approver = await step.run('find-approver', () =>
people.byCostCenter(data.costCenter)
)
const decision = await step.waitForApproval({
approver,
timeout: '7d',
summary: data
})
if (decision === 'rejected') return { status: 'rejected' }
await step.run('book-in-accounting', () =>
accounting.uploadInvoice({ pdf, data })
)
return { status: 'booked' }
}
})