Ledgerify README

The project's README from github.com/AhmadHassan-BTed/Ledgerify. As one markdown file: README.md.

Ledgerify Logo

Ledgerify

Client-Side Shopify Ledger Intelligence & Multi-Department Analytics

A resilient, browser-native analytics platform engineered for complex Shopify Excel exports. Built with an Obsidian dark interface, zero-backend architecture, dynamic schema normalization, and multi-departmental intelligence.

TypeScript React Vite TailwindCSS License Build Status

Live Demonstration • System Architecture • Contributing


Overview

Modern e-commerce ledgers generated by Shopify exports often contain irregular schemas, composite product bundles, inconsistent date serials, and fragmented departmental requirements. Ledgerify was created to solve this problem entirely on the client side.

By combining browser-native SheetJS parsing, resilient schema normalization, and an Inversion-of-Control (IoC) dependency injection container, Ledgerify transforms raw, multi-megabyte Excel spreadsheets into structured domain intelligence across eight specialized organizational roles without sending data to an external server.

The platform provides human-centric visibility: leaders and operators receive clear, synthesized conclusions rather than being overwhelmed by raw tabular data.


Architectural Principles

Ledgerify is built upon three core engineering pillars:

  1. Separation of Concerns (SoC): Strict isolation between parsing, storage, domain metric calculation, and UI presentation.
  2. Dependency Injection (DI): Business logic resides in decoupled domain services injected through a lightweight IoC container.
  3. Zero-Knowledge Privacy: 100% client-side computation. Workbooks are parsed in-memory, cached in browser IndexedDB, and never transmitted over the network.

Architecture Overview

For the comprehensive technical specification, class diagrams, normalization rules, and state management flow, see ARCHITECTURE.md.

flowchart TD
    subgraph ClientLayer["Client Layer (Browser Runtime)"]
        A["User Upload (.xlsx / .csv)"] --> B["IFileParser (SheetJS Engine)"]
        B --> C["Resilient Normalizer & Header Mapper"]
        C --> D["Domain Entities (NormalizedOrder[])"]
        D --> E["IStorageService (IndexedDB Cache)"]
    end

    subgraph ServiceLayer["Domain & Service Layer (IoC Container)"]
        E --> F["Dependency Injection Container"]
        F --> G1["ExecutiveService"]
        F --> G2["FinanceService"]
        F --> G3["InventoryService"]
        F --> G4["OperationsService"]
        F --> G5["MarketingService"]
        F --> G6["CreativeService"]
        F --> G7["AdminDataQualityService"]
        F --> G8["CompareService"]
    end

    subgraph PresentationLayer["Presentation Layer (Obsidian UI)"]
        G1 & G2 & G3 & G4 & G5 & G6 & G7 & G8 --> H["React Context Providers"]
        H --> I["Departmental View Controllers"]
        I --> J["Interactive Visualizations & Drill-Downs"]
    end

Data Flow & Normalization Pipeline

Raw Shopify exports exhibit variations across stores, countries, and export configurations. The normalization pipeline dynamically detects headers, reconciles currency formats, and structures composite line items.

flowchart LR
    A["Raw Workbook Buffer"] --> B["Workbook Sheet Discovery"]
    B --> C["Header Fuzzy Normalization"]
    C --> D["Value Sanitization & Type Coercion"]
    D --> E["Compound Bundle Splitting"]
    E --> F["Flag & Anomaly Tagging"]
    F --> G["NormalizedOrder Schema"]

    subgraph NormalizationLogic["Transformation Rules"]
        C -.- C1["Case & whitespace agnostic regex matching"]
        D -.- D1["Excel serial date to ISO UTC conversion"]
        E -.- E1["Extracts individual bottles from Discovery/Trio sets"]
        F -.- F1["Identifies $0 test orders, missing emails, spike quantities"]
    end

Request & Parsing Lifecycle

When an operator uploads a workbook or toggles between datasets, the execution flow follows a deterministic, non-blocking lifecycle:

sequenceDiagram
    autonumber
    actor User as Operator
    participant UI as Dashboard UI
    participant Parser as File Parser (SheetJS)
    participant Normalizer as Schema Normalizer
    participant Storage as IndexedDB Storage
    participant DI as IoC Container
    participant Services as Domain Services

    User->>UI: Selects .xlsx / .csv file
    UI->>Parser: Passes ArrayBuffer
    Parser->>Normalizer: Streams raw sheet records
    Normalizer->>Normalizer: Resolves dynamic column mappings
    Normalizer->>Normalizer: Extracts category yields & anomalies
    Normalizer-->>Storage: Persists NormalizedDataset
    Normalizer-->>DI: Injects Active Dataset State
    DI->>Services: Trigger reactive metric calculation
    Services-->>UI: Dispatches aggregated view models
    UI-->>User: Renders Obsidian dashboards with 0ms server latency

Module Relationship & Dependency Injection

The application decouples interface components from domain calculation algorithms through the Service Context and IoC Container.

classDiagram
    class IFileParser {
        <<interface>>
        +parse(file: File): Promise~NormalizedOrder[]~
    }

    class IStorageService {
        <<interface>>
        +saveDataset(dataset: Dataset): Promise~void~
        +getDatasets(): Promise~Dataset[]~
        +deleteDataset(id: string): Promise~void~
    }

    class ServiceContainer {
        +financeService: FinanceService
        +executiveService: ExecutiveService
        +inventoryService: InventoryService
        +operationsService: OperationsService
        +marketingService: MarketingService
        +creativeService: CreativeService
        +adminService: AdminDataQualityService
        +compareService: CompareService
    }

    class DataProvider {
        +activeDataset: Dataset
        +filteredOrders: NormalizedOrder[]
        +setFilter(filter: FilterState): void
    }

    ServiceContainer --> FinanceService
    ServiceContainer --> ExecutiveService
    ServiceContainer --> InventoryService
    ServiceContainer --> OperationsService
    ServiceContainer --> MarketingService
    DataProvider ..> ServiceContainer : Consumes via Context
    IFileParser <|.. XlsxParser
    IStorageService <|.. IndexedDbStorage

Build & Deployment Pipeline

Ledgerify utilizes automated continuous integration via GitHub Actions, compiling TypeScript bundles and deploying static assets to GitHub Pages.

flowchart TD
    subgraph GitRepository["Git Repository"]
        A["Push to main branch"] --> B["GitHub Actions Triggered"]
    end

    subgraph CIWorkflow["CI / CD Pipeline"]
        B --> C["Setup Node.js Runtime"]
        C --> D["npm ci (Deterministic Dependency Tree)"]
        D --> E["tsc --noEmit (Type Integrity Validation)"]
        E --> F["vite build (Production Minification)"]
        F --> G["Upload Artifact (dist/)"]
    end

    subgraph HostingInfrastructure["Edge Hosting"]
        G --> H["Deploy to GitHub Pages Environment"]
        H --> I["Public Release (HTTPS / Global CDN)"]
    end

Departmental Perspectives

Ledgerify structures analytical output into eight dedicated dashboards, each aligned with specific business functions:

View Perspective Target Role Key Metrics & Visualizations Status
Executive CEO / Founders Month-over-Month trajectory, buyer retention rates, revenue pacing gauge, customer acquisition split. ✓
Finance CFO / Controller Gross ledger totals, net revenue, category yields (50ml, 100ml, Discovery, Trio), refund liabilities. ✓
Inventory Supply Chain / Ops Fragrance velocity meters, reorder urgency triage, composite set extraction, physical bottle share. ✓
Operations Warehouse / Fulfillment Day-of-week dispatch heatmap, shipping province hotspots, multi-box packing complexity ratios. ✓
Marketing Growth / Performance High-value customer tiers, geographic ad allocation, cart co-purchase affinity matrix, repeat cohorts. ✓
Creative Design & Studio Visual brief generators, hero product identification, packaging style trends, scent keyword demand. ✓
Admin Quality Data Engineers Automated health scores, missing field audits, test order isolation, quantity spike detection. ✓
Comparison Strategy & Finance Side-by-side multi-file benchmarking, variance delta calculations, dual-series curves. ✓

Technical Specifications

Schema & Field Normalization Specifications

Supported Input Columns (Fuzzy Matched)

The normalizer handles varied naming conventions across Shopify CSV and Excel exports:

  • Order Identifier: Name, Order ID, Order Number, #, Invoice ID
  • Timestamp: Created at, Order Date, Date, Processed at, Sale Date
  • Customer Email: Email, Customer Email, Contact Email
  • Financial Status: Financial Status, Payment Status, Status
  • Total Amount: Total, Total Amount, Gross Sales, Net Sales, Subtotal
  • Item Summary: Lineitem name, Item Name, Items, Products, Description
  • Quantity: Lineitem quantity, Total Quantity, Quantity, Qty
  • Shipping Destination: Shipping City, City, Shipping Province, State, Region
Local Storage & Security Architecture

Client-Side Isolation

  • Storage Layer: IndexedDB database (LedgerifyDB) operating within origin sandboxing.
  • Data Retention: Workbooks persist locally in the operator's browser session or local storage cache.
  • Zero Third-Party Tracking: No analytics scripts, remote beacons, or external telemetries are bundled.

Repository Structure

Ledgerify/
├── .github/
│   └── workflows/
│       └── deploy.yml              # GitHub Actions Pages deployment pipeline
├── scripts/
│   ├── inspect.js                  # CLI utility for workbook inspection
│   └── inspect_sheets.js           # Multi-sheet diagnostic analyzer
├── src/
│   ├── components/
│   │   ├── charts/                 # Recharts components (Area, Bar, Donut, Multi-Series)
│   │   ├── layout/                 # Top navigation, dataset switcher, theme controls
│   │   ├── ui/                     # Atomic UI cards, heatmaps, gauges, tables
│   │   └── views/                  # 8 departmental dashboard implementations
│   ├── context/
│   │   ├── DataContext.tsx         # Dataset state and upload orchestrator
│   │   ├── FilterContext.tsx       # Date, search, and category filter provider
│   │   ├── ServiceContext.tsx      # Dependency injection context provider
│   │   └── ThemeContext.tsx        # Obsidian dark / light mode manager
│   ├── core/
│   │   ├── di/
│   │   │   └── container.ts        # IoC Service Container
│   │   ├── parser/
│   │   │   ├── IFileParser.ts      # Parser contract
│   │   │   ├── normalizer.ts       # Resilient header & entity normalizer
│   │   │   └── xlsxParser.ts       # SheetJS workbook parser
│   │   ├── services/               # Pure departmental calculation services
│   │   └── storage/                # IndexedDB persistence adapter
│   ├── styles/
│   │   └── themes/                 # CSS theme definitions and role accents
│   ├── types/                      # Domain interfaces and analytics models
│   ├── App.tsx                     # Root application container
│   ├── index.css                   # Obsidian design tokens and base styles
│   └── main.tsx                    # Application entry point
├── package.json                    # Project manifests and scripts
├── tsconfig.json                   # TypeScript compiler configuration
└── vite.config.ts                  # Vite build bundler configuration

Development Workflow

Prerequisites

Local Setup

# Clone the repository
git clone https://github.com/AhmadHassan-BTed/.github.git Ledgerify
cd Ledgerify

# Install dependencies deterministically
npm ci

# Start the local development server
npm run dev

The application will be accessible at http://localhost:5173. A sample ledger is pre-bundled for instant local evaluation.

Verification & Production Build

# Execute TypeScript type validation and Vite production bundling
npm run build

# Preview production build locally
npm run preview

Contributing and Standards

Contributions adhering to strict engineering standards are welcomed. When submitting changes:

  1. Maintain complete Separation of Concerns: calculation logic belongs in core/services/, not inside presentation components.
  2. Ensure strict TypeScript type safety without the use of any overrides where domain models exist.
  3. Validate that parsing resilience handles corrupted inputs, $0 test orders, and missing columns without runtime exceptions.
  4. Verify that npm run build passes with zero errors before opening pull requests.

Author & Attribution

Engineered and designed by Ahmad Hassan (B-Ted).


License

This project is open-source software licensed under the MIT License.

Ledgerify (AhmadHassan-BTed/Ledgerify)

Searching Database…

What is this?Ledgerify is a browser-native analytics platform that parses Shopify Excel ledger exports and turns them into structured dashboards for eight different business functions (executive, finance, inventory, operations, marketing, creative, data quality, and comparison), all without a backend server.
Is this a hosted service or something I run myself?It is a client-side React web app with zero backend: you open it in a browser, upload your Excel workbook, and everything is parsed and stored locally in IndexedDB.
How do I get it running?Clone the repo, install dependencies with npm, and run the local dev server; a sample ledger is pre-bundled so you can try it instantly without uploading your own file.
What do I need installed before running it?Node.js 20.0 or higher and npm 9.0 or higher.
Does it handle messy or inconsistent Shopify exports?It is built specifically for that: a fuzzy-matching normalization pipeline reconciles different column names, currency formats, and composite line items across stores, and the Admin Quality dashboard flags missing fields, test orders, and quantity spikes.
Who is this dashboard set built for?Eight organizational roles are covered out of the box: CEO/Founders, CFO/Controller, Supply Chain/Ops, Warehouse/Fulfillment, Growth/Performance, Design & Studio, Data Engineers, and Strategy/Finance.
Does my Shopify sales data get uploaded anywhere?No. Workbooks are processed entirely in-browser and cached in a local IndexedDB database; no analytics scripts, tracking beacons, or external calls are bundled.
Can I compare two different ledger exports side by side?Yes, the Comparison dashboard runs side-by-side multi-file benchmarking with variance delta calculations and dual-series curves.
What file formats can I upload?It is designed for Shopify Excel exports (multi-sheet workbooks) and CSV files, parsed client-side using browser-native SheetJS parsing.
How is the codebase organized internally?It follows strict Separation of Concerns, with domain calculation logic living in core/services/ and injected into UI components through a lightweight IoC/dependency-injection container rather than mixed into presentation code.
Size
0.8 MB
Stars
1.1K
Updated
CommitOct 13
Age
3mo
Commits · 90 Days