Skip to content

System Architecture

Overview

graph TB
    subgraph External
        CIN7[Cin7 ERP<br/>Source of Truth]
    end

    subgraph Data Pipeline
        AIRFLOW[Apache Airflow<br/>Nightly ETL]
    end

    subgraph Azure Cloud
        DB[(Azure SQL Database<br/>Cin7_PO_Headers<br/>Cin7_PO_Lines)]
        API[Azure Functions<br/>Node.js API]
        SWA[Azure Static Web Apps<br/>React Frontend]
    end

    subgraph Auth
        AAD[Microsoft Entra ID<br/>Azure AD B2C]
    end

    CIN7 -->|SP-API / Export| AIRFLOW
    AIRFLOW -->|MERGE Upsert| DB
    DB --> API
    API --> SWA
    AAD -->|MSAL Auth| SWA
    AAD -->|JWT Validation| API

Technology Stack

Layer Technology Purpose
Frontend React + TypeScript + Tailwind CSS User interface
API Azure Functions (Node.js) Backend REST API
Database Azure SQL Database Data storage
Auth Microsoft Entra ID (Azure AD B2C) + MSAL Authentication
Hosting Azure Static Web Apps Frontend + API hosting
Data Pipeline Apache Airflow Nightly Cin7 → SQL sync
Source Control GitHub Code repository

Data Flow

Nightly Sync (Cin7 → Database)

  1. Airflow DAG triggers at scheduled time
  2. Extracts PO data from Cin7 via SP-API
  3. Transforms and loads into Azure SQL using MERGE upsert
  4. Only updates Cin7-sourced columns — preserves app-owned columns (vendor replies, status, etc.)

User Interactions (Browser → API → Database)

  1. User authenticates via MSAL → receives JWT token
  2. Frontend sends API requests with JWT in X-User-Token header
  3. API validates token, extracts user role and vendor code
  4. API executes SQL queries with role-based filtering
  5. Response returned to frontend for rendering

Key Design Decisions

Dual-Column Pattern

Each editable field has two columns: the original Cin7 value and the vendor's reply value. Example: xfd (original) and vendor_reply_xfd (vendor edit). This preserves the source of truth while tracking changes.

State Machine Engine

All status transitions go through a single executeTransition() function that validates against the Ref_PO_Transitions table. This ensures no invalid status changes can occur.

Role-Based Access Control

Three roles (Vendor, Manager, Admin) with hierarchy: Admin > Manager > Vendor. Vendors are scoped to their own company's POs via billing_company filtering.

AI Chat Architecture

The Data Assistant strictly operates over the Azure Functions API utilizing OpenAI's models (gpt-4o-mini). It includes comprehensive PII masking, an Agentic SQL fallback engine, and an observability loop to continually capture structured analytical data that guides improvement.

sequenceDiagram
    participant User as Frontend (User)
    participant API as Azure Functions (/api/chat)
    participant DB as Azure SQL Database
    participant LLM as OpenAI (gpt-4o-mini)

    User->>API: 1. Send Question
    Note over API: 2. Enforce RBAC & Mask PII
    API->>LLM: 3. Pass 1: Request tool calls
    LLM-->>API: Returns standard function or 'run_analysis'

    alt Standard Tool (e.g., get_po_count)
        API->>DB: 4a. Execute parameterized query (scoped)
    else Agentic SQL Fallback (run_analysis)
        Note over API: 4b. Validate SQL Safety & Scope
        API->>DB: 4c. Execute dynamically generated SQL
    end

    DB-->>API: Returns records
    Note over API: 5. Backend Rule Engine <br/>generates Custom ECharts config
    API->>LLM: 6a. Pass 2: Send data for summarization
    LLM-->>API: 6b. Returns natural language summary
    Note over API: 7. Zod Output Guardrails & Unmask PII
    API-->>User: 8. Returns Response (Typewriter Text + Chart Data)
    Note over API: 9. Telemetry logging saves to DB <br/>with auto_score evaluation