Repository files navigation # openPOS — Restaurant Management System
Full-featured, **offline-first** restaurant POS and management platform built with Flutter + FastAPI + PostgreSQL.
```
┌─────────────────────────────────────────────────────┐
│ Flutter App (Android / iOS / Web) │
│ Riverpod · GoRouter · Hive offline cache │
└────────────────────┬────────────────────────────────┘
│ HTTP / WebSocket (LAN)
┌────────────────────▼────────────────────────────────┐
│ FastAPI Backend (Python 3.11) │
│ SQLAlchemy async · JWT + PIN auth · APScheduler │
└────────────────────┬────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────┐
│ PostgreSQL 15 │
└─────────────────────────────────────────────────────┘
```
---
## 🚀 Quick Start — Docker (recommended)
**One-time setup:**
```bash
# 1. Copy and configure environment
cp backend/.env.example backend/.env
# → Open backend/.env and set SECRET_KEY to a random 64-char string:
# python -c "import secrets; print(secrets.token_hex(32))"
# 2. Start everything (database + backend)
docker-compose up -d
```
That's it. On first boot the container automatically:
- Waits for PostgreSQL to be ready
- Runs all database migrations (`alembic upgrade head`)
- Seeds default admin user and branding settings (`seed.py`)
**Default login credentials** (change immediately after first login):
| Field | Value |
|----------|--------------|
| Username | `admin` |
| Password | `Admin@1234` |
| PIN | `0000` |
**API explorer:** http://localhost:8000/api/docs
---
## 🔧 Manual Setup (no Docker)
### Prerequisites
- Python 3.11+
- PostgreSQL 15+ running locally
### Steps
```bash
# 1. Create and activate virtual environment
cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# 2. Install dependencies
pip install -r requirements.txt
# 3. Configure environment
cp .env.example .env
# Edit .env — set DATABASE_URL to your local PostgreSQL and set SECRET_KEY
# 4. Create database (run once)
# Follow db_setup.txt
# 5. Run migrations
alembic upgrade head
# 6. Seed default data
python seed.py
# 7. Start the server
python start_server.py
# or for development with auto-reload:
python start_server.py --reload
```
Server is available at:
- Local: http://localhost:8000
- Network: http://:8000 (shown on startup)
---
## 📱 Flutter App
```bash
cd frontend/wood_bar_app
flutter pub get
# Android APK (arm64 — most tablets)
flutter build apk --release --target-platform android-arm64
# Install on connected device
adb install build/app/outputs/flutter-apk/app-arm64-v8a-release.apk
```
On first launch the app shows a **server setup screen** — enter your server IP (e.g. `http://192.168.1.100:8000` ). The app will also auto-discover the server via mDNS on the same LAN.
---
## ⚙️ Branding & Customisation
All business identity settings live in **Admin → Branding Settings**:
| Setting | Description |
|---------|-------------|
| Restaurant name | Shown on receipts and app header |
| Currency symbol | Used app-wide on every price display |
| Currency code | ISO code (USD, GBP, EUR, …) |
| Tax rate | Applied to all orders |
| Service charge | Optional flat % added to orders |
| Primary / accent colours | App theme (restart app to apply) |
| Logo | Shown on digital receipts |
| Receipt footer | Custom closing message |
Currency symbol changes take effect immediately on the next screen load — no rebuild required.
---
## 🏗 Architecture & Features
| Feature | Description |
|---------|-------------|
| **Core POS** | Visual floor plan, table management, seat/course ordering |
| **KDS** | Real-time kitchen display, bump system, sold-out toggle |
| **Cashier** | Counter service, takeaway/delivery, cash drawer |
| **Admin Panel** | Users, menu builder, floor editor, reports, branding |
| **AYCE** | Session timers, premium limits, overtime surcharge |
| **Multi-Channel** | DoorDash/Uber/Grubhub webhooks, QR self-order, kiosk |
| **Labor** | Clock-in/out, void pattern detection, labor % alerts |
| **Inventory** | Recipe costing, variance detection, auto-PO generation |
| **CRM/Loyalty** | Tier system, points earn/redeem, birthday rewards |
| **Payments** | Cash/card/mobile/split, offline queue, void workflow |
| **Tip Pool** | Points-weighted or FOH/BOH percentage split, payroll export |
| **Catering** | Event quotes, invoices, calendar, 72 hr reminders |
| **Multi-Unit** | Cross-location dashboard, inventory transfer, menu sync |
| **Security** | JWT rotation, PIN lockout, audit log, PCI DSS flow |
| **Daypart** | Time-based menu switching, price modifiers, WS alerts |
---
## 📅 Background Jobs
| Job | Schedule | Purpose |
|-----|----------|---------|
| AYCE monitor | Every 60 s | Expire/warn sessions |
| Labor alerts | Every 5 min | Early clock-in, high labour % |
| Birthday rewards | Daily 00:00 | Grant 300 pts for upcoming birthdays |
| Auto-PO | Daily 01:00 | Draft POs for low-stock ingredients |
| Event reminders | Daily 08:00 | 72 hr catering reminders |
| Loyalty expiry | Weekly | Expire old points |
| Daily reports | Daily 23:00 | Email daily summary |
---
## 👤 User Roles
```
admin → manager → cashier / waiter → kitchen / bar / catering
```
Role access is enforced both server-side (FastAPI dependencies) and client-side (GoRouter guards).
---
## 📶 Offline Mode
When the server is unreachable:
- Menu and tables served from Hive cache
- Orders queued in `pending_orders` box
- Cash payments stored AES-256 encrypted in `pending_payments`
- Loyalty transactions queued in `pending_loyalty`
- Sync runs automatically on reconnect with exponential backoff
---
## 🖥 Recommended Hardware
| Device | Recommendation |
|--------|---------------|
| Server | Raspberry Pi 5 (8 GB) or any Linux PC |
| Tablets | 10″ Android, 1920×1200, Android 10+ |
| KDS | 24″+ monitor with Android TV box |
| Receipt printer | Epson TM-T88VI (ESC/POS, TCP port 9100) |
| Cash drawer | Via receipt printer RJ11 |
---
## 🔌 API Reference
| URL | Description |
|-----|-------------|
| `/api/docs` | Swagger UI |
| `/api/redoc` | ReDoc |
| `/health` | Health check |
---
## 🛠 Development
```bash
# Add a new feature module:
# 1. backend/app/api/v1/endpoints/new_feature.py — router
# 2. backend/app/schemas/schemas.py — Pydantic schemas
# 3. backend/app/models/models.py — SQLAlchemy model
# 4. backend/alembic/versions/XXXX_new_feature.py — migration
# 5. backend/app/services/new_service.py — business logic
# 6. backend/main.py — register router
# Generate a new Alembic migration:
cd backend
alembic revision --autogenerate -m "add new_feature table"
alembic upgrade head
# Backend tests
cd backend && pytest tests/ -v
```
---
*openPOS v1.0 — 2026*
# OpenPOS
You can’t perform that action at this time.