Skip to content

mostafammagdy/FuelSystem

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Irving24 Fuel System

A full-stack Point-of-Sale system built for a real service station in Quebec, Canada.
Handles dual sales models — prepaid fuel dispensing (DIESEL/DEF) and in-store retail — with role-based access control, real-time analytics, inventory tracking, receipt generation, and Quebec tax compliance.

FeaturesTech StackArchitectureGetting StartedAPI ReferenceScreenshots


Why This Project

Most POS tutorials stop at a shopping cart. This system solves real operational problems at a gas station:

  • Prepaid fuel authorization — A customer authorizes $500, fuels $450 worth of diesel, and is only charged $450. The system tracks both the authorized ceiling and the actual charge, preventing overcharges while maintaining an audit trail.
  • Quebec tax compliance — Automatically applies 5% GST + 9.975% QST to every transaction with itemized breakdowns on receipts.
  • Dual sales model — A single cashier interface handles both fuel pump transactions and retail counter sales, with distinct workflows unified under one dashboard.
  • Shift accountability — Role-based access ensures cashiers can only operate the POS, while managers handle inventory and admins control user access.

Features

Point of Sale

  • Unified interface for fuel pump transactions and retail counter sales
  • Prepaid fuel workflow: authorize amount, dispense fuel, charge actual amount
  • Real-time cart with quantity adjustment, item removal, and live tax calculation
  • Payment method selection (Cash, Credit Card, Debit Card, Mobile Pay)
  • Pump status monitoring (IDLE / ACTIVE / ERROR)

Receipt Generation

  • Auto-generated receipt numbers (IRV24-YYYYMMDD-00001 daily sequence)
  • Professional receipt layout with business info and tax breakdown
  • QR code embedded per transaction for digital verification
  • Browser print integration via react-to-print

Analytics Dashboard

  • Daily stats — Revenue, transaction count, average transaction value
  • Fuel vs. Retail split — Separate revenue and volume metrics
  • Payment breakdown — Pie chart by payment method
  • Trend analysis — Area charts with 7/14/30-day and custom date ranges
  • Range reports — Daily revenue breakdown over any date period

Inventory Management

  • Real-time stock levels with search, category filter, and sorting
  • Low-stock alerts with configurable thresholds
  • Out-of-stock flagging with visual indicators
  • Restock and adjustment logging (damage, correction) with operator tracking
  • Complete audit trail per product via StockAdjustment model

Transaction History

  • Paginated transaction log with date range, payment method, and sale type filters
  • Click-to-expand transaction details with itemized breakdown
  • Reprint receipts from any past transaction

Access Control

Role POS Transactions Dashboard Inventory Admin
Admin Full Full Full Full (read/write) Full
Manager Full Full Full Full (read/write)
Cashier Full View own View View only

Security

  • JWT authentication with 30-day token expiry
  • Bcrypt password hashing (salt rounds: 10)
  • Helmet HTTP security headers
  • Rate limiting — 200 req/15min (API), 20 req/15min (auth)
  • Input validation and sanitization via express-validator
  • CORS restricted to frontend origin
  • Auto-logout on 401 responses

Observability

  • Winston structured JSON logging (file + console transports)
  • Morgan HTTP request logging piped to Winston
  • Rotating log files (5MB max, 5 file retention)
  • Separate error log and combined log

Tech Stack

Backend

Package Version Purpose
Express.js 5.1 REST API framework
MongoDB + Mongoose 8.17 Document database with schema validation
jsonwebtoken 9.0 JWT authentication
bcryptjs 3.0 Password hashing
express-validator 7.3 Request validation and sanitization
express-rate-limit 8.2 Brute-force protection
Helmet 8.1 Security headers
Winston 3.19 Application logging
Morgan 1.10 HTTP request logging
Jest + Supertest 30.2 / 7.2 Testing (in-memory MongoDB)

Frontend

Package Version Purpose
React 19.1 UI framework
Vite 7.0 Build tool with HMR
Tailwind CSS 4.1 Utility-first styling
React Router 7.13 Client-side routing
Axios 1.13 HTTP client with interceptors
Recharts 3.7 Analytics charts
react-to-print 3.2 Receipt printing
qrcode.react 4.2 QR code generation
react-datepicker 9.1 Date range selection
react-hot-toast 2.6 Toast notifications

Architecture

┌─────────────────────────────────────────────────────────┐
│                      FRONTEND                           │
│                                                         │
│  React 19 + Vite + Tailwind CSS                        │
│                                                         │
│  ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌──────────┐ │
│  │   POS    │ │Dashboard │ │ Inventory │ │  Admin   │ │
│  │  Page    │ │  Charts  │ │ Manager   │ │  Panel   │ │
│  └────┬─────┘ └────┬─────┘ └─────┬─────┘ └────┬─────┘ │
│       │             │             │             │       │
│  ┌────┴─────────────┴─────────────┴─────────────┴────┐ │
│  │              Service Layer (Axios)                 │ │
│  │  authService │ saleService │ productService │ ...  │ │
│  └──────────────────────┬────────────────────────────┘ │
│                         │ JWT Bearer Token              │
└─────────────────────────┼───────────────────────────────┘
                          │ HTTP / REST
┌─────────────────────────┼───────────────────────────────┐
│                      BACKEND                            │
│                         │                               │
│  ┌──────────────────────┴────────────────────────────┐ │
│  │           Express.js 5 + Middleware               │ │
│  │  Helmet │ CORS │ Rate Limit │ Morgan │ Validator  │ │
│  └──────────────────────┬────────────────────────────┘ │
│                         │                               │
│  ┌──────────────────────┴────────────────────────────┐ │
│  │              Route Handlers                        │ │
│  │  /auth │ /sales │ /products │ /pumps │ /inventory │ │
│  └──────────────────────┬────────────────────────────┘ │
│                         │                               │
│  ┌──────────────────────┴────────────────────────────┐ │
│  │        Middleware: protect + requireRole           │ │
│  └──────────────────────┬────────────────────────────┘ │
│                         │                               │
│  ┌──────────────────────┴────────────────────────────┐ │
│  │       Mongoose Models + Pre-save Hooks            │ │
│  │  User │ Product │ Pump │ Sale │ StockAdjustment   │ │
│  └──────────────────────┬────────────────────────────┘ │
│                         │                               │
│  ┌──────────────────────┴────────────────────────────┐ │
│  │                 Winston Logger                     │ │
│  │           error.log │ combined.log                 │ │
│  └───────────────────────────────────────────────────┘ │
└─────────────────────────┼───────────────────────────────┘
                          │
                 ┌────────┴────────┐
                 │    MongoDB      │
                 │   Irving24 DB   │
                 └─────────────────┘

Project Structure

FuelSystem/
├── backend/
│   ├── app.js                        # Express app (middleware, routes)
│   ├── server.js                     # Entry point (DB connect + listen)
│   ├── config/
│   │   ├── db.js                     # MongoDB connection
│   │   └── logger.js                 # Winston configuration
│   ├── middleware/
│   │   └── authMiddleware.js         # JWT verify + role guard
│   ├── models/
│   │   ├── User.js                   # Auth + roles
│   │   ├── Product.js                # Catalog (fuel + retail)
│   │   ├── Pump.js                   # Pump state machine
│   │   ├── Sale.js                   # Transactions + receipt gen
│   │   └── StockAdjustment.js        # Inventory audit trail
│   ├── routes/
│   │   ├── authRoutes.js             # Login / Register
│   │   ├── saleRoutes.js             # In-store + fuel sales, stats
│   │   ├── productRoutes.js          # CRUD products
│   │   ├── pumpRoutes.js             # Pump control
│   │   ├── userRoutes.js             # User management (admin)
│   │   └── inventoryRoutes.js        # Stock ops + history
│   └── tests/
│       ├── setup.js                  # MongoMemoryServer lifecycle
│       ├── auth.test.js              # 8 auth tests
│       └── sales.test.js             # 7 sales tests
│
├── frontend/my-fuel-system/
│   └── src/
│       ├── App.jsx                   # Router configuration
│       ├── main.jsx                  # Entry point + BrowserRouter
│       ├── context/
│       │   └── AuthContext.jsx        # Global auth state
│       ├── pages/
│       │   └── POS.jsx               # Main POS interface
│       ├── components/
│       │   ├── Layout.jsx            # Shared header + navigation
│       │   ├── ProtectedRoute.jsx    # Auth + role guard
│       │   ├── Login.jsx             # Authentication screen
│       │   ├── Receipt.jsx           # Printable receipt + QR
│       │   ├── Dashboard.jsx         # Analytics + charts
│       │   ├── TransactionHistory.jsx # Sale log + filters
│       │   ├── InventoryManagement.jsx# Stock management
│       │   ├── AdminPanel.jsx        # User CRUD
│       │   └── ErrorBoundary.jsx     # Error fallback
│       └── services/
│           ├── api.js                # Axios instance + interceptors
│           ├── authService.js
│           ├── saleService.js
│           ├── productService.js
│           ├── pumpService.js
│           ├── userService.js
│           └── inventoryService.js
│
└── README.md

Getting Started

Prerequisites

1. Clone the repository

git clone https://github.com/mostafammagdy/FuelSystem.git
cd FuelSystem

2. Backend setup

cd backend
npm install

Create a .env file in backend/:

MONGODB_URI=mongodb://localhost:27017/Irving24
JWT_SECRET=your_strong_secret_key_here
PORT=5000
CORS_ORIGIN=http://localhost:5173

Start the server:

npm start

3. Frontend setup

cd frontend/my-fuel-system
npm install
npm run dev

The app will be running at http://localhost:5173.

4. Seed initial data

Open MongoDB shell and run:

use Irving24

// Create admin (password: admin123)
db.users.insertOne({
  username: "admin",
  password: "$2a$10$XQJG5cQYEOmrsGQBEd/jnOZABDxGRm0rKp6S1x2L3yZPvAYjH0Km",
  role: "admin",
  createdAt: new Date()
})

// Add fuel products
db.products.insertMany([
  { name: "DIESEL", category: "Fuel", price: 1.65, stock: 10000, unit: "liter", isFuel: true, fuelPumpId: "PUMP-01", createdAt: new Date() },
  { name: "DEF", category: "Fuel", price: 1.25, stock: 5000, unit: "liter", isFuel: true, fuelPumpId: "PUMP-02", createdAt: new Date() }
])

// Add pumps
db.pumps.insertMany([
  { pumpId: "PUMP-01", fuelType: "DIESEL", status: "IDLE", createdAt: new Date() },
  { pumpId: "PUMP-02", fuelType: "DEF", status: "IDLE", createdAt: new Date() }
])

5. Run tests

cd backend
npm test

All 15 tests run against an in-memory MongoDB instance — no external database needed.


API Reference

Authentication

Method Endpoint Body Response
POST /api/auth/register { username, password } { _id, username, role, token }
POST /api/auth/login { username, password } { _id, username, role, token }

Sales

Method Endpoint Description
POST /api/sales/instore Record retail sale (auto-decrements stock)
POST /api/sales/fuel Record fuel sale with pump + liters
GET /api/sales List sales (paginated, filterable)
GET /api/sales/stats/daily?date=YYYY-MM-DD Revenue, counts, payment breakdown
GET /api/sales/stats/range?start=...&end=... Multi-day trend data
GET /api/sales/:id Single transaction details
In-store sale request body
{
  "items": [
    { "productId": "64f...", "quantity": 2 },
    { "productId": "64f...", "quantity": 1 }
  ],
  "totalAmount": 14.97,
  "paymentMethod": "Credit Card"
}
Fuel sale request body
{
  "pumpId": "PUMP-01",
  "fuelType": "DIESEL",
  "fuelProductId": "64f...",
  "quantity": 45.5,
  "totalAmount": 75.08,
  "authorizedAmount": 500.00,
  "paymentMethod": "Credit Card"
}

Products

Method Endpoint Auth Description
GET /api/products Public List all products
POST /api/products Admin/Manager Create product
PUT /api/products/:id Admin/Manager Update product
DELETE /api/products/:id Admin/Manager Delete product

Pumps

Method Endpoint Description
GET /api/pumps List all pumps with status
POST /api/pumps Register new pump
POST /api/pumps/:pumpId/unlock Set pump to ACTIVE
POST /api/pumps/:pumpId/lock Set pump to IDLE

Inventory

Method Endpoint Description
GET /api/inventory Products with stock (search, filter, sort)
GET /api/inventory/low-stock?threshold=10 Below-threshold items
GET /api/inventory/history/:productId Adjustment audit trail
PUT /api/inventory/:productId/restock Add stock (admin/manager)
PUT /api/inventory/:productId/adjust Log damage/correction

Users (Admin only)

Method Endpoint Description
GET /api/users List all users
POST /api/users Create user with role
PUT /api/users/:id Update user / change role
DELETE /api/users/:id Remove user

Screenshots

Add your screenshots here. Take screenshots of each screen and place them in a docs/screenshots/ folder, then uncomment the lines below.


Testing

The backend includes 15 integration tests running against an in-memory MongoDB instance via mongodb-memory-server:

 PASS  tests/auth.test.js
  Auth Endpoints
    POST /api/auth/register
      ✓ registers a new user and returns token
      ✓ rejects duplicate username
      ✓ rejects short username
      ✓ rejects short password
    POST /api/auth/login
      ✓ logs in with valid credentials
      ✓ rejects wrong password
      ✓ rejects non-existent user
      ✓ rejects empty fields

 PASS  tests/sales.test.js
  Sales Endpoints
    POST /api/sales/instore
      ✓ creates an in-store sale and decrements stock
      ✓ rejects unauthenticated requests
      ✓ rejects sale with insufficient stock
      ✓ rejects invalid payment method
    GET /api/sales
      ✓ returns paginated sales
    GET /api/sales/stats/daily
      ✓ returns daily statistics
    Health Check
      ✓ returns ok status

Test Suites: 2 passed, 2 total
Tests:       15 passed, 15 total

Environment Variables

Backend (.env)

Variable Required Default Description
MONGODB_URI Yes MongoDB connection string
JWT_SECRET Yes Secret key for JWT signing
PORT No 5000 Server port
CORS_ORIGIN No http://localhost:5173 Allowed frontend origin
NODE_ENV No development Environment mode
LOG_LEVEL No info Winston log level

Frontend (.env.local)

Variable Required Default Description
VITE_API_BASE_URL No http://localhost:5000 Backend API URL

License

This project is for educational and portfolio purposes.


Built with Express.js, MongoDB, React, and a lot of coffee.
Designed for Irving24 Service Station, Quebec, Canada

About

Revised and updated version of POS system for Irving24 Service Station (Fuel + Items)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages