Skip to content

MAITRI137/Odoo-hackathon-project

Repository files navigation

ExpenseFlow

ExpenseFlow is a production-minded reimbursement management system built for the Reimbursement Management problem statement. It replaces slow, error-prone manual reimbursement handling with OCR-assisted receipt capture, role-based approval routing, audit visibility, real-time currency normalization, and a cleaner enterprise UI in a single Next.js 14 application.

Our team built ExpenseFlow with a strong focus on:

  • dynamic runtime data instead of static JSON
  • responsive and clean UI
  • robust validation and role-based access control
  • intuitive navigation
  • local-first and offline-friendly behavior where practical
  • clean repository structure and clear documentation

Quick Start

The fastest way to run ExpenseFlow is with Docker Compose.

docker compose up --build

After the container is healthy, open:

  • http://localhost:3000

If port 3000 is already in use on your machine, Compose also supports a one-line override:

APP_PORT=3001 docker compose up --build

PowerShell:

$env:APP_PORT="3001"
docker compose up --build

No separate PostgreSQL setup is required for the Docker path. The compose workflow runs the app in a single container with an embedded PostgreSQL instance, applies the Prisma schema automatically, seeds the demo dataset on first boot, and serves the application.

Demo Credentials

  • Admin: admin@expenseflow.demo / password123
  • Manager: manager1@expenseflow.demo / password123
  • Employee: employee1@expenseflow.demo / password123

Problem Statement

Companies often struggle with manual expense reimbursement processes that are:

  • time-consuming
  • error-prone
  • hard to audit
  • unclear for employees waiting on approvals
  • inconsistent when multi-level approval rules are involved

Typical pain points include:

  • no simple way to define approval flows based on thresholds
  • no flexible support for multi-level or conditional approvals
  • manual receipt handling
  • manual currency conversion for cross-border spending
  • weak status visibility for submitters and approvers

Solution Summary

ExpenseFlow centralizes the full reimbursement flow:

  • New companies are created automatically on first signup.
  • The company currency is derived from the selected country using the Rest Countries API.
  • Employees can create draft expenses, upload receipts, run OCR extraction, review the extracted values, and submit expenses for approval.
  • Managers and approvers receive approval requests in sequence or in parallel depending on rule settings.
  • Admins can manage users, reporting lines, approval rules, and override stuck or exceptional requests.
  • The product stores both original submitted currency values and company-base currency values using live exchange data with cache fallbacks.
  • Audit logs and in-app notifications make each workflow step visible.

Feature Coverage

Authentication and Company Setup

  • Credentials authentication with NextAuth.js v5
  • Signup flow with:
    • full name
    • email
    • conditional company name field for public email domains such as Gmail or Outlook
    • password
    • confirm password
    • country selection
  • Automatic company creation on first signup
  • Automatic admin user creation on first signup
  • Company base currency derived from live country/currency data
  • Forgot password flow with temporary password generation
  • SMTP-backed email sending when configured
  • In-app fallback for temporary passwords during local development when SMTP is not configured

Roles and Permissions

  • ADMIN
    • manage users
    • resend passwords for employees and managers from the users table
    • view the generated password in a persistent admin dialog and copy it directly
    • safely delete users who are not tied to historical workflow records
    • configure approval rules
    • view all company expenses
    • override any expense
  • MANAGER
    • review assigned approvals
    • approve or reject with comments
    • view direct-report expenses
  • EMPLOYEE
    • create draft expenses
    • upload receipts and use OCR
    • submit claims
    • view only their own expense history and approval trail

Approval Workflow

  • manager-first routing when enabled
  • sequential approval routing
  • parallel approval routing
  • minimum approval percentage rules
  • required approver override rules
  • hybrid workflows that combine sequence and conditional logic
  • approval audit logs
  • admin override route for final approval or rejection

Expenses and OCR

  • draft and submit flows
  • OCR receipt extraction with Tesseract.js
  • PDF first-page conversion before OCR
  • OCR extraction for:
    • amount
    • date
    • inferred category
    • currency
  • manual correction after OCR
  • in-form receipt preview while editing
  • click-to-enlarge receipt and PDF review
  • receipt preview in the detail view
  • receipt access directly from employee, manager, and admin list views
  • read-only lock after submission

Currency Handling

  • live exchange lookup using https://api.exchangerate-api.com/v4/latest/{BASE_CURRENCY}
  • cached FX responses in memory
  • persisted disk-backed FX cache for local resilience
  • original submitted currency preserved
  • converted company-base amount stored on the expense
  • warning fallback if live conversion is unavailable

UI and Experience

  • professional enterprise-style dashboard shell
  • persistent desktop sidebar
  • mobile bottom navigation
  • sticky glassmorphism header
  • notification bell with unread state
  • sortable tables
  • responsive layouts
  • breadcrumb navigation
  • subtle motion and entry animations
  • clean status badges and workflow stepper
  • glass surface treatment without over-styling or novelty visuals
  • shared read-only expense detail route for managers, admins, and employees

Notifications

  • in-app notification center in the top bar
  • new approval assignment notifications for approvers
  • approval progress notifications for employees
  • final approval or rejection notifications for employees
  • mark-one and mark-all-as-read behavior
  • persisted notification history in the database

Safety and Operational Hardening

  • Zod validation on client and server
  • strict TypeScript
  • authenticated OCR route
  • authenticated FX route
  • company-scoped queries
  • self-manager and simple reporting-cycle protection
  • transaction-based workflow state changes
  • indexed Prisma models for common list and status queries
  • disk-backed country and FX caches for local/offline resilience
  • security headers in Next.js config

Tech Stack

Layer Technology Version
Framework Next.js App Router 14.2.35
Language TypeScript 5.9.3
Styling TailwindCSS 3.4.18
Authentication next-auth 5.0.0-beta.30
ORM Prisma 6.17.1
Database PostgreSQL 14+
OCR tesseract.js 6.0.1
PDF conversion pdf-to-png-converter 3.14.0
Forms React Hook Form + Zod 7.72.0 / 4.3.6
Data fetching SWR 2.4.1
Email Nodemailer 7.0.13

Architecture Overview

App Structure

  • app/(auth) contains login, signup, and forgot-password flows
  • app/(dashboard) contains the authenticated role-based product shell
  • app/api/* contains API routes for auth, users, approvals, rules, expenses, notifications, and dashboard summaries
  • components/* contains UI primitives and domain-specific modules
  • lib/* contains shared backend logic including auth, OCR, caching, email, workflow logic, and notification helpers
  • prisma/* contains the schema and seed script

Approval Engine

lib/approvalEngine.ts is the core workflow module. It handles:

  • expense submission initialization
  • creation of approval requests
  • manager-first routing
  • sequential and parallel fan-out
  • percentage threshold checks
  • required approver overrides
  • final expense state changes
  • audit log creation
  • email notifications
  • in-app notification creation

Route handlers only validate input, authorize access, and delegate workflow logic to the engine.

OCR Pipeline

POST /api/expenses/ocr:

  1. validates the uploaded file and type
  2. stores the file locally in the configured uploads directory
  3. converts PDFs to an image buffer
  4. runs Tesseract OCR with a 30-second timeout
  5. extracts likely structured fields with receipt-focused heuristics
  6. returns OCR suggestions plus the stored receipt URL so the uploaded file can be reviewed immediately in the form

Caching Strategy

ExpenseFlow uses both in-memory and disk-backed caches:

  • countries:
    • live source: Rest Countries API
    • memory cache: 24 hours
    • disk cache fallback: .cache/expenseflow/countries.json
  • exchange rates:
    • live source: ExchangeRate API
    • memory cache: 1 hour per base currency
    • disk cache fallback: .cache/expenseflow/fx-<BASE>.json

This improves startup resilience and supports a more local-first setup instead of depending entirely on cloud availability.

Notification Flow

The notification system is intentionally lightweight and role-aware:

  • approvers receive notifications when a request is assigned
  • employees receive progress updates when an approver acts
  • employees receive a final notification when the expense is approved or rejected
  • notifications remain visible in the top-bar bell interface until marked read

Local Development Setup

Prerequisites

  • Node.js 18+
  • PostgreSQL 14+
  • Git

Steps

  1. Clone the repository.
  2. Install dependencies.
npm install
  1. Copy .env.example to .env.
  2. Fill the required values.
  3. Sync the database schema.
npm run db:push
  1. Seed the demo data.
npm run db:seed
  1. Start the development server.
npm run dev
  1. Open http://localhost:3000.

Docker Deployment

One-Command Submission Run

docker compose up --build

Optional port override when 3000 is busy:

APP_PORT=3001 docker compose up --build

PowerShell:

$env:APP_PORT="3001"
docker compose up --build

What Docker Compose Does

  • builds the app image
  • starts a single container
  • boots an embedded PostgreSQL server inside that container
  • applies the Prisma schema automatically
  • seeds the demo dataset on first run
  • serves the Next.js production build on port 3000

Docker Notes

  • no external database is required for the compose path
  • uploads and database state are persisted through named volumes
  • SMTP is optional; leave SMTP env values blank for local setup
  • the compose workflow is designed to keep setup simple for team handoff, mentor access, and demo runs

Environment Variables

Variable Required for Local Dev Description
DATABASE_URL Yes PostgreSQL connection string for Prisma
NEXTAUTH_SECRET Yes Session signing secret
NEXTAUTH_URL No Optional fixed public app base URL. Leave blank to let Auth.js use the incoming host dynamically, which works well with ngrok.
SMTP_HOST No SMTP host for real outgoing mail
SMTP_PORT No SMTP port
SMTP_USER No SMTP username
SMTP_PASS No SMTP password
SMTP_FROM No Sender identity
UPLOAD_DIR Yes Local uploads directory

Docker-Only Runtime Overrides

These are optional when using the provided docker-compose.yml because defaults are already included:

  • POSTGRES_DB
  • POSTGRES_USER
  • POSTGRES_PASSWORD
  • PGDATA
  • APP_PORT

API Reference

Authentication

  • POST /api/auth/register

    • Auth: public
    • Body: { fullName, email, companyName?, password, confirmPassword, country }
    • Response: company metadata and success message
  • POST /api/auth/forgot-password

    • Auth: public
    • Body: { email }
    • Response: success message, or a temporary password when SMTP is not configured

Users

  • GET /api/users

    • Auth: Admin
    • Response: company users with manager info
  • POST /api/users

    • Auth: Admin
    • Body: { name, email, role, managerId }
    • Response: user id, message, email status, and generated temporary password
  • PATCH /api/users/:id

    • Auth: Admin
    • Body: { name, role, managerId }
    • Response: success message
  • DELETE /api/users/:id

    • Auth: Admin
    • Response: success message
    • Notes: protected for users tied to expense, approval, audit, or rule history
  • POST /api/users/:id/send-password

    • Auth: Admin
    • Response: success message and the generated temporary password

Reference Data

  • GET /api/countries

    • Auth: public
    • Response: country list with currency metadata
  • GET /api/currencies?base=INR

    • Auth: authenticated
    • Response: live/cached FX payload and source

Expenses

  • GET /api/expenses

    • Auth: authenticated
    • Scope:
      • Employee: own expenses
      • Manager: direct-report expenses
      • Admin: all company expenses
  • POST /api/expenses

    • Auth: Employee
    • Body: { description, category, amount, currency, date, remarks, receiptUrl }
    • Response: created expense id and optional conversion warning
  • GET /api/expenses/:id

    • Auth: authenticated with role-based scope checks
    • Response: expense, approval requests, and audit log
  • PATCH /api/expenses/:id

    • Auth: Employee owner
    • Requirement: expense must be DRAFT
  • POST /api/expenses/:id/submit

    • Auth: Employee owner
    • Requirement: expense must be DRAFT
    • Side effects: audit log, approval requests, notifications, emails
  • POST /api/expenses/ocr

    • Auth: authenticated
    • Body: multipart upload with file
    • Response: OCR extraction payload for amount, date, currency, and category plus the stored receipt URL

Approvals

  • GET /api/approvals

    • Auth: Manager or Admin
    • Response: approvals assigned to the signed-in approver
  • PATCH /api/approvals/:id

    • Auth: Manager or Admin assignee
    • Body: { decision, comments }
    • Response: success message

Approval Rules

  • GET /api/approval-rules

    • Auth: Admin
    • Response: all approval rules for the company
  • POST /api/approval-rules

    • Auth: Admin
    • Body: { name, description, isManagerApprover, isSequential, minimumApprovalPercentage, approvers[] }
  • PATCH /api/approval-rules/:id

    • Auth: Admin
    • Body: same as create
  • DELETE /api/approval-rules/:id

    • Auth: Admin

Notifications

  • GET /api/notifications

    • Auth: authenticated
    • Response: latest notifications plus unread count
  • PATCH /api/notifications/:id

    • Auth: authenticated owner
    • Response: marks one notification as read
  • PATCH /api/notifications/read-all

    • Auth: authenticated
    • Response: marks all notifications as read

Admin Override

  • POST /api/admin/expenses/:id/override
    • Auth: Admin
    • Body: { decision, comments }
    • Response: success message

Dashboard Summary

  • GET /api/dashboard/summary
    • Auth: authenticated
    • Response: role-scoped totals and counts

Profile

  • PATCH /api/profile/password
    • Auth: authenticated
    • Body: { currentPassword, newPassword, confirmPassword }
    • Response: success message

Approval Workflow Diagram

Employee submits expense
        |
        v
Manager-first enabled?
   | yes                         | no
   v                             v
Direct manager request      Rule approvers start
created as sequence 0       immediately
        |
        v
Sequential rule? ------------------------------+
   | yes                                       | no
   v                                           v
Create next approver only                Create all approvers together
after previous action                    and evaluate after each action
        |
        v
Evaluate after every approval/rejection:

1. Required approver rejected
   => reject immediately

2. Required approver approved
   => approve immediately

3. Minimum approval percentage reached
   => approve immediately

4. No percentage rule and every approver approved
   => approve

5. Threshold can no longer be met
   => reject

6. Otherwise
   => continue workflow

Seed Data

The seed script creates:

  • Company: Acme Corp
  • Country: India
  • Currency: INR
  • 1 Admin user
  • 2 Managers
  • 3 Employees
  • 1 approval rule
  • 5 demo expenses across draft, submitted, approved, and rejected states
  • demo in-app notifications

Submission Notes

This repository is prepared as our hackathon submission codebase.

Recommended submission checklist:

  1. Push the repository to the team GitHub repo.
  2. Add the mentor as a collaborator on the repository.
  3. Confirm the repo is accessible.
  4. Provide the video demo link on the hackathon platform.
  5. Share the Docker Compose run command: docker compose up --build

Credits

Hackathon Platform

  • Odoo x VIT Pune Hackathon 26
  • Vishwakarma Institute of Technology (VIT), Pune

Team

  • Team Leader: Maitri
  • Team Member: Vyas Devgna

Mentor

  • Mentor: Jay Patel (jayp)
  • GitHub: jayp-odoo

Acknowledgments

  • We thank the Odoo x VIT Pune Hackathon 26 organizers for the platform and opportunity to build this solution.
  • We are grateful to our mentor Jay Patel for the guidance and technical direction throughout the challenge.
  • This submission was prepared by our team with Maitri as Team Leader and Vyas Devgna as Team Member.

Known Limitations and Future Work

  • OCR accuracy still depends on receipt quality, orientation, and lighting
  • The current rule selector uses the latest company rule; category- or amount-specific rule targeting would be a strong next step
  • SMTP is optional in the default local and Docker setup; production email delivery requires real SMTP credentials
  • The Docker setup is optimized for demo and submission convenience rather than horizontal production scaling

Verification Checklist

The project should be validated with:

npx tsc --noEmit
npm run lint
npm run build

For container verification:

docker compose up --build

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages