A complete Point of Sale (POS) and restaurant operations platform
Streamline service, improve kitchen flow, and track performance in one system.
Built with the tools and technologies:
Naqdi is a restaurant management system focused on daily operations: order capture, table management, kitchen coordination, and management reporting. It is designed for cafes and full-service restaurants that need a fast POS workflow with a reliable back office.
- Order creation and status tracking across front-of-house and kitchen
- Table assignment and service status control
- Menu and item management
- Kitchen Display System (KDS) with preparation workflow
- Low-stock alerts and inventory visibility
- Role-based access for admins, managers, cashiers, and cooks
- Authentication and user roles
- Orders, tables, and menu management
- Kitchen operations and live queues
- Admin analytics and reporting endpoints
- Small cafes needing fast checkout and simple table flow
- Full-service restaurants coordinating FOH and BOH in real time
- Teams with multiple roles and shift changes
- Backend (server)
- Node.js + Express (REST API)
- PostgreSQL + Prisma
- JWT auth + bcryptjs
- dotenv, CORS, config
- ESC/POS printing via escpos + escpos-usb
- Frontend (client)
- Next.js + React
- TanStack React Query + Axios
- Tailwind CSS + Radix UI
- React Hook Form + Zod
- i18next + language detection
- Reduces service bottlenecks with live kitchen visibility
- Increases order accuracy with structured workflows
- Provides operational insight through reports and analytics
- Scales from single-location cafes to larger restaurants
Naqdi POS includes hardware-level terminal gating to authorize specific client devices and protect against unauthorized network access, along with a persistent internet bridge to connect mobile devices.
- Auto-Gating: When a new tablet or mobile client loads the POS, it is automatically locked with an Approval Required screen showing the terminal's unique Device UUID.
- Admin Approval: Administrators must navigate to the Settings -> Devices tab on their dashboard to view, name, and Approve or Deny connection requests.
- Auto-Healing: Loopback connections on the host machine (
localhostor127.0.0.1) are automatically auto-approved and self-healed in case of accidental blocks. - Self-Lockout Protection: The dashboard automatically disables action controls on the current active admin device to prevent accidental self-lockout.
To connect tablets or mobile phones over the internet (bypassing local network constraints and localtunnel's phishing reminder landing pages), use the built-in tunnel wrapper:
- Configure your persistent subdomains in
src/.env:TUNNEL_SUBDOMAIN_CLIENT=your-custom-client-subdomain TUNNEL_SUBDOMAIN_API=your-custom-api-subdomain
- Start the tunnel bridge in the root directory:
npm run tunnel
- Scan the generated QR code or open the permanent URL:
https://your-custom-client-subdomain.loca.lt?apiUrl=https://your-custom-api-subdomain.loca.ltThis URL remains the same across server restarts, server reboots, or power outages.
This application is designed to be deployed entirely on Netlify for free:
- Database: PostgreSQL (Supabase / Neon / Aiven)
- Backend (API): Netlify Functions
- Frontend (Client): Netlify
The backend has been configured with serverless-http to run natively as a Netlify Serverless Function.
- Go to Netlify and add a new site by importing an existing project from GitHub.
- Select this repository.
- Change the Base directory to
server. - The Build command (
npm install) should automatically populate. - Go to Environment variables and add:
DATABASE_URL(Prisma Connection String)JWT_SECRETJWT_EXPIRE(e.g.,7d)NODE_ENV(Set toproduction)
- Click Deploy Site.
- Once deployed, copy the new URL for your backend (e.g.,
https://naqdi-api.netlify.app).
- Go to Netlify and add a new site by importing an existing project from GitHub.
- Select this repository.
- Change the Base directory to
client. - The Build command (
npm run build) and Publish directory (.next) should automatically populate. - Go to Advanced build settings and add a new environment variable:
- Key:
NEXT_PUBLIC_API_URL - Value: Your Vercel backend URL (e.g.,
https://naqdi-backend.vercel.app).
- Key:
- Click Deploy Site.
Because cloud servers cannot connect to your cafe's local USB receipt printer, this project includes a standalone Local Print Agent.
This lightweight Node.js script runs on your store's computer. It connects to your cloud backend, fetches pending print jobs, and prints them to your USB printer.
- Open a terminal on your cafe's local computer.
- Navigate to the
local-print-agentdirectory:cd local-print-agent npm install - Copy
.env.exampleto.envand set your cloud backend URL:API_URL=https://cafe-pos-backend.onrender.com POLL_INTERVAL=5000
- Start the print agent:
Keep this terminal open, and it will automatically catch and print receipts as orders come in from the cloud.
npm start