No description
  • TypeScript 92.9%
  • Python 6%
  • CSS 0.6%
  • Dockerfile 0.3%
  • HTML 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-07-17 10:51:46 +07:00
apps feat: export report as HTML instead of PDF 2026-07-17 10:51:46 +07:00
.dockerignore Initial commit: POSv (Phê La) - kiosk ordering, multi-store, reports, mock data 2026-07-10 19:19:32 +07:00
.env.example feat: initial POS system with Docker & Synology support 2026-07-17 07:43:09 +07:00
.gitignore Initial commit: POSv (Phê La) - kiosk ordering, multi-store, reports, mock data 2026-07-10 19:19:32 +07:00
bun.lock Initial commit: POSv (Phê La) - kiosk ordering, multi-store, reports, mock data 2026-07-10 19:19:32 +07:00
docker-compose.dev.yml Initial commit: POSv (Phê La) - kiosk ordering, multi-store, reports, mock data 2026-07-10 19:19:32 +07:00
docker-compose.prod.yml Initial commit: POSv (Phê La) - kiosk ordering, multi-store, reports, mock data 2026-07-10 19:19:32 +07:00
docker-compose.synology.yml fix: install prisma CLI on-the-fly for migrate service, use db push instead of migrate deploy 2026-07-17 08:17:13 +07:00
docker-compose.yml docs: update README with docker-compose.yml configuration 2026-07-10 21:34:54 +07:00
Dockerfile fix: remove frozen-lockfile flag for Docker build compatibility 2026-07-17 07:44:50 +07:00
generate_pdf_report.py feat: add staff login with store selection, enhanced inventory with grouped view and per-store actions, enhanced products page with unified grid/table view, Excel import/export with template, professional PDF restaurant POS report, enhanced inventory page with grouped view and per-store actions, staff login with store selection for multi-store support 2026-07-10 21:09:44 +07:00
generate_pos_data.py feat: add staff login with store selection, enhanced inventory with grouped view and per-store actions, enhanced products page with unified grid/table view, Excel import/export with template, professional PDF restaurant POS report, enhanced inventory page with grouped view and per-store actions, staff login with store selection for multi-store support 2026-07-10 21:09:44 +07:00
generate_restaurant_data.py feat: add staff login with store selection, enhanced inventory with grouped view and per-store actions, enhanced products page with unified grid/table view, Excel import/export with template, professional PDF restaurant POS report, enhanced inventory page with grouped view and per-store actions, staff login with store selection for multi-store support 2026-07-10 21:09:44 +07:00
nginx.conf fix: fix docker build and nginx config for production deployment 2026-07-10 21:50:04 +07:00
package-lock.json Initial commit: POSv (Phê La) - kiosk ordering, multi-store, reports, mock data 2026-07-10 19:19:32 +07:00
package.json Initial commit: POSv (Phê La) - kiosk ordering, multi-store, reports, mock data 2026-07-10 19:19:32 +07:00
README.md docs: use bun instead of ts-node for running seed scripts 2026-07-17 08:21:36 +07:00
restaurant_performance_report.pdf feat: add staff login with store selection, enhanced inventory with grouped view and per-store actions, enhanced products page with unified grid/table view, Excel import/export with template, professional PDF restaurant POS report, enhanced inventory page with grouped view and per-store actions, staff login with store selection for multi-store support 2026-07-10 21:09:44 +07:00
restaurant_pos_data.csv feat: add staff login with store selection, enhanced inventory with grouped view and per-store actions, enhanced products page with unified grid/table view, Excel import/export with template, professional PDF restaurant POS report, enhanced inventory page with grouped view and per-store actions, staff login with store selection for multi-store support 2026-07-10 21:09:44 +07:00

Phê La POS System

React 19 NestJS 11 PostgreSQL 17 Redis 7 Docker Bun 1.3

🎯 Overview

A modern Point of Sale (POS) System built for the Phê La Vietnamese coffee & tea chain. Designed for multi-store operations with real-time inventory, sales analytics, and role-based access control.


🏗️ Architecture

graph TB
    A[🌐 React 19 + Vite 6] -->|REST API| B[🔧 NestJS 11 + Prisma]
    B --> C[(PostgreSQL 17)]
    B --> D[🔴 Redis 7]
    A -->|Static Assets| E[🌐 Nginx]
    style A fill:#61DAFB,color:#000
    style B fill:#E0234E,color:#fff
    style C fill:#4169E1,color:#fff
    style D fill:#DC382D,color:#fff
    style E fill:#009639,color:#fff

