Fatura
Multi-tenant invoicing and quotation SaaS engineered for Tanzanian enterprises and SMEs, featuring localized financial formatting, offline-first multi-tab persistence, and client-side PDF document compilation.
Regional Commercial Friction & Administrative Inefficiencies
Small and medium-sized enterprises (SMEs) and independent service providers across East Africa frequently manage billing workflows through unversioned desktop spreadsheets and manual word processor templates. This informal operational pattern leads to severe administrative bottlenecks: overlapping sequential numbering, untracked receivables, and reconciliation errors across split settlement channels.
Existing global SaaS invoicing tools enforce rigid Western banking assumptions. They mandate recurring credit card processing, lack native support for Tanzanian commercial conventions—such as standard 18% Value Added Tax (VAT) computations, advance deposit scheduling, and localized Tanzanian Shilling (/= notation) formatting—and require constant high-bandwidth internet connectivity to function.
Fatura was designed as a lightweight, multi-tenant billing engine tailored specifically to East African commerce. It provides complete multi-organization isolation, atomic sequential numbering across distributed team members, partial payment tracking for bank and mobile money disbursements, and client-side vector document rendering that operates reliably across high-latency mobile networks.

Architectural Design: Multi-Tenancy, Client-Side PDF Compilation & Multi-Tab Caching
Traditional document generation architectures rely on server-side headless browser clusters (such as Puppeteer or Chromium running in cloud functions) to render HTML templates into downloadable PDFs. In regional deployments, this pattern incurs severe penalties: high cold-start latencies (often 3 to 5 seconds per document), memory-intensive server footprints, recurring compute expenses, and compliance risks associated with transmitting sensitive commercial financial data across public network hops.
Fatura inverts this paradigm by executing 100% of PDF document compilation directly on the client. Leveraging @react-pdf/renderer with dynamically registered web typography (Inter), invoices and payment receipts are assembled in-memory as vector-sharp printable documents in under 250 milliseconds. Businesses can customize layouts across multiple presets (Classic, Modern, Minimal, Bold) and inject custom brand color accents. To ensure document readability and legal accessibility, an integrated mathematical color engine parses sRGB relative luminance and validates WCAG AA contrast thresholds (4.5:1 ratio) before saving brand tokens.
Data persistence is structured around Cloud Firestore using tenant-scoped subcollections under /businesses/{businessId}/. Tenancy isolation is enforced at the database engine level via security rules that check authenticated membership against /members/{uid} records. To support field operators experiencing intermittent cellular signals, Firestore is initialized with persistentLocalCache and persistentMultipleTabManager. This guarantees offline IndexedDB synchronization across multiple browser tabs simultaneously without SQLite lock contention.
const businessRef = doc(db, 'businesses', business.id);
const invoiceRef = doc(collection(db, 'businesses', business.id, 'documents'));
await runTransaction(db, async (transaction) => {
const busDoc = await transaction.get(businessRef);
if (!busDoc.exists()) {
throw new Error("Business config does not exist.");
}
const busData = busDoc.data();
const nextInvNum = busData.nextInvoiceNumber || 1;
const prefix = busData.invoicePrefix || 'INV-2026-';
const generatedNumber = `${prefix}${String(nextInvNum).padStart(4, '0')}`;
transaction.set(invoiceRef, {
businessId: business.id || '',
type: 'invoice',
number: generatedNumber,
status: 'draft',
clientId: docData.clientId,
clientSnapshot: docData.clientSnapshot,
lineItems: docData.lineItems,
subtotal: docData.subtotal,
vatEnabled: docData.vatEnabled,
vatRate: docData.vatRate,
vatAmount: docData.vatAmount,
total: docData.total,
issueDate: new Date().toISOString().split('T')[0],
dueDate: new Date(Date.now() + 14 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
notes: docData.notes || '',
terms: docData.terms || '',
convertedFromId: docData.id,
createdBy: user.uid,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
});
// Increment business counter
transaction.update(businessRef, { nextInvoiceNumber: nextInvNum + 1 });
// Update quote status to converted
const quoteRef = doc(db, 'businesses', business.id || '', 'documents', docData.id || '');
transaction.update(quoteRef, {
status: 'converted',
updatedAt: new Date().toISOString()
});
});Atomic Firestore transaction orchestrating quotation conversion. Concurrently reads the tenancy counter, formats padded sequence identifiers, generates immutable client and line-item snapshots, increments the business document counter, and marks the source quotation as converted without risk of race condition collisions.
Technical Outcomes & Operational Takeaways
Eliminating server-side PDF generation infrastructure reduced cloud operational overhead to zero dollars while eliminating cold-start latency entirely. Compiling vector documents locally inside Web Worker / browser memory threads ensured immediate invoice previews, instantaneous receipt exports, and strict client data confidentiality.
The atomic transaction pipeline resolved document number collisions under concurrent multi-user environments. By snapshotting client profile data and item catalog values directly onto document records at the moment of issuance, invoices remain immune to subsequent client address updates or catalog price alterations, preserving historical audit integrity.
Integrating Progressive Web App (PWA) caching via Workbox and multi-tab Firestore persistence proved essential for field reliability. Users in regions with intermittent electrical and cellular connectivity can draft quotations, register manual cash or mobile money receipts, and generate printable documents without connection-loss stalls.