Integrations & Communications¶
Backend domains:
- app/graphql/emails/ — outgoing email send + inbox sync (via Aurinko)
- app/graphql/whatsapp/ — WhatsApp send (scaffolded; service to be filled in)
- app/graphql/chats/ — AI chat sessions (OpenAI / Anthropic / DeepSeek)
- app/graphql/files/ — file storage (DO Spaces / S3) + per-entity attachments
- app/graphql/signatures/ — in-app document e-signatures
- app/graphql/pdf/ — PDF rendering service
- app/graphql/pdf_templates/ — per-tenant PDF layout templates
- app/graphql/integrations/ — Aurinko (mail) + QuickBooks Online connectors
- app/webhooks/ — incoming webhook routers (PAC, Polar, WorkOS)
Emails¶
emails/ covers:
createClientEmail,deleteClientEmail— per-client email defaults.sendEmail,sendPdfEmail— generic outgoing sender (used byresendInvoiceEmail, statements, etc.).sendSignatureApprovalEmail— used by the signatures flow.
Inbox sync (read side) is handled through the Aurinko integration — see below.
WhatsApp¶
whatsapp/ is currently scaffolding: model + service folders exist but the public mutations/queries are not wired. The roadmap is to mirror emails/ (send + per-client default + log).
This is one of the highest-leverage features to finish for a Panama PYME — most owners and buyers respond on WhatsApp before they touch email.
AI Chats¶
chats/ powers the in-app AI assistant — used to query the tenant's own data ("what's my biggest unpaid invoice?") and to drive document extraction.
Key mutations: archiveSessionChats.
Key queries: chats, getChatById, getCurrentSessionActiveChat.
Provider selection (OpenAI, Anthropic, DeepSeek) is configured per tenant. File attachments are inspected for type via _is_valid_file_for_chat and _is_text_based_file.
Files¶
A File row holds metadata (name, sha, mime, size, signed URL) and is linked to many entities via FileEntity (polymorphic — invoice, expense, supplier, etc.).
Key mutations: addFile, addFileEntity, generateFileUrls, generateSignedUrl, deleteFile, uploadTmpFile, generateTempFileUrls, createFile.
Key queries: findFiles, getFileById, getFileBySearch, findFilesByEntity, findByFileName.
Storage is Digital Ocean Spaces (S3-compatible). Files are SHA-deduped: re-uploading the same file resolves to the existing row.
There is also a strategy layer (app/graphql/files/strategies/) that routes uploaded invoice files to the right parser (supplier invoice OCR, bank statement parser, …).
Signatures¶
signatures/ is the in-app e-signature feature. A signature is an image attached to a user + applied to an entity (quote, contract, PDF). Use sendSignatureApprovalEmail to fire the approval flow.
Key mutations: addSignature, removeSignature.
Key queries: getSignaturesForEntity, getSignatureById.
This is NOT a full DocuSign-grade signing protocol (no certificate chain, no tamper-proofing, no audit-grade timestamp). For Panama PYMES it is enough for internal approvals and informal client sign-off; it should not be used for legally binding contracts.
PDF rendering + templates¶
pdf/ renders PDFs (invoices, statements, reports) from HTML templates. pdf_templates/ lets a tenant customise the layout — logo, colours, header text, footer disclaimer.
Key mutations: createPdfTemplate, updatePdfTemplate, deletePdfTemplate.
Integrations¶
integrations/ holds OAuth connectors:
- Aurinko — mail + calendar sync provider. Mutations:
getAurinkoAuthorizationUrl,connectAurinko,disconnectAurinko. Query:getAurinkoConnection. - QuickBooks Online — outbound sync (planned full bidirectional). Mutations:
getQboAuthorizationUrl,exchangeQboAuthorizationCode. Query:getQuickbooksConnection.
Webhooks (inbound)¶
app/webhooks/ exposes signed HTTP routes for:
- PAC — Alanube delivering DGI authorisation results. See PAC → Webhooks.
- Polar — SaaS-billing events from polar.sh.
- WorkOS — SSO / user lifecycle events.
Each router validates the signing secret, persists the inbound payload, and emits an internal event handled by the appropriate domain.