🛠️ Tech Stack

Layer Technology Version
Frontend React, Vite, TanStack Router/Query, Tailwind CSS v4, i18next 19 / 6
Backend NestJS, Prisma ORM, JWT, PDFKit, ExcelJS 11
Database PostgreSQL, Redis 17 / 7
Container Docker (multi-stage), Nginx Latest

🚀 Quick Start

Prerequisites

  • Docker & Docker Compose
  • Bun (optional, for local development)

🐳 Quick Start with Docker Compose

# Clone and start
git clone https://git.khoavo.myds.me/vndangkhoa/POSv.git
cd POSv
docker compose up --build -d

# Check status
docker compose ps

# View logs
docker compose logs -f api

# Stop services
docker compose down

# Full reset (removes data volumes)
docker compose down -v

🔧 Local Development

# Install dependencies
bun install

# Start development servers
bun run dev              # API at http://localhost:3000
cd apps/web && bun run dev  # Web at http://localhost:5173

# Database
bun run db:push     # Push schema changes
bun run db:studio   # Prisma Studio
bun run seed        # Seed demo data

# Testing
bun run test        # Unit tests
bun run test:e2e    # E2E tests

Synology NAS Deployment

Deploy the full stack on a Synology NAS using Container Manager (GUI).

Prerequisites

  • Synology NAS with Container Manager installed (Package Center)
  • SSH access (optional, for manual migration/seed)
  • Registry login: In Container Manager → RegistrySettings → add https://git.khoavo.myds.me with your Forgejo username & token

Setup Steps

1. Prepare the project folder

On your Synology, create a shared folder (e.g., posv) via File Station. Upload the entire project directory into it (or clone via Git if SSH is available).

2. Create .env file

In the project folder, create a .env file with your production settings:

DB_USER=pos
DB_PASSWORD=pos_secret
DB_NAME=pos_management
JWT_SECRET=your-strong-random-secret-here
JWT_EXPIRATION=7d
JWT_REFRESH_EXPIRATION=30d
CORS_ORIGIN=http://localhost:8080,http://192.168.1.100:8080

Replace 192.168.1.100 with your Synology NAS IP address.

3. Import the stack into Container Manager

  1. Open Container Manager on your Synology DSM
  2. Go to ProjectAdd
  3. Select the project folder (e.g., /volume1/posv)
  4. Set the file to docker-compose.synology.yml
  5. Click NextApply

Container Manager will pull the pre-built images from the registry and start all services.

4. Run database migration

After the stack is running, run the migration service:

# Via SSH into the Synology:
cd /volume1/posv
docker compose -f docker-compose.synology.yml --profile migrate run --rm migrate

Or from Container Manager: go to Project → select your project → YAML Settings → add --profile migrate to the run command, then start the migrate service manually.

5. (Optional) Seed demo data

# SSH into the Synology:
docker compose -f docker-compose.synology.yml exec api bun add prisma
docker compose -f docker-compose.synology.yml exec api bun prisma/seed-phela.ts

Access the System

Service URL
Web App http://<synology-ip>:8080
API http://<synology-ip>:3000/api
API Docs (Swagger) http://<synology-ip>:3000/api/docs

Login Credentials

Role Email / Code Password
Super Admin admin@phela.vn admin@123
Store Manager manager.hanoi@phela.vn manager@123
Staff (Kiosk) NV001 NV016 1234

Update & Restart

git pull
docker compose -f docker-compose.synology.yml pull
docker compose -f docker-compose.synology.yml up -d
# Re-run migration if schema changed
docker compose -f docker-compose.synology.yml --profile migrate run --rm migrate

🔐 Demo Accounts

Primary Seed (bun run seed:phela)

Role Email / Code Password Access
Super Admin admin@phela.vn admin@123 Full system access, all stores
Store Manager manager.hanoi@phela.vn manager@123 Phê La Phạm Ngọc Thạch (HN)
Store Manager manager.dalat@phela.vn manager@123 Phê La Nguyễn Chí Thanh (ĐL)
Store Manager manager.danang@phela.vn manager@123 Phê La Bạch Đằng (ĐN)
Store Manager manager.hcm@phela.vn manager@123 Phê La Hai Bà Trưng (HCM)
Store Manager manager.nhatrang@phela.vn manager@123 Phê La Trần Phú (NT)
Store Manager manager.haiphong@phela.vn manager@123 Phê La Bùi Thị Xuân (HP)

