Skip to content

overview architecture

Douwe de Vries edited this page Jul 1, 2026 · 2 revisions

Architecture

CSV Align has one shared Rust backend with two app shells. Browser mode reaches that backend through Axum routes in src/api/app.rs; desktop mode reaches it through Tauri commands in src-tauri/src/commands.rs.

Component map

graph TD
    subgraph Frontend
        App[frontend/src/App.tsx]
        Workflow[frontend/src/hooks/useComparisonWorkflow.ts]
        Transport[frontend/src/services/tauri.ts]
        Results[frontend/src/features/results]
    end
    subgraph WebRuntime[Local web runtime]
        Axum[src/main.rs and src/api/app.rs]
        Handlers[src/api/handlers.rs]
    end
    subgraph DesktopRuntime[Desktop runtime]
        TauriMain[src-tauri/src/main.rs]
        Commands[src-tauri/src/commands.rs]
    end
    subgraph SharedRust[Shared Rust crate]
        Store[src/backend/store.rs]
        WorkflowRust[src/backend/workflow.rs]
        Data[src/data]
        Compare[src/comparison]
        Presentation[src/presentation/responses.rs]
    end
    App --> Workflow
    Workflow --> Transport
    Transport -->|HTTP in browser| Axum
    Axum --> Handlers
    Transport -->|invoke in desktop| Commands
    TauriMain --> Commands
    Handlers --> Store
    Commands --> Store
    Store --> WorkflowRust
    WorkflowRust --> Data
    WorkflowRust --> Compare
    WorkflowRust --> Presentation
    Results --> Transport
Loading

Request and comparison flow

sequenceDiagram
    participant UI as React UI
    participant Transport as frontend/src/services/tauri.ts
    participant API as HTTP or Tauri command
    participant Store as src/backend/store.rs
    participant Workflow as src/backend/workflow.rs
    participant Engine as src/comparison/engine.rs

    UI->>Transport: createSession()
    Transport->>API: POST /api/sessions or create_session
    API->>Store: create()
    Store-->>API: session id
    UI->>Transport: loadFile(File A/B)
    Transport->>API: multipart bytes or load_csv_bytes
    API->>Workflow: load_csv_workflow()
    Workflow->>Store: store parsed CsvData
    UI->>Transport: compareFiles(request)
    Transport->>API: compare route or command
    API->>Workflow: run_comparison_for_session()
    Workflow->>Engine: try_compare_csv_data()
    Engine-->>Workflow: RowComparisonResult list
    Workflow-->>UI: serialized CompareResponse
Loading

Shared backend

src/lib.rs exports the public crate modules: api, backend, comparison, data, and presentation. The backend code is deliberately transport-agnostic. src/backend/store.rs is synchronous and protected by parking_lot::RwLock, so Axum can wrap heavy work in spawn_blocking while Tauri commands can call the same workflows directly.

The comparison path uses these layers:

Layer Files Responsibility
Request validation src/backend/validation.rs, src/backend/requests.rs Converts user input into a checked ComparisonConfig.
CSV data src/data/types.rs, src/data/csv_loader.rs, src/data/json_fields.rs Represents loaded rows, physical columns, virtual JSON columns, and detected column types.
Matching src/comparison/engine.rs, src/comparison/rows.rs Splits rows by usable keys, handles duplicates, and matches exact or flexible keys.
Value comparison src/comparison/value_compare.rs Applies cleanup rules and reports per-column differences.
Response shape src/presentation/responses.rs Serializes Rust domain results into frontend API contracts.

Frontend shape

The React app is workflow-first rather than route-first. frontend/src/App.tsx renders three steps from state returned by frontend/src/hooks/useComparisonWorkflow.ts. That hook composes smaller action hooks:

  • frontend/src/hooks/useWorkflowSessionLifecycle.ts creates and deletes backend sessions.
  • frontend/src/hooks/useWorkflowComparisonActions.ts loads files, suggests mappings, runs comparisons, and handles auto-pair.
  • frontend/src/hooks/useWorkflowPersistenceActions.ts saves and loads pair-order files, snapshots, CSV exports, and HTML exports.
  • frontend/src/hooks/useWorkflowNavigation.ts controls which step is unlocked.

Result rendering is concentrated in frontend/src/features/results/presentation.ts, frontend/src/features/results/search.ts, and frontend/src/components/ResultsTable.tsx.

API parity

The transport constants are split by runtime: browser routes are in frontend/src/services/apiRoutes.ts, and Tauri command names are in frontend/src/services/tauriCommands.ts. The Rust side mirrors those lists in src/api/app.rs and src-tauri/src/main.rs. Parity is tested by tests/transport_parity_integration.rs and src-tauri/src/tests.rs.

See transport parity and API for the contract details.

Codebase size snapshot

As of 2026-07-01, the repository has about 17.1k Rust source lines, 14.5k TypeScript/TSX source lines, 2.4k Python script lines, and 1.4k CSS lines, excluding generated files, lockfiles, build output, samples, and icons. The current code has 179 public Rust items and 160 exported TypeScript symbols. See by the numbers for the full snapshot.

Key source files

File Purpose
src/lib.rs Shared crate module boundary.
src/main.rs Axum local web runtime.
src/api/app.rs HTTP route definitions and frontend static serving.
src/api/handlers.rs HTTP handlers that call backend workflows.
src-tauri/src/main.rs Tauri command registration and desktop SessionStore setup.
src-tauri/src/commands.rs Tauri command implementations and native file dialogs.
frontend/src/services/tauri.ts Runtime transport selection.

Clone this wiki locally