Skip to content

Low-Level Design (LLD)

Backend service composition, scheduled task flow, and authentication.

Backend service map

flowchart LR
    subgraph api[FastAPI app]
        RT[api/v1/router.py<br/>~73 sub-routers]
        AUTH[core/auth.py<br/>JWT + password login]
        MW[Org middleware<br/>X-Organization-Id]
    end

    subgraph svc[Services layer]
        APW[ap_workflow<br/>invoice intake → ERP post]
        ERS[erp_sync<br/>orchestrator]
        ERA[erp_adapters<br/>Zoho/QB/NetSuite/Oracle]
        MATCH[canonical_matching<br/>entity mapping]
        WFE[workflow_executor<br/>approval handlers]
        AG[agents framework<br/>tools + MCP]
    end

    subgraph store[State]
        PG[(PostgreSQL<br/>RLS by organization_id)]
        RD[(Redis)]
    end

    RT --> AUTH --> MW --> APW & ERS & WFE & AG
    APW --> ERA
    ERS --> ERA
    WFE --> MATCH
    APW & ERS & WFE & MATCH & AG --> PG
    AG --> RD

Scheduled task flow (Celery + Redis)

sequenceDiagram
    participant Beat as Celery Beat (60s tick)
    participant Q as Redis queues
    participant W as Celery worker
    participant DB as PostgreSQL
    participant ERP as External ERP/Billing

    Beat->>DB: query due scheduled_tasks / sync configs
    Beat->>Q: enqueue run task (erp_sync_runs / agents)
    W->>Q: consume task
    W->>ERP: fetch records (OAuth / API key, TLS)
    W->>DB: write replica rows + audit log
    W->>DB: update sync_history / job status

Authentication flow

sequenceDiagram
    participant U as User
    participant API as FastAPI /auth
    participant RL as Login rate limiter (Redis)
    participant DB as PostgreSQL

    U->>API: POST /auth/login (email, password)
    API->>RL: check_not_locked(email)
    alt locked
        RL-->>API: AccountLockedError
        API-->>U: 429 + Retry-After
    else not locked
        API->>DB: get_user_by_email
        API->>API: bcrypt verify_password
        alt success
            API->>RL: reset(email)
            API-->>U: 200 + JWT (signed, exp)
        else failure
            API->>RL: record_failure(email)
            API-->>U: 401
        end
    end

Notes

  • Queues — workers consume erp_sync_default, erp_sync_runs, default, agents (launched via start-worker.sh). Celery -Q does not glob.
  • Password policy — enforced at registration via core/password_policy.py; lockout via core/login_rate_limit.py.
  • Agent tools — local tool registry + MCP servers (per-org credentials injected).