Vendiqo is a multi-tenant event and venue POS system. Verleiher (hire companies) rent POS hardware to event customers: the cloud stack configures organisations and events; Raspberry Pi edge servers run on-venue ordering, printing, and sync; the Android app wraps the Pi PWA for waiter devices with Bluetooth printing and Stripe Tap to Pay.
flowchart TB
subgraph cloud [Cloud]
AdminUI[Vue admin UI]
CloudAPI[FastAPI + PostgreSQL]
AdminUI --> CloudAPI
end
subgraph venue [Venue LAN - Raspberry Pi]
PiPWA[Vue PWA]
PiAPI[FastAPI + SQLite]
Printers[ESC/POS printers]
PiPWA --> PiAPI
PiAPI --> Printers
end
subgraph android [Android waiter phone]
WebView[WebView + Pi PWA]
BTPrinter[Bluetooth printer]
TapToPay[Stripe Tap to Pay]
WebView --> PiAPI
WebView --> BTPrinter
WebView --> TapToPay
end
PiAPI -->|bundle + sync| CloudAPI
TapToPay -->|via Pi proxy| CloudAPI
- Multi-tenant Verleiher model with role-based access (
platform_admin,tenant_admin,organisation_admin,member) - Organisations, events (config → test → prod → archive), catalog (articles, categories, ingredients), waiters
- Appliances (server, printer, mobile, tablet, router, ap), lendings, and Pi pairing codes
- User management, tax codes, countries, payment types
- Event configuration: stations, printers, layouts, vouchers, kitchen monitors, cash registers, receipt printing
- Sales reports, event stats, transactions, cash sessions, bookkeeping export, collective bill PDFs
- Stripe Connect onboarding and Stripe Terminal edge API (optional in local dev)
- Hosted Cloud-Pi browser sandboxes for events in config status
- Orderjutsu import wizard
- Help center and admin UI in German and English; locale-aware money and date formatting
- Offline-first ordering with SQLite and background cloud sync
- Waiter ordering, open tables, split-pay, collective bills (Sammelrechnung)
- Cash registers, customer display, shift sessions
- Kitchen monitor, pickup screen
- Payments: cash, TWINT, SumUp; card via Stripe Terminal on Android
- Vouchers, stock tracking, receipt history
- ESC/POS network printing (python-escpos)
- Native WebView wrapper for the Pi PWA
- Bluetooth ESC/POS receipt printing
- Stripe Tap to Pay via
window.AndroidTerminal
| Path | Purpose |
|---|---|
cloud/ |
Cloud backend (FastAPI + PostgreSQL) and admin frontend (Vue 3 / Vite / TypeScript) |
pi/ |
Pi edge backend (FastAPI + SQLite) and venue PWA (Vue 3 / Vite) |
android/ |
Vendiqo Waiter Android app |
packages/vendiqo_shared/ |
Shared Python helpers (VAT split, stock, bundle contract) |
packages/frontend-shared/ |
Shared frontend utilities |
website/ |
Static landing page and privacy policy (production via Caddy) |
sd-card-creator/ |
Raspberry Pi OS SD card image build tooling |
docs/ |
Integration guides (e.g. Stripe Connect / Terminal) |
Further documentation: cloud/README.md, pi/README.md, android/README.md, sd-card-creator/README.md, AGENTS.md.
Use two terminals (or run stacks sequentially):
Cloud:
cd cloud
cp .env.example .env
docker compose up --build- API:
http://localhost:8000(health:/health) - Admin UI:
http://localhost:5173
Pi edge (with cloud running):
cd pi
cp .env.example .env
docker compose up --build- API:
http://localhost:8001 - PWA:
http://localhost:5174
Set SYNC_ENABLED=0 in pi/.env to run the Pi without cloud pairing.
Android (debug/emulator): loads Pi frontend from http://localhost:5174 (adb reverse tcp:5174 tcp:5174); API http://localhost:8001. See android/README.md.
Default cloud admin login (from cloud/.env.example): admin@vendiqo.local / admin123.
Backend (pytest):
cd cloud/backend && pip install -r requirements.txt -r requirements-dev.txt && python3 -m pytest tests/ -v
cd pi/backend && pip install -r requirements.txt -r requirements-dev.txt && python3 -m pytest tests/ -vFrontend (Vitest):
cd cloud/frontend && ../../scripts/npm.sh ci && npm test
cd pi/frontend && ../../scripts/npm.sh ci && npm testSee AGENTS.md for coverage commands and CI details.
- Cloud backend uses PostgreSQL; Pi backend uses SQLite on the device.
- Router DB writes use
commit_or_raise()(seecloud/backend/app/db_errors.py). - FastAPI routes with synchronous SQLAlchemy session access are
def(notasync def) to avoid blocking the event loop. - Shared Python logic (e.g. VAT split) lives in
packages/vendiqo_sharedand is re-exported by cloud/pi. - Production startup requires successful Alembic migrations; there is no silent
create_allfallback. - Local dev frontends run as Vite dev servers inside Docker.
cloud/backend/requirements.lock and pi/backend/requirements.lock are generated with pip-compile --generate-hashes --allow-unsafe (see comments in the lockfiles).