MezbanPOS — Software Documentation
Product overview, features, and what’s built on mezbanpos.com (website and API).
MezbanPOS — Detailed Software Documentation
A local-network Point of Sale system built for small fast food and pizza shops.
About This Document
- Sections 1–21 describe the MezbanPOS desktop application (Electron + React + SQLite): product overview, features, and behavior. The desktop app is a separate codebase; it runs on Windows, macOS, and Linux and connects to the cloud only for registration, heartbeat, notifications, and license validation.
- Section 22 documents what is built in this repository: the mezbanpos.com website (PHP marketing site) and the backend API (FastAPI) that power the site and serve the desktop app (downloads, leads, install tracking, notifications, license checks).
Table of Contents
- What Is MezbanPOS?
- How It Works
- User Roles & Access
- Authentication
- Point of Sale (POS)
- Payment & Checkout
- Kitchen Display System (KDS)
- Menu Management
- Floor Plan & Tables
- Order History & Management
- Customer Database
- Shift Management
- Reporting & Analytics
- Settings & Configuration
- Printing
- Backup & Recovery
- Multi-Device / Local Network
- Audit Logging
- License Management
- Database Schema
- What Is Not Yet Implemented
- What Is Built in This Repository (mezbanpos.com)
1. What Is MezbanPOS?
MezbanPOS is a desktop Point of Sale application designed to run on a local network inside a restaurant or fast food shop. It is built with Electron, which means it runs as a native application on Windows, macOS, and Linux — no browser, no internet, no cloud subscription required.
The software covers the full order lifecycle:
- A cashier takes an order at the counter or for a table
- The order appears instantly on the kitchen screen
- Kitchen staff mark items as in-progress and ready
- The cashier collects payment and prints a receipt
- Managers review sales reports and shift summaries
- All data lives on a single machine (or shared via LAN)
2. How It Works
MezbanPOS runs in one of three modes:
| Mode | Description |
|---|---|
| Standalone | Single terminal. Everything runs locally — no network setup needed. |
| Server Mode | This terminal hosts the database, REST API, and WebSocket server on port 3737. All other devices connect to it. |
| Client Mode | This terminal connects to a Server terminal over LAN/WiFi by entering the server's IP address. |
In a multi-terminal setup, one machine acts as the hub. All order data, the menu, and settings live on that machine. Secondary terminals (POS counters, kitchen screens) connect to it and receive real-time updates over WebSocket.
Technology used under the hood:
- SQLite database (via Drizzle ORM)
- Express HTTP server for REST API
- WebSocket server for real-time events
- Electron for the desktop shell
- React for the UI
- Zustand for local state management
3. User Roles & Access
Every staff member has a PIN-protected account assigned one of four roles.
| Role | What They Can Do |
|---|---|
| Admin / Owner | Everything: settings, user management, reports, menu, POS, KDS, shifts, floor plan |
| Manager | POS, KDS, Menu, Floor Plan, Reports, Shifts — but not user management or system settings |
| Cashier / Staff | POS order taking and payment only |
| Kitchen Staff | Kitchen Display System (KDS) view only — can update order status |
Role enforcement happens on every page/route. A cashier who navigates directly to the reports URL is redirected back to the POS.
4. Authentication
How login works:
- The login screen shows all active staff as tiles
- Staff tap their name, then enter a 4–6 digit PIN
- The PIN is hashed with SHA-256 and compared against the stored hash
- After 5 consecutive wrong PINs, the account is locked for 5 minutes
- No internet connection is ever required
User management (Admin/Manager only):
- Create users with a name, role, and PIN
- Change a user's PIN at any time
- Deactivate users (soft delete — records are preserved)
Manager Override:
- Certain actions (void, refund) performed by a cashier require a manager or admin to enter their own PIN in a modal to authorize the action
- This is logged in the audit trail
5. Point of Sale (POS)
The POS is the primary daily-use screen. It is divided into a left panel (menu/cart) and a right panel (order summary/payment).
5.1 Taking an Order
Order Types:
- Dine-In — Requires table selection and optionally server assignment
- Takeout — No table needed; fast counter orders
- Delivery — Requires customer phone number; address is auto-filled from the customer database
Browsing the Menu:
- Categories are displayed as tabs at the top
- Items display with name and price
- Unavailable (86'd) items are hidden; a toggle reveals them
Customizing an Item: When an item is tapped, a customization modal opens:
- Choose a variant (e.g., Small, Medium, Large — each with a price modifier)
- Select modifiers/toppings (e.g., extra cheese, no onions — each with an optional extra charge)
- Add per-item notes
5.2 The Cart
The cart shows all items added to the current order:
- Adjust quantity with + / – buttons
- Remove individual items
- Add item-level notes inline
- Apply a flat discount amount
- Look up a customer by phone number (for delivery orders)
5.3 Hold & Recall Orders
- Any in-progress order can be put on hold and saved
- A cashier can recall any held order from the "Open Orders" modal
- This allows managing multiple tables or customers simultaneously
5.4 86'd Items (Availability Toggle)
- Any menu item can be quickly marked as unavailable ("86'd")
- 86'd items are hidden from the ordering screen
- Kitchen or managers can toggle availability in real time
6. Payment & Checkout
Tapping "Charge" on the cart opens the payment modal.
6.1 Payment Methods
Cash:
- Enter the amount tendered
- Change is calculated and displayed automatically
- Quick-amount buttons round up to the nearest $5, $10, $20, or $50
Card:
- Record a card payment manually (no terminal integration)
- Optional tip entry (preset percentages: 10%, 15%, 20%, or custom amount)
Split Payment:
- Pay part by card, part by cash
- Card portion handles tip; cash portion calculates change
- Each portion can have its own tax rate applied (configurable in settings)
6.2 Tax Calculation
Tax is calculated with support for overrides at multiple levels:
| Level | Description |
|---|---|
| Global Default | Applied to all items by default |
| Payment Method | Different rates for cash vs card (e.g., pass card fee to customer) |
| Per Category | Override rate for an entire category (e.g., beverages) |
| Per Item | Override rate for a specific menu item |
When a split payment is made, the weighted average tax rate is applied proportionally.
6.3 Tips
- Tips are recorded per order
- Only available on card payments
- Totals appear in shift reports and analytics
6.4 Shift Requirement
- A shift must be open before any payment can be processed
- If no shift is open, a warning banner appears on the POS with an "Open Shift" button
- This prevents untracked sales
7. Kitchen Display System (KDS)
The KDS is designed to run on a dedicated screen in the kitchen, preferably a large touchscreen.
How It Works
- Orders appear the moment they are placed at the POS
- The screen is divided into three columns: Pending, In Progress, Ready
- Kitchen staff tap an order card to advance its status
- When an order is Ready, the cashier is notified and can begin the handoff
Order Cards Show:
- Order number and type (Dine-In / Takeout / Delivery)
- Table number (for dine-in)
- List of items with quantities, variants, modifiers, and notes
- Elapsed time since the order was placed
Real-Time Updates:
- Powered by WebSocket — new orders appear instantly without refreshing
- An audio alert (beep) plays when a new order arrives
- If the WebSocket disconnects, the screen falls back to polling every 30 seconds
- A live/offline connection indicator is always visible
8. Menu Management
Accessible to Admin and Manager roles.
Categories
- Create, edit, and delete categories
- Assign a display color for visual organization
- Set sort order to control how they appear on the POS
- Set a per-category tax rate override
- Toggle active/inactive
Menu Items
- Create items with name, description, and base price
- Upload an item image (stored locally on the server machine)
- Assign to a category
- Set a per-item tax rate override
- Toggle active/inactive (inactive items are hidden on POS)
Variants
Each item can have multiple variants with price modifiers:
- Example: "Medium" (+$0), "Large" (+$2.50), "Family" (+$5.00)
- The cashier selects a variant when adding an item to the cart
Modifiers / Toppings
Each item can have modifiers:
- Example: "Extra Cheese" (+$1.00), "No Onions" (+$0.00)
- Can be marked required (must select) or optional
- Supports multiple selections
9. Floor Plan & Tables
Floor Plan Editor (Admin/Manager)
A visual drag-and-drop editor lets you lay out your dining room:
- Add tables in three shapes: round, square, rectangle
- Set table number, label, and seat count
- Position and resize tables on the canvas
- Assign a rotation angle
- Assign a server to each table
Live Table View
When not in edit mode, the floor plan shows real-time table status:
- Available — green, ready for seating
- Occupied — red, has an open order
- Reserved — yellow
Tapping an occupied table from the POS opens that table's order directly.
10. Order History & Management
A full searchable log of every order. Accessible to Admin and Manager.
Browsing Orders
- Quick filter: Today, Yesterday, Last 7 Days, Last 30 Days
- Full-text search across order number, customer name, etc.
Per-Order Detail View
- All items, quantities, variants, modifiers
- Subtotal, discount, tax, total
- Payment method, amount paid, change given
- Who created the order and when
Actions
Void Order:
- Cancels the entire order
- Requires a reason to be entered
- If done by a cashier, requires a manager PIN override
- Logged in the audit trail
Refund Item:
- Refund one or more items from an order
- Specify quantity and reason
- Requires manager authorization if performed by cashier
- Logged in audit trail
Reprint Receipt:
- Print a receipt for any historical order
11. Customer Database
A simple customer address book used primarily for delivery orders.
Features
- Search customers by name or phone number
- View full customer record: name, phone, address, notes
- View all past orders for a customer
- Create, edit, or delete customer records
Auto-Creation at Checkout
When a delivery order is placed and the customer's phone number is not found:
- The system creates a new customer record automatically during checkout
- Subsequent deliveries to the same number auto-fill their address
12. Shift Management
Shifts track a working period — typically one staff member's time at the register.
Opening a Shift
- Enter the opening float (cash already in the drawer)
- System records who opened it and when
Closing a Shift
- Count the actual cash in the drawer
- System calculates: expected cash = opening float + cash sales
- Displays whether the drawer is balanced, over, or short
- Add optional notes
- Option to trigger an automatic database backup on close
Shift Report
- Total orders taken
- Cash sales vs card sales breakdown
- Total discounts applied
- Total tips collected
- Who opened and closed the shift
- Printable
13. Reporting & Analytics
Accessible to Admin and Manager. Covers sales data from any time window.
Summary Cards
| Metric | Description |
|---|---|
| Total Revenue | Sum of all paid orders in the period |
| Order Count | Number of completed orders |
| Average Order Value | Revenue ÷ orders |
| Voids | Number and total value of voided orders |
| Refunds | Number and total value of refunded items |
| Tips | Total tips collected |
Charts
- Daily Revenue Bar Chart — bar per day showing revenue
- Daily Order Count — alongside the revenue chart
- Time periods: Last 7 days, Last 14 days, Last 30 days
Top Items
- The 8 best-selling items ranked by quantity sold and revenue generated
Export
- CSV Export — raw sales data saved to a file on disk
- PDF Export — formatted report saved to a file on disk
14. Settings & Configuration
Accessible to Admin only.
Shop Settings
| Setting | Description |
|---|---|
| Shop Name | Displayed on receipts |
| Currency Symbol | e.g., $, €, £, ₹ |
| Default Tax Rate | Applied to all items unless overridden |
| Cash Tax Rate | Tax rate when paying by cash |
| Card Tax Rate | Tax rate when paying by card |
| Receipt Footer Text | Custom message at bottom of receipts |
| Starting Order Number | Set where order numbering begins |
Terminal Mode
- Set this terminal to Standalone, Server, or Client mode
- In Client mode: enter the Server terminal's IP address
- Port: default
3737(configurable)
Printer
- Select from detected system printers
- Choose paper width: 80mm or 58mm
- Auto-print receipts: Ask / Always / Never
- Send a test print to verify setup
Floor Plan
- Enable or disable the table floor plan feature
Backup
- Choose a backup directory (USB drive, cloud-synced folder, etc.)
- Set number of backups to keep (default: 10)
- Toggle auto-backup when a shift is closed
- Trigger a manual backup immediately
- View when the last backup was taken
User Management
- Create staff accounts (name, role, PIN)
- Change any user's PIN
- View all users with their roles
15. Printing
MezbanPOS prints to any system printer that supports standard thermal receipt formatting.
What Can Be Printed
- Customer Receipt — after payment (auto-print or prompted)
- Bill / Pre-payment Receipt — print before collecting payment
- Shift Report — end-of-shift summary
- Historical Receipt — reprint any past order
Receipt Contents
- Shop name and header
- Order number, date/time, order type
- Cashier name
- Itemized list with variants, modifiers, and notes
- Subtotal, discount, tax, tip, and total
- Payment method and change given
- Custom footer text
Printer Setup
- Select any installed system printer from settings
- Paper widths supported: 80mm and 58mm
- Test print available from settings
16. Backup & Recovery
How Backups Work
- MezbanPOS creates a copy of the SQLite database file
- Backups are saved to a user-chosen directory
- File name includes a timestamp for easy identification
- Old backups are automatically deleted when the count exceeds the configured limit
Backup Triggers
| Trigger | Description |
|---|---|
| Manual | Press "Backup Now" in Settings |
| Shift Close | Automatic if enabled in Settings |
| Startup Check | If last backup is more than 24 hours old, prompts a reminder |
Recovery
To restore from a backup, replace the current database file with a backup copy. The backup files are plain SQLite files — no proprietary format.
17. Multi-Device / Local Network
MezbanPOS is designed to work across multiple devices over a shared WiFi or wired LAN — no internet required.
Typical Setup
┌──────────────────────────────────────────────────┐
│ LOCAL NETWORK │
│ │
│ ┌─────────────────┐ ┌──────────────────────┐ │
│ │ MAIN REGISTER │ │ KITCHEN SCREEN │ │
│ │ (Server Mode) │◄──►│ (Client Mode) │ │
│ │ │ │ │ │
│ │ • Database │ │ • KDS view only │ │
│ │ • Express API │ │ • Connects by IP │ │
│ │ • WebSocket hub │ │ • Real-time updates │ │
│ └─────────────────┘ └──────────────────────┘ │
│ │
│ Optional: additional POS terminals │
└──────────────────────────────────────────────────┘
WebSocket Real-Time Events
| Event | Triggered When |
|---|---|
order:new |
An order is placed at any terminal |
order:status_changed |
Kitchen staff advances order status |
order:settled |
Payment is collected |
menu:updated |
Menu item or category is changed |
All connected clients receive these events instantly.
Standalone Web KDS
The server also hosts a lightweight browser-based KDS page at http://<server-ip>:3737/kds that any device on the network can open — including tablets not running the full Electron app.
18. Audit Logging
Every destructive action is recorded in a tamper-evident audit log.
What Is Logged
- Order voids — who requested, who authorized, reason, timestamp, amounts
- Item refunds — same fields plus which items and quantities were refunded
Who Can Review Logs
- Admin and Manager can view the audit trail per order in the Order History page
Manager Authorization
- If a Cashier initiates a void or refund, a modal appears requiring a Manager or Admin to enter their PIN
- Both the requesting user and the authorizing user are recorded in the log
19. License Management
MezbanPOS includes a built-in licensing system.
| State | Meaning |
|---|---|
| Trial | Running within the trial period; all features available |
| Active | Valid license key applied; full access |
| Grace | License expired but within a short grace window |
| Expired | Trial or license has ended; limited functionality |
| Tampered | License data has been modified; invalid |
- A license banner appears in the UI when the trial is active or expiring
- Activation is done by entering a license key in Settings
- License is bound to the machine's hardware fingerprint
20. Database Schema
All data is stored in a SQLite database managed by Drizzle ORM.
| Table | Purpose |
|---|---|
users |
Staff accounts, roles, hashed PINs |
categories |
Menu categories with tax overrides |
menu_items |
Menu items with prices and tax overrides |
item_variants |
Size/type variants per item with price modifiers |
item_modifiers |
Toppings and add-ons per item |
orders |
All orders with payment details, tax, tips |
order_items |
Line items within each order (name snapshot) |
order_item_modifiers |
Modifiers selected per order line item |
tables |
Dining room table definitions and positions |
table_assignments |
Which server is assigned to which table |
customers |
Customer phone, name, address for delivery |
settings |
Key-value store for all configuration |
audit_log |
Void and refund action history |
shifts |
Shift records with cash reconciliation data |
Snapshots of item names and prices are stored in order_items so historical orders remain accurate even if the menu changes later.
21. What Is Not Yet Implemented
The following features are planned or partially scaffolded but not fully functional:
| Feature | Status |
|---|---|
| mDNS / Bonjour auto-discovery | Manual IP entry only; no auto-discovery |
| Inventory / stock tracking | No stock levels or depletion tracking |
| Percentage-based discounts | Only flat-amount discounts |
| Combo deals / promotions | Not implemented |
| Loyalty points | Not implemented |
| Email or SMS receipts | Not implemented |
| Online ordering integration | Not implemented |
| Multi-currency / conversion | Display symbol only; no conversion |
| Scheduled automatic backups | Shift-close or manual only |
| Staff performance reports | Shift summary only; no per-staff detail |
22. What Is Built in This Repository (mezbanpos.com)
This section documents the website and backend that live in this repository. They support the MezbanPOS desktop app (downloads, lead capture, install registration, notifications, license validation) and run at mezbanpos.com.
22.1 Repository Layout
| Path | Description |
|---|---|
html/ |
Public website: PHP pages, CSS, JS, images. Served as document root. |
app/ |
FastAPI backend: main.py and requirements.txt. Runs on port 8001; Nginx proxies /api/ and /healthz to it. |
nginx-mezbanpos.conf |
Nginx server block (PHP-FPM, proxy to FastAPI, SSL). |
data/ |
SQLite database file for the backend (leads.sqlite); created at runtime if missing. |
logs/ |
Application logs (e.g. app.out.log, app.err.log). |
22.2 Website (html/)
Technology: PHP 8.x, plain HTML/CSS/JS. No front-end framework. Shared header/footer via inc/nav.php and inc/footer.php.
Pages
| Page | Purpose |
|---|---|
index.php |
Homepage: hero, features, how it works, pricing, testimonials, FAQ, CTA. Download buttons open lead modal then trigger file download. |
suggestions.php |
Suggestion form: name, email (optional), suggestion text; protected by math captcha; submits to POST /api/suggestions. |
privacy.php |
Privacy policy. |
terms.php |
Terms of service and refund policy. |
blog/index.php |
Blog listing. |
blog/how-to-open-a-restaurant-in-pakistan/index.php |
Blog post. |
blog/mezbanpos-vs-hulm-vs-moneypex/index.php |
Blog post. |
lahore/index.php |
Location-specific landing (e.g. Lahore). |
admin/index.php |
Admin dashboard: login with shared secret token; installs, downloads, notifications, analytics. Calls backend /api/v1/admin/* with Bearer token. |
Download Flow (Homepage)
- User clicks "Download for Windows" or "Download for macOS".
- Windows: Download lead modal opens (name + email). On submit,
POST /api/downloadswith{ name, email, platform: "windows" }, then browser downloads/downloads/MezbanPOS%20Setup%200.1.0.exe. - macOS: Architecture picker modal (Apple Silicon vs Intel). User picks; then same lead modal; on submit,
POST /api/downloadswithplatform: "mac-silicon"or"mac-intel", then download of corresponding DMG. After download, optional "Opening MezbanPOS on macOS" instructions modal (xattr fix, Open Anyway). - Download count is fetched from
GET /api/downloadsand shown in hero, CTA, and stats.
Assets and Scripts
- CSS:
css/style.css(main),css/blog.css(blog). - JS:
js/nav-footer.js(mobile nav, hamburger, drawer),js/chat-widget.js(WhatsApp-style floating button and panel). Inline scripts onindex.phpfor FAQ accordion, download modals, download count, form submit; onsuggestions.phpfor captcha and form submit. - SEO:
sitemap.xml,robots.txt. Schema.org JSON-LD on homepage (SoftwareApplication, FAQPage, Organization, BreadcrumbList). Open Graph and Twitter Card meta tags.
Routing (Nginx + .htaccess)
- Nginx:
location /tries$uri,$uri/,$uri.php..htmlrequests are redirected to.phpin Nginx config. .htaccess:DirectoryIndex index.php index.html; RewriteRule redirects*.html→*.php(301).
22.3 Backend API (app/main.py)
Technology: FastAPI, SQLite (standard library), Pydantic. CORS and origin checks for public endpoints.
Database path: DB_PATH = "/var/www/mezbanpos.com/data/leads.sqlite". WAL mode enabled. Tables created in init_db().
Public Endpoints (No Auth)
| Method | Path | Description |
|---|---|---|
| GET | /api/captcha |
Returns { question, token } for math challenge (e.g. "7 + 3"). Token is HMAC-SHA256 signed; valid 10 minutes. |
| GET | /api/downloads |
Returns { count } — current download counter value. |
| POST | /api/downloads |
Body: { name, email, platform? }. Origin/referer must match mezbanpos.com / www.mezbanpos.com. Increments counter, inserts into downloads table; returns { ok: true, count }. |
| POST | /api/suggestions |
Form: name, email, suggestion, captcha_answer, captcha_token. Verifies captcha; inserts into suggestions. Returns { ok: true } or error. |
| POST | /api/submit-lead |
Form: name, phone, email, business, location, notes. Inserts into leads. Legacy lead form. |
| GET | /healthz |
Returns { ok: true, ts }. Used for liveness. |
App Endpoints (Desktop App → Cloud)
Used by the MezbanPOS Electron app when it has internet.
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/register |
Body: installId, machineId, name, email, phone, city, appVersion, platform. Upserts installs row; preserves existing license_key and license_status. |
| POST | /api/v1/heartbeat |
Body: installId, appVersion, platform. Updates last_seen_at, app_version, platform for that install. |
| GET | /api/v1/notifications |
Query: installId. Returns active notifications (optional filter by target = 'all' or install ID or city). |
| POST | /api/v1/license/validate |
Body: installId, machineId, licenseKey. Checks installs for matching row; returns { valid, expiresAt, type }. |
Admin Endpoints (Bearer Token)
Require header: Authorization: Bearer <ADMIN_SECRET>. ADMIN_SECRET from env (default in code for dev).
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/admin/login |
Body: { token }. Returns success if token matches ADMIN_SECRET. |
| GET | /api/v1/admin/installs |
Query: city, platform, license_status, search, page, limit. Paginated list of installs. |
| GET | /api/v1/admin/installs/export |
CSV export of all installs. |
| GET | /api/v1/admin/downloads |
Query: search, page, limit. Paginated downloads. |
| GET | /api/v1/admin/notifications |
List all notifications. |
| POST | /api/v1/admin/notifications |
Create notification (body: type, title, message, url, target, expiresAt). |
| PATCH | /api/v1/admin/notifications/{id} |
Update notification (active, title, message, url, target, type, expiresAt). |
| DELETE | /api/v1/admin/notifications/{id} |
Delete notification. |
| GET | /api/v1/admin/analytics |
Aggregates: total installs, installs last 30 days, active (last 7 days); by city, platform, app version; license breakdown (trial, active, expired). |
22.4 Backend Database Schema (This Repository)
SQLite database used by app/main.py (not the desktop app’s POS database).
| Table | Purpose |
|---|---|
leads |
Marketing leads: name, phone, email, business, location, notes, recaptcha_score, utm_meta, ip, user_agent, created_at. |
downloads |
Download events: name, email, ip, user_agent, platform, created_at. |
suggestions |
User suggestions: name, email, suggestion, ip, user_agent, created_at. |
counters |
Key-value; key downloads holds the public download count (incremented on each POST /api/downloads). |
installs |
Desktop app registrations: install_id, machineid, registered* (name, email, phone, city), app_version, platform, registered_at, last_seen_at, license_key, license_status. |
notifications |
In-app messages: id, type, title, message, url, target ('all' or install_id or city), active, created_at, expires_at. |
22.5 Deployment
- Web server: Nginx. Document root
html/. PHP via FastCGI (e.g.php8.3-fpm.sock). SSL via Certbot (Let’s Encrypt). - API: FastAPI app runs separately (e.g.
uvicorn app.main:app --host 127.0.0.1 --port 8001). Nginx proxies:location /api/→http://127.0.0.1:8001location = /healthz→http://127.0.0.1:8001/healthz
- Environment:
CAPTCHA_SECRET,ADMIN_SECRET,CORS_ORIGIN(optional).DB_PATHis hardcoded; ensuredata/exists and is writable. - Downloads: Installer files are served by Nginx from
html/downloads/(e.g.MezbanPOS Setup 0.1.0.exe,MezbanPOS-0.1.0-arm64.dmg,MezbanPOS-0.1.0.dmg). Add these files to the server; they are not in the repo.
22.6 Summary: What This Repo Implements
| Area | Implemented |
|---|---|
| Marketing site | Homepage, blog, suggestions, privacy, terms, Lahore landing, admin dashboard. |
| Download flow | Lead capture (name/email), platform-specific download links, download counter, macOS arch picker and instructions. |
| Lead & feedback | Lead form (submit-lead), suggestions form with math captcha. |
| Desktop app support | Install registration, heartbeat, notifications, license validation. |
| Admin | Token login; installs list/export; downloads list; notifications CRUD; analytics (installs, activity, license breakdown). |
| Infra | Nginx config, PHP + FastAPI, SQLite, health check. |