Skip to content

Latest commit

 

History

History
124 lines (90 loc) · 4 KB

File metadata and controls

124 lines (90 loc) · 4 KB

2ASK Ledger

An AI CFO for freelancers, consultants, and small agencies. Upload bank statements and invoices, get grounded answers about cash flow, GST, and overdue payments. Every document is SHA-256 anchored for a tamper-evident audit trail.

Stack

Frontend — React 19, React Router 7, Tailwind CSS, framer-motion, recharts, @react-oauth/google (for Gmail attachment import).

Backend — FastAPI, SQLite, pdfplumber for parsing, sentence-transformers (all-MiniLM-L6-v2) for embeddings with lexical fallback, Groq SDK (llama-3.3-70b-versatile) for reasoning.

Auth — JWT-based; demo mode bypasses login.

Prerequisites

  • Node.js 18+
  • Python 3.10+
  • A Groq API key (console.groq.com)
  • Optional: Google OAuth client ID for Gmail fetch

Configure

Create .env at the project root:

GROQ_API_KEY=your_groq_key_here
GROQ_MODEL=llama-3.3-70b-versatile    # optional override
REACT_APP_GOOGLE_CLIENT_ID=your_google_oauth_client_id
NEXT_PUBLIC_GOOGLE_CLIENT_ID=your_google_oauth_client_id
ALLOWED_ORIGINS=http://localhost:3000

Create frontend/.env (CRA only reads env files inside the frontend directory):

PORT=3000
REACT_APP_GOOGLE_CLIENT_ID=your_google_oauth_client_id

Install

npm run install:all

This creates backend/venv, installs Python requirements, and runs npm install in frontend/.

Run

npm run dev

Starts both servers concurrently:

Run them separately if you prefer:

npm run backend     # uvicorn on :8000
npm run frontend    # CRA on :3000

Routes

Path Purpose
/ Landing
/dashboard Bento-grid overview: inflow, health score, insights, calendar
/upload Ingest PDFs / CSVs
/transactions Parsed ledger rows
/invoices Invoice Studio with trust-hash footer
/audit Tamper-evident event log
/ask-cfo RAG-grounded chat
/planning GST and tax deadlines

Ask CFO pipeline

  1. User message is checked for smalltalk; greetings short-circuit without retrieval.
  2. retrieve_document_context runs vector search over uploaded PDFs/CSVs.
  3. Falls back to ledger context (transactions, invoices, proofs) if no documents.
  4. Retrieved chunks + a structured financial summary are sent to Groq.
  5. Response is parsed as JSON with answer, why, supporting_items.

If LM Studio is running on localhost:1234, the backend uses it instead of Groq.

Project layout

backend/
  main.py              # FastAPI app + dotenv loader
  routers/             # auth, dashboard, finance, cfo, invoices, audit
  services/
    finance_service.py # ask_cfo, totals, GST, intent routing
    rag_service.py     # embedding + retrieval
    gemma_service.py   # LLM fallback chain (LM Studio -> Groq)
    llm_service.py     # Groq client wrapper
  models/              # SQLite schema
  scripts/             # seed / reset utilities

frontend/
  src/
    App.js
    context/AppStateContext.jsx   # persistent chat + dashboard state
    pages/                        # Dashboard, AskCFO, UploadCenter, ...
    components/                   # Sidebar, TopNav, GmailFetchButton
    api.js                        # fetch wrappers

Troubleshooting

  • {"detail":"Not Found"} at localhost:8000 — you're hitting the backend. The app is on :3000.
  • "Unable to generate response" / "LLM service unavailable"GROQ_API_KEY missing or the model is decommissioned. Check Groq deprecations.
  • "OAuth client was not found"REACT_APP_GOOGLE_CLIENT_ID not set in frontend/.env, or http://localhost:3000 is not an authorized JavaScript origin on the client.
  • Backend killed with exit 137 — macOS low-memory kill. Close other apps or run backend / frontend in separate terminals.

Reset demo state

npm run reset:zero

Wipes backend/generated/, clears the SQLite DB, and seeds a clean state.