Mock Seed (bun run seed:mock — adds staff + 30-day orders)

Role Code PIN Access
Staff NV001 NV016 1234 POS/Kiosk mode only

Staff Login: Uses code + PIN at /kiosk route


🐳 Docker Compose Files

File Purpose
docker-compose.yml Default stack (postgres, redis, api, web on port 80)
docker-compose.dev.yml Dev services (postgres, redis only — run API/web locally)
docker-compose.prod.yml Production variant (web on port 8080)
docker-compose.synology.yml Synology NAS optimized (pre-built images, web on 8080, healthchecks, migrate profile)

Quick Reference (docker-compose.synology.yml)

services:
  postgres:
    image: postgres:17-alpine
    environment:
      POSTGRES_USER: pos
      POSTGRES_PASSWORD: pos_secret
      POSTGRES_DB: pos_management
    volumes: [postgres_data:/var/lib/postgresql/data]
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U pos -d pos_management"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    volumes: [redis_data:/data]
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  api:
    image: git.khoavo.myds.me/vndangkhoa/posv-api:latest
    environment:
      NODE_ENV: production
      PORT: 3000
      DATABASE_URL: postgresql://pos:pos_secret@postgres:5432/pos_management
      REDIS_URL: redis://redis:6379
      JWT_SECRET: ${JWT_SECRET}
      CORS_ORIGIN: http://localhost:8080,http://${HOST_IP:-localhost}:8080
    ports: ["3000:3000"]
    depends_on:
      postgres: { condition: service_healthy }
      redis: { condition: service_healthy }
    volumes: [uploads:/app/uploads]
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  web:
    image: git.khoavo.myds.me/vndangkhoa/posv-web:latest
    ports: ["8080:80"]
    depends_on:
      api: { condition: service_healthy }
    restart: unless-stopped

volumes:
  postgres_data:
  redis_data:
  uploads:

🔌 API Endpoints

Module Endpoints
Auth POST /api/auth/login, POST /api/auth/staff-login, GET /api/auth/me
Products GET /api/products, POST /api/products, POST /api/products/import
Sales GET /api/sales/orders, GET /api/sales/revenue
Inventory GET /api/inventory/stock, POST /api/inventory/adjustment
Reports GET /api/reports/summary, GET /api/reports/export
Users GET /api/users, POST /api/users
Dashboard GET /api/dashboard

📊 Reports

The system generates professional PDF reports:

Report Description
📈 Weekly Revenue By category, day, hour with charts
🏆 Top Products By quantity & revenue
💳 Payment Methods Breakdown by type
👥 Staff Performance Sales & ratings per staff
📄 Restaurant POS Report Professional PDF template with charts
# Download restaurant POS report (PDF)
curl -H "Authorization: Bearer <token>" \
  http://localhost:3000/api/reports/export/restaurant-pos \
  -o restaurant-report.pdf

📁 Project Structure

POSv/
├── apps/
│   ├── api/           # NestJS API
│   │   ├── src/
│   │   ├── prisma/    # Database schema
│   │   └── Dockerfile
│   └── web/           # React + Vite
│       ├── src/
│       └── Dockerfile
├── docker-compose.yml
├── docker-compose.dev.yml
├── docker-compose.prod.yml
<<<<<<< HEAD
=======
├── docker-compose.synology.yml   # Synology Container Manager
>>>>>>> 9d41116 (feat: initial POS system with Docker & Synology support)
├── nginx.conf
└── package.json

🧪 Development Commands

Command Description
bun run dev Start API in watch mode
cd apps/web && bun run dev Start web dev server
bun run db:push Push Prisma schema to DB
bun run db:studio Prisma Studio
bun run seed Seed demo data
bun run seed:mock Generate 30-day mock data
bun run raw:phela Generate 90-day Phê La raw data
bun run import:raw Import raw data into DB
bun run test Run unit tests
bun run test:e2e Run E2E tests

🌱 Seed Data

The system includes realistic Phê La mock data:

Entity Details
Stores 4 locations (Phê La Mới, Trung Tâm, Sài Gòn, Vườn Đào)
Products 26 items (Cà Phê, Moka Pot, French Press, Syphon, Cold Brew, Trà Ô Long, Ô Long Matcha, Toppings)
Staff 13 members with PIN login
Sales 30/90-day realistic patterns
Pricing Realistic VND pricing

📜 License

Proprietary - Phê La Restaurant Group

Built with ❤️ for Phê La Restaurant Group