Skip to content

About

Full-stack retail platform: POS/inventory admin dashboard + AI-powered customer storefront (React, Express, Prisma, PostgreSQL, OpenAI)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RetailFlow logo

RetailFlow

A POS and inventory admin dashboard paired with an AI-powered customer storefront.

Platform: web License: MIT Frontend: React 19 Language: TypeScript Styling: Tailwind CSS v4 Backend: Express 5 ORM: Prisma 7 Database: PostgreSQL AI: OpenAI API

At a Glance | AI Recommendations | Features | Tech Stack | Getting Started | Auth Model | Order Lifecycle | License

Table of Contents

RetailFlow is a full-stack retail platform combining a POS / inventory admin dashboard with an AI-powered customer storefront. A retailer manages products, stock, and both in-store and online orders from one dashboard; customers browse, create accounts, check out, and get OpenAI-powered product recommendations on a separate storefront app.

At a Glance

Area What it covers Full details
Apps Monorepo of three apps sharing one PostgreSQL database: API, Admin, and Store Apps
AI recommendations OpenAI-powered product picks on the homepage, product page, and cart, with a deterministic fallback so the storefront never breaks without an API key AI Recommendations
Customer storefront Amazon.in-style browsing, accounts, cart and checkout, order tracking, and AI-powered recommendations Customer Storefront
Retailer admin Staff login, product, category and inventory management, POS sales, Online Orders, customers, and reports Retailer Admin
Backend Modular Express API with two JWT auth realms, one Sale model for POS and online orders, and OpenAI recommendation endpoints Backend
Tech stack React 19, TypeScript, Vite, Tailwind CSS v4, Node.js, Express 5, Prisma 7, PostgreSQL, OpenAI API Tech Stack
Getting started Database, backend environment, install, migrate and seed, then run all three apps Getting Started
Auth model Separate staff and customer JWT realms, each with its own secret Auth Model
Order lifecycle POS sales are created as DELIVERED; online orders move from PENDING to DELIVERED, or CANCELLED Order Lifecycle
Scripts Dev server, build, migration, staff-user, and catalog-seed commands Scripts
Roadmap Redis, Docker, CI; returns, sales visits, offline-first PWA Roadmap
License MIT License

Back to top

Apps

This is a monorepo with three apps sharing one PostgreSQL database:

App Path Purpose
API backend/ Express + Prisma REST API
Admin frontend/ Retailer dashboard — POS, inventory, online order fulfillment, reports
Store shop/ Customer storefront — browsing, accounts, cart, checkout, AI recommendations

Back to top

AI Recommendations

RetailFlow uses the OpenAI API to suggest products to customers on the storefront, based on what they have viewed, bought, or put in their cart.

AI-powered recommendations in three places, each with a deterministic fallback so the storefront never breaks without an API key:

Placement Section title Behavior
Homepage "Recommended for You" Personalized from a signed-in customer's browsing/purchase history; falls back to best-sellers for guests or new accounts
Product page "You May Also Like" Related items from the same category re-ranked by the model
Cart "Frequently Bought Together" Complementary add-ons not already in the cart

How it works:

Step What happens
1. Shortlist The backend builds a capped list of active, in-stock candidate products, filtered by category: the categories a signed-in customer has viewed or purchased (homepage), the current product's category (product page), or the categories of the items in the cart (cart). The product being viewed and any items already in the cart are excluded.
2. Ask the model The shortlist and the shopper's context (recent views and purchases, the product being viewed, or the cart contents) are sent to the OpenAI Chat Completions API in JSON mode.
3. Validate Only product IDs from the shortlist are accepted. Anything else the model returns is dropped, so it can never invent a product.
4. Cache Results are held in an in-memory cache for 10 minutes to avoid redundant calls.
5. Fall back If no API key is set, the request fails or takes longer than 8 seconds, or the model returns nothing usable, the storefront shows deterministic results instead: best-sellers on the homepage, and products from the same category (or the cart's categories) on the product page and cart.

Endpoints:

Endpoint Auth Purpose
GET /api/recommendations/home Optional customer token; personalized when signed in Homepage picks
GET /api/recommendations/product/:id None Related products for a product page
POST /api/recommendations/cart None; body { "productIds": [1, 2] } Add-ons for a cart

Turn it on: set OPENAI_API_KEY in backend/.env (optionally OPENAI_MODEL, which defaults to gpt-4o-mini), as described in Getting Started. The client is created lazily, so the server starts normally without a key and simply uses the fallbacks.

Where the code lives: backend/src/modules/recommendations/ (routes, controller, service) and the RecommendedProducts component in shop/src/components/.

Back to top

Features

Customer Storefront (shop)

  • Amazon.in-style marketplace UI: two-tier navy header with a category strip, homepage category tiles and per-category product rows, a filterable/sortable listing page, and a buy-box style product page (star ratings, M.R.P. strike-through pricing, Add to Cart + Buy Now)
  • 32 seeded products across 9 categories (Electronics, Mobiles & Accessories, Fashion, Home & Kitchen, Beauty, Books, Sports & Fitness, Toys & Baby, Grocery) — see backend/scripts/seed-catalog.ts
  • Product browsing with search, category filters, and images
  • Customer accounts: signup/login (JWT), persistent order history
  • Cart and guest or logged-in checkout
  • Order tracking with a fulfillment status stepper (Pending → Confirmed → Packed → Shipped → Delivered)
  • AI-powered product recommendations on the homepage, product page, and cart — see AI Recommendations

Retailer Admin (frontend)

  • Staff login (JWT, role-based User model)
  • Product, category, and inventory management, including image uploads
  • Point-of-sale sales flow with a running cart, discounts, tax, and multiple payment methods
  • Online Orders: a dedicated view for orders placed through the storefront, separate from in-store POS sales, with guarded status transitions (e.g. an order can't jump from Pending straight to Shipped)
  • Customer management, sales history with printable invoices, and sales/profit/payment-method reports

Backend (backend)

  • Modular Express API (routes → controller → service per feature), Prisma ORM over PostgreSQL via the @prisma/adapter-pg driver adapter
  • Two independent JWT auth realms — staff and customer — with separate secrets, so a token minted for one can never be replayed against the other
  • A single Sale model backs both POS sales and online orders (source: POS | ONLINE), avoiding a duplicate Order model while keeping existing POS behavior untouched
  • AI recommendation endpoints use the official openai SDK with a lazily-constructed client (the server never crashes on startup if OPENAI_API_KEY is unset), a capped/category-filtered candidate list sent to the model, strict validation that the model only picks from real candidate IDs, and an in-memory TTL cache to avoid redundant calls

Back to top

Tech Stack

Layer Technologies
Frontend (both apps) React 19, TypeScript, Vite, Tailwind CSS v4, React Router
Backend Node.js, Express 5, TypeScript, Prisma 7, PostgreSQL
Auth JWT (jsonwebtoken), password hashing (bcryptjs)
AI OpenAI API (Chat Completions, JSON mode)
Uploads multer, served as static files

Back to top

Getting Started

Setup steps: database, environment, install and seed, run everything

1. Database

Create a PostgreSQL database and point DATABASE_URL at it in backend/.env (copy backend/.env.example as a starting point).

2. Backend environment

In backend/.env, set:

DATABASE_URL=postgresql://user:password@localhost:5432/retailflow
JWT_STAFF_SECRET=<random 32+ byte secret, e.g. `openssl rand -hex 32`>
JWT_CUSTOMER_SECRET=<a different random secret>
OPENAI_API_KEY=           # optional — recommendations fall back gracefully without it
OPENAI_MODEL=gpt-4o-mini  # optional override
PORT=4000

3. Install, migrate, seed

cd backend
npm install
npx prisma migrate deploy
npx prisma generate

# Create your first admin login
npx tsx scripts/create-staff-user.ts "Your Name" you@example.com yourpassword

# Populate a multi-category product catalog (idempotent — safe to re-run)
npx tsx scripts/seed-catalog.ts

4. Run everything

Command Starts
cd backend && npm run dev http://localhost:4000
cd frontend && npm run dev Admin dashboard, http://localhost:5173
cd shop && npm run dev Customer storefront, http://localhost:5174

Both frontends read their API base URL from VITE_API_BASE_URL in their own .env (defaults to http://localhost:4000).

Back to top

Auth Model

Two separate JWT realms, each with its own secret and localStorage token, so a leaked customer token can never authenticate as staff (or vice versa):

Realm Access Endpoints
Staff (User model, roles ADMIN/MANAGER/STAFF) Required on virtually every admin-only route: inventory, customers, reports, POS sales, and order-status updates. POST /api/auth/staff/login
Customer (Customer model) Optional on public storefront routes (so guest checkout still works) but required for order history/detail. Signing up with an email that already exists as a passwordless walk-in customer (created via an in-store POS sale) claims that existing record instead of creating a duplicate. POST /api/auth/customer/signup
POST /api/auth/customer/login

Product browsing (GET /api/products, GET /api/categories) stays fully public.

Back to top

Order Lifecycle

Every sale — in-store or online — is a Sale row distinguished by source:

Source Created Status handling
POS (source: POS) Created instantly by staff orderStatus is set straight to DELIVERED since there's no shipping step.
Online (source: ONLINE) Created via POST /api/orders from the storefront Starts at orderStatus: PENDING and is advanced by staff through the admin Online Orders page: PENDING → CONFIRMED → PACKED → SHIPPED → DELIVERED, or CANCELLED from any state before SHIPPED. Transitions are validated server-side against an explicit allowed-transitions map.

Back to top

Scripts

Available commands: dev server, build, migrations, seeding
Command Where What
npm run dev each app Start the dev server
npm run build frontend, shop Type-check + production build
npx prisma migrate deploy backend Apply pending migrations
npx tsx scripts/create-staff-user.ts <name> <email> <password> [role] backend Create or update an admin/staff login
npx tsx scripts/seed-catalog.ts backend Seed/update the 9-category, 32-product demo catalog

Back to top

Roadmap

  • Redis, Docker, CI
  • Returns, sales visits, offline-first PWA

Back to top

License

MIT © prasodium

Back to top

About

Full-stack retail platform: POS/inventory admin dashboard + AI-powered customer storefront (React, Express, Prisma, PostgreSQL, OpenAI)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages