Invoice Pro v1.0

AI-powered invoice extraction and financial management platform

Complete SaaS solution with Next.js 16 frontend, Go backend microservices, document extraction, and intelligent data processing.

πŸš€ Quick Start

Prerequisites

Installation

# Clone repository
git clone https://github.com/yourusername/invoice-pro.git
cd invoice-pro

# Install dependencies
./deploy.sh install

# Start development
docker-compose up -d

Access Points

Service URL Purpose
Frontendhttp://localhost:3000Next.js web app
Backend APIhttp://localhost:8080gRPC-Web gateway
PostgreSQLlocalhost:5432Primary database
Redislocalhost:6379Cache & rate limiting

πŸ—οΈ Architecture

System Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Frontend (Next.js 16)              β”‚
β”‚  β€’ App Router, TypeScript, Tailwind CSS        β”‚
β”‚  β€’ Connect-RPC gRPC client                     β”‚
β”‚  β€’ React Query for state management            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚ HTTP/gRPC-Web
                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         Backend Services (Go)                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Rate Limiter (Redis)                    β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                 β–Ό                                β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Authentication (JWT)                    β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                 β–Ό                                β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Business Logic Handlers                 β”‚  β”‚
β”‚  β”‚  β€’ Accounting Service                    β”‚  β”‚
β”‚  β”‚  β€’ Import Service                        β”‚  β”‚
β”‚  β”‚  β€’ Integration Service                   β”‚  β”‚
β”‚  β”‚  β€’ AI Agent Service                      β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β–Ό            β–Ό            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚PostgreSQLβ”‚  β”‚ Redis  β”‚  β”‚ AI APIs  β”‚
β”‚(Primary) β”‚  β”‚(Cache) β”‚  β”‚(OpenAI)  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“¦ Data Import System Complete

Overview

Universal CSV/Excel import with AI-powered column mapping. Supports any provider (Paystack, Stripe, Flutterwave, Square) with automatic field detection and transformation.

Key Features

Import Strategy

Method Speed Cost Accuracy
Template Matching Instant FREE 100%
Rule-Based Patterns Instant FREE 70-95%
AI Fallback ~2s ~$0.02/file 85%
90-day Cache Instant FREE 95% hit

Database Schema

import_sessions
  - id, tenant_id, filename, status
  - total_rows, processed_rows, error_rows
  - integration_id, provider, template_id
  
import_field_mappings
  - session_id, source_column, target_entity, target_field
  - mapping_strategy (template/ai/rules)
  - confidence_score, transformations (JSONB)
  
import_errors
  - session_id, row_number, field_name, error_message
  
import_templates
  - name, description, provider
  - column_mappings (JSONB), is_public
  
mapping_cache
  - cache_key (hash of columns), mapping_result (JSONB)
  - hit_count, expires_at

API Endpoints (gRPC)

Frontend Components

frontend/src/
β”œβ”€β”€ app/dashboard/data-imports/
β”‚   β”œβ”€β”€ page.tsx                 (list all imports)
β”‚   β”œβ”€β”€ new/page.tsx             (import wizard)
β”‚   β”œβ”€β”€ [id]/page.tsx            (import details)
β”‚   └── templates/page.tsx       (manage templates)
β”œβ”€β”€ components/data-imports/
β”‚   β”œβ”€β”€ import-wizard.tsx        (multi-step wizard)
β”‚   β”œβ”€β”€ upload-step.tsx
β”‚   β”œβ”€β”€ review-step.tsx
β”‚   └── execute-step.tsx
β”œβ”€β”€ hooks/
β”‚   └── use-imports.ts           (8 React hooks)
└── lib/api/
    └── imports.ts               (ImportsAPI client)

Usage Example

// Upload file
const session = await ImportsAPI.uploadFile({
  tenantId: 'uuid',
  file: csvFile,
  integrationId: 'uuid', // optional
  provider: 'stripe',    // optional
  templateId: 'uuid',    // optional (instant import)
})

// Get mappings (AI or template)
const { mappings } = await ImportsAPI.getMappings(tenantId, sessionId)

// Adjust if needed
await ImportsAPI.updateMapping({
  tenantId,
  sessionId,
  mappingId: 'uuid',
  targetField: 'amount',
  isUserConfirmed: true
})

// Execute import
await ImportsAPI.executeImport(tenantId, sessionId)
πŸ’‘ Template Optimization: When a template is selected, mappings are applied instantly without AI analysis. This provides 100% accuracy at zero cost, compared to ~$0.02 per AI analysis.

⚑ Workflow Automation Phase 6 Complete

Overview

Visual workflow builder with scheduled execution, AI-powered automation, and seamless integration management. Build complex business processes with drag-and-drop nodes.

Key Features

Workflow Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚        Workflow Builder (Frontend V2)            β”‚
β”‚  β€’ Drag-and-drop canvas with zoom/pan           β”‚
β”‚  β€’ Node palette (triggers, actions, logic)       β”‚
β”‚  β€’ Configuration sidebar                         β”‚
β”‚  β€’ Integration validation before save            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚ HTTP POST /api/workflows
                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      Workflow API Route (Next.js)                β”‚
β”‚  β€’ Validates required integrations               β”‚
β”‚  β€’ Returns 400 if integration missing            β”‚
β”‚  β€’ Saves workflow definition to backend          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚ gRPC createWorkflow
                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚       Backend Workflow Services (Go)             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  Workflow Scheduler (Cron)                 β”‚ β”‚
β”‚  β”‚  β€’ Polls for scheduled workflows           β”‚ β”‚
β”‚  β”‚  β€’ Triggers execution at intervals         β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚               β–Ό                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  Workflow Runner (Graph Executor)          β”‚ β”‚
β”‚  β”‚  β€’ Resolves {{template}} variables         β”‚ β”‚
β”‚  β”‚  β€’ Executes nodes in dependency order      β”‚ β”‚
β”‚  β”‚  β€’ Manages execution context               β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚               β–Ό                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  Node Executors (11 types)                β”‚ β”‚
β”‚  β”‚  β€’ Triggers: paystack_sync                 β”‚ β”‚
β”‚  β”‚  β€’ Actions: create_payment, create_contact β”‚ β”‚
β”‚  β”‚  β€’ Logic: condition, loop, transform       β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Node Executors

Category Node Type Purpose
Triggerspaystack_syncFetch transactions from Paystack API
Actionscreate_paymentCreate payment record in database
create_contactCreate customer/vendor contact
create_journalCreate journal entry for accounting
link_externalLink to external transaction source
send_emailSend notification email
LogicconditionIf/else branching with operators
loopIterate over arrays, set context per item
transformData mapping and transformation

Template Variable System

Use {{variable}} syntax to reference data from previous nodes. Supports dot notation for nested fields.

// Template syntax examples
{{current_transaction.amount}}       // Access nested field
{{loop_item.customer.email}}         // Access from loop context
{{paystack_transactions[0].status}}  // Array indexing

// Context variables
{{loop_item}}      // Current item in loop
{{loop_index}}     // Current iteration index (0-based)
{{loop_total}}     // Total items in array
{{loop_is_first}}  // Boolean: first iteration
{{loop_is_last}}   // Boolean: last iteration

Condition Operators

Operator Example Use Case
equalsstatus == "success"Exact match
not_equalstype != "refund"Exclusion
greater_thanamount > 10000Numeric threshold
less_thanamount < 1000Lower bound
containsemail contains "@gmail"Substring match
starts_withreference starts_with "PAY"Prefix match
ends_withname ends_with ".pdf"Suffix match
is_emptydescription is_emptyNull/empty check

Integration-Aware Workflow Builder

When creating workflows that require integrations (Paystack, Stripe, etc.), the system automatically validates that integrations are connected before saving.

User Flow

  1. User drags Paystack Scheduled Sync node onto canvas
  2. Node configuration shows alert: "⚠️ Integration Required - Connect Paystack Integration β†’"
  3. User configures polling interval and transaction filter
  4. User clicks Save Workflow
  5. Backend validates that Paystack integration exists and is connected
  6. If missing: Returns 400 error with provider name
  7. Frontend shows alert: "Please connect Paystack integration before saving"
  8. User clicks link β†’ Redirects to integrations page
  9. User connects Paystack with API key
  10. Returns to workflow builder and saves successfully βœ…

Backend Validation

// API Route: /api/workflows (POST)

// Extract integration nodes
const integrationNodes = nodes.filter(node => 
  node.nodeType === 'paystack_scheduled_sync' || 
  node.nodeType === 'stripe_scheduled_sync'
)

// Check each integration
for (const node of integrationNodes) {
  const provider = node.nodeType.replace('_scheduled_sync', '')
  
  const integrations = await accountingClient.listIntegrations({})
  const hasIntegration = integrations.some(
    int => int.provider === provider && int.status === 'connected'
  )
  
  if (!hasIntegration) {
    return NextResponse.json({
      error: 'Missing required integrations',
      missingIntegrations: [{ provider }],
      message: `Please connect ${provider} before saving`
    }, { status: 400 })
  }
}

Frontend Node Configuration

// Paystack Sync Node Config UI

{selectedNode.nodeType === "paystack_scheduled_sync" && (
  <>
    <div className="bg-blue-50 border border-blue-200 rounded p-3">
      <AlertCircle className="text-blue-600" />
      <span className="font-semibold">Integration Required</span>
      <p>This workflow requires a connected Paystack integration.</p>
      <a href="/integrations">Connect Paystack Integration β†’</a>
    </div>
    
    <select>
      <option value="15">Every 15 minutes</option>
      <option value="60">Every hour</option>
      <option value="1440">Daily (recommended)</option>
    </select>
  </>
)}

Example Workflow: Auto-Import Paystack Transactions

{
  "name": "Auto-import Paystack Transactions",
  "nodes": [
    {
      "id": "node_1",
      "nodeType": "paystack_scheduled_sync",
      "config": {
        "polling_interval": "1440",
        "from_date": "{{today - 7 days}}",
        "to_date": "{{today}}",
        "transaction_filter": "success_only"
      }
    },
    {
      "id": "node_2",
      "nodeType": "loop",
      "config": {
        "array_path": "paystack_transactions.transactions"
      }
    },
    {
      "id": "node_3",
      "nodeType": "condition",
      "config": {
        "field": "{{loop_item.amount}}",
        "operator": "greater_than",
        "value": 10000
      }
    },
    {
      "id": "node_4",
      "nodeType": "create_payment",
      "config": {
        "amount": "{{loop_item.amount}}",
        "reference": "{{loop_item.reference}}",
        "customer_email": "{{loop_item.customer.email}}",
        "payment_type": "received",
        "payment_method": "card"
      }
    },
    {
      "id": "node_5",
      "nodeType": "create_journal",
      "config": {
        "description": "Payment received: {{loop_item.reference}}",
        "lines": [
          {
            "account_code": "1010",
            "debit": "{{loop_item.amount}}"
          },
          {
            "account_code": "4010",
            "credit": "{{loop_item.amount}}"
          }
        ]
      }
    }
  ],
  "connections": [
    { "sourceId": "node_1", "targetId": "node_2" },
    { "sourceId": "node_2", "targetId": "node_3" },
    { "sourceId": "node_3", "targetId": "node_4", "type": "true_branch" },
    { "sourceId": "node_4", "targetId": "node_5" }
  ]
}

Workflow Execution Flow

  1. Scheduler triggers workflow (daily at midnight)
  2. Paystack Sync Node fetches last 7 days of transactions via API
  3. Loop Node iterates over each transaction, sets {{loop_item}}
  4. Condition Node checks if amount > ₦10,000
  5. Create Payment Node creates payment record with resolved values
  6. Create Journal Node generates double-entry journal entry
  7. Workflow completes, logs execution summary

Paystack API Integration

Real HTTP integration to api.paystack.co/transaction with pagination, date filtering, and Bearer authentication.

// Paystack Sync Executor (Go)

func (e *PaystackSyncExecutor) Execute(ctx context.Context, ...) {
  // 1. Get integration credentials
  integration := getIntegration(tenantID, "paystack")
  
  // 2. Fetch transactions from Paystack
  transactions := fetchPaystackTransactions(
    integration.SecretKey,
    config.FromDate,
    config.ToDate,
    100 // perPage
  )
  
  // 3. Transform API response
  for _, txn := range transactions {
    amount := txn.Amount / 100 // kobo to naira
    processedTxns = append(processedTxns, {
      "amount": amount,
      "reference": txn.Reference,
      "status": txn.Status,
      "customer": {
        "email": txn.Customer.Email,
        "name": txn.Customer.FirstName + " " + txn.Customer.LastName
      }
    })
  }
  
  // 4. Store in execution context
  return map[string]interface{}{
    "paystack_transactions": {
      "transactions": processedTxns,
      "total": len(processedTxns)
    }
  }
}

Performance

Files

File Lines Purpose
workflow_scheduler.go275Cron-based scheduler
workflow_runner.go441Graph execution engine
executors/paystack_sync.go210Paystack API integration
executors/loop.go145Array iteration with context
executors/condition.go217If/else branching logic
executors/transform.go180Data transformation
workflow-builder-v2.tsx1800+Visual workflow builder
/api/workflows/route.ts150Workflow CRUD + validation
βœ… Phase 6 Complete: All workflow automation features are production-ready including template resolution, loop iteration, condition branching, transforms, Paystack API integration, and integration-aware workflow builder with validation.

πŸ”’ Rate Limiting Complete

Overview

Multi-tier token bucket rate limiting with Redis. Protects API from abuse with automatic retry and user-friendly feedback.

Architecture

Default Limits

Tier Requests/Min Burst
Global10,000100
Tenant1,00050
User20020
AI Chat10010
File Upload20020
Bulk Ops505

Backend Implementation

// Go - Rate limiter with token bucket
rateLimiter := middleware.NewRateLimiter(redisClient, config)

// gRPC interceptor chain
grpcSrv := grpc.NewServer(
    grpc.ChainUnaryInterceptor(
        rateLimiter.Unary(),      // Rate limit FIRST
        authInterceptor.Unary(),  // Auth second
    ),
)

Frontend Integration

// Automatic retry on rate limit
import { withRateLimitRetry } from '@/lib/rate-limit-handler'

const result = await withRateLimitRetry(async () => {
  return await fetch('/api/endpoint')
})
// Retries 3x with backoff: 1s β†’ 2s β†’ 4s

// Toast notification
import { useRateLimitToast } from '@/components/ui/rate-limit-toast'

const { toast, showToast } = useRateLimitToast()
if (isRateLimited) {
  showToast("Rate limit reached, retrying in 3s...", 3)
}

Performance

πŸ“„ Complete Guide: See rate-limiting.html for detailed documentation with examples, testing, and monitoring.

πŸ€– AI Chatbot Enhanced

Overview

Natural language interface for financial queries. Powered by OpenAI with context-aware function calling.

Features

Available Functions

Function Purpose
get_dashboard_statsRevenue, expenses, profit overview
list_transactionsRecent transactions with filters
get_revenue_trendTime-series revenue analysis
get_expense_breakdownCategory-wise expense breakdown
search_paymentsFind specific payments
get_mrr_reportMonthly recurring revenue metrics

Usage

// Frontend - Chat with AI
import { accountingClientBrowser } from '@/lib/connect-rpc-browser'

const stream = accountingClientBrowser.chatWithAI({
  tenantId: 'uuid',
  sessionId: 'uuid',
  userMessage: 'What was my revenue last month?'
})

for await (const response of stream) {
  console.log(response.assistantMessage)
}

πŸ”Œ Integrations Active

Supported Providers

Provider Type Features
Paystack API + CSV Live sync, transaction history, webhooks
Stripe CSV Balance history import, template matching
Flutterwave CSV Transaction export import
Square CSV Payment export import
Generic CSV Any provider with AI mapping

Integration Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     Integration Manager                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  API Sync    β”‚   β”‚  CSV Import  β”‚  β”‚
β”‚  β”‚  (Paystack)  β”‚   β”‚  (All)       β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚         β”‚                  β”‚           β”‚
β”‚         β–Ό                  β–Ό           β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  ExternalTransactionSource      β”‚  β”‚
β”‚  β”‚  (Deduplication & Linking)      β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚         β”‚                               β”‚
β”‚         β–Ό                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Payment & Journal Entry        β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Dual Entry Points

πŸ’‘ Duplicate Prevention: CSV imports create ExternalTransactionSource records to prevent re-import via API sync. Reference column becomes ExternalID for uniqueness.

πŸ“Š Pitch Deck Generation Active

Overview

AI-generated investor pitch decks with live financial metrics. Connect data sources, answer questions, get presentation-ready slides.

Features

Data Sources

βš™οΈ Backend Services

Service Architecture

backend/
β”œβ”€β”€ cmd/
β”‚   └── server/
β”‚       └── main.go              (gRPC server, interceptors)
β”œβ”€β”€ internal/
β”‚   β”œβ”€β”€ accountingserver/        (20+ gRPC handlers)
β”‚   β”‚   β”œβ”€β”€ accounts.go
β”‚   β”‚   β”œβ”€β”€ payments.go
β”‚   β”‚   β”œβ”€β”€ journalentries.go
β”‚   β”‚   β”œβ”€β”€ reconciliation.go
β”‚   β”‚   β”œβ”€β”€ ai_agent.go
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ services/                (Business logic)
β”‚   β”‚   β”œβ”€β”€ import_parser_service.go
β”‚   β”‚   β”œβ”€β”€ import_mapper_service.go
β”‚   β”‚   β”œβ”€β”€ import_service.go
β”‚   β”‚   β”œβ”€β”€ ai_agent_service.go
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”œβ”€β”€ ratelimit.go         (Rate limiting)
β”‚   β”‚   └── auth.go              (JWT validation)
β”‚   β”œβ”€β”€ database/
β”‚   β”‚   └── database.go          (GORM setup)
β”‚   └── models/
β”‚       └── models.go            (50+ database models)
└── proto/
    └── accounting.proto         (gRPC definitions)

Key Services

Service Purpose LOC
ImportParserServiceCSV/Excel parsing & validation400
ImportMapperServiceAI/template column mapping500
ImportServiceImport workflow orchestration400
AIAgentServiceChatbot with function calling600
PaymentServicePayment CRUD & reconciliation300
JournalServiceDouble-entry accounting450

Database Models (50+)

🎨 Frontend App

Tech Stack

Structure

frontend/src/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ (auth)/
β”‚   β”‚   β”œβ”€β”€ login/page.tsx
β”‚   β”‚   └── register/page.tsx
β”‚   └── dashboard/
β”‚       β”œβ”€β”€ page.tsx              (dashboard)
β”‚       β”œβ”€β”€ payments/
β”‚       β”œβ”€β”€ journal-entries/
β”‚       β”œβ”€β”€ accounts/
β”‚       β”œβ”€β”€ data-imports/
β”‚       β”œβ”€β”€ integrations/
β”‚       └── settings/
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ ui/                       (shadcn components)
β”‚   β”œβ”€β”€ dashboard/
β”‚   β”œβ”€β”€ data-imports/
β”‚   └── pitch-deck/
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ connect-rpc-browser.ts   (gRPC client)
β”‚   β”œβ”€β”€ rate-limit-handler.ts
β”‚   └── api/
β”‚       └── imports.ts
β”œβ”€β”€ hooks/
β”‚   └── use-imports.ts           (React hooks)
└── gen/
    β”œβ”€β”€ accounting_pb.ts         (Protobuf messages)
    └── accounting_connect.ts    (gRPC service)

πŸ—„οΈ Database Schema

Core Tables

-- Tenants & Users
tenants (id, name, base_currency, created_at)
users (id, email, password_hash, created_at)
tenant_memberships (tenant_id, user_id, role)

-- Accounting
accounts (id, tenant_id, name, type, code, parent_id)
transactions (id, tenant_id, amount, date, type, status)
payments (id, tenant_id, amount, date, type, payment_method)
journal_entries (id, tenant_id, date, description, status)
journal_lines (entry_id, account_id, debit, credit)

-- Data Imports
import_sessions (id, tenant_id, filename, status, total_rows)
import_field_mappings (id, session_id, source_column, target_field)
import_errors (id, session_id, row_number, error_message)
import_templates (id, name, provider, column_mappings)
mapping_cache (cache_key, mapping_result, expires_at)

-- Integrations
integrations (id, tenant_id, provider, status, credentials)
external_transaction_sources (integration_id, external_id, transaction_id)

-- AI & Analytics
ai_query_history (id, tenant_id, user_id, query, response)
subscriptions (id, tenant_id, plan, mrr, status)
pitch_data (tenant_id, data_type, content)

πŸš€ Production Deployment

Deployment Script

# Install dependencies
./deploy.sh install

# Deploy to production
./deploy.sh deploy

# Setup SSL certificate
./deploy.sh ssl yourdomain.com

# Status check
./deploy.sh status

Docker Compose Services

Service Image Purpose
frontendnode:18-alpineNext.js app
backendgolang:1.25-alpinegRPC server
extractorgolang:1.25-alpineDocument AI
postgrespostgres:15-alpineDatabase
redisredis:7-alpineCache & rate limiting
nginxnginx:alpineReverse proxy

Environment Variables

# Backend (.env)
DATABASE_URL=postgres://user:pass@postgres:5432/invoicepro
REDIS_URL=redis://redis:6379
JWT_SECRET=your-secret-key
OPENAI_API_KEY=sk-...
PAYSTACK_SECRET_KEY=sk_...

# Frontend (.env.local)
NEXT_PUBLIC_GRPC_WEB_URL=http://localhost:8080
NEXT_PUBLIC_API_URL=http://localhost:3000/api

Resource Limits (Optimized for $6-24/mo droplets)

Service CPU Memory
Frontend0.5512MB
Backend1.01GB
Extractor0.5512MB
PostgreSQL1.01GB
Redis0.25256MB
Nginx0.25128MB

πŸ“Š Monitoring

Health Checks

# Check all services
docker-compose ps

# View logs
docker-compose logs -f backend
docker-compose logs -f frontend

# Database connection
docker-compose exec postgres psql -U postgres -d invoicepro

# Redis status
docker-compose exec redis redis-cli INFO

Key Metrics

⚠️ Important:
  • Always backup PostgreSQL before major updates
  • Monitor disk usage (imports create temp files)
  • Set up log rotation for Docker containers
  • Test SSL renewal process (Let's Encrypt auto-renews)

Invoice Pro Documentation | Complete Implementation Guide | 2025
For detailed rate limiting documentation, see rate-limiting.html