| --- |
| title: WifiBiz |
| emoji: 📡 |
| colorFrom: blue |
| colorTo: indigo |
| sdk: docker |
| app_port: 7860 |
| pinned: false |
| --- |
| |
| # WifiBiz — Multi-Tenant WiFi Hotspot Platform |
|
|
| A backend platform for selling WiFi access via captive portals. Built for small businesses (hotels, restaurants, shops) to monetize their internet connection. |
|
|
| ## Features |
|
|
| - Captive portal with M-Pesa payment integration (Snippe) |
| - Per-device WiFi plans with speed limits |
| - Omada SDN controller integration for client authorization |
| - Tenant dashboard API (devices, plans, sessions, payouts) |
| - Super admin panel |
| - SMS notifications via Android SMS Gateway |
| - Auto-renew, billing reminders, and session management |
|
|
| ## Stack |
|
|
| - **Runtime:** Node.js 20 + Express |
| - **Database:** MariaDB (persisted to `/data` volume) |
| - **Payments:** Snippe (M-Pesa STK Push) |
| - **WiFi Controller:** TP-Link Omada SDN |
|
|
| ## Environment Variables |
|
|
| Set these in Space Settings → Variables and secrets: |
|
|
| | Variable | Description | |
| |---|---| |
| | `JWT_SECRET` | Long random string for tenant JWT signing | |
| | `JWT_ADMIN_SECRET` | Long random string for admin JWT signing | |
| | `PAYMENT_CREDENTIAL_SECRET` | Long random string used to encrypt tenant-owned payment provider secrets | |
| | `ADMIN_TOKEN` | Static bearer token for admin endpoints | |
| | `OMADA_URL` | Omada controller URL (e.g. `https://1.2.3.4:8043`) | |
| | `OMADA_USER` | Omada admin username | |
| | `OMADA_PASS` | Omada admin password | |
| | `SNIPPE_API_KEY` | Snippe live API key | |
| | `SNIPPE_WEBHOOK_SECRET` | Snippe webhook signing secret | |
| | `SMS_GATEWAY_URL` | Android SMS Gateway endpoint | |
| | `SMS_GATEWAY_USER` | SMS gateway username | |
| | `SMS_GATEWAY_PASS` | SMS gateway password | |
| | `PORTAL_HOST` | Public hostname of this Space (e.g. `mbonea-wifibiz.hf.space`) | |
| | `PORTAL_SCHEME` | `https` | |
| | `DB_NAME` | `wifiplatform` | |
| | `DB_USER` | `wifiuser` | |
| | `DB_PASS` | A strong password for the MariaDB user | |
| | `DATA_ROOT` | Persistent data root for this Space, e.g. `/data/wifiplatform` for production or `/data/wifiplatform-v2` for staging | |
| | `RESTORE_SQL_PATH` | Optional first-run SQL dump path to restore instead of loading `schema.sql` | |
|
|
| ## Cloning Production Data for a v2 Space |
|
|
| Do not run two Spaces against the same MariaDB directory. Use a different `DATA_ROOT` per Space: |
|
|
| ```env |
| # Production Space |
| DATA_ROOT=/data/wifiplatform |
| DB_NAME=wifiplatform |
| |
| # v2/Staging Space |
| DATA_ROOT=/data/wifiplatform-v2 |
| DB_NAME=wifiplatform |
| RESTORE_SQL_PATH=/data/wifiplatform_backup.sql |
| ``` |
|
|
| Create the dump from production while production MariaDB is running: |
|
|
| ```bash |
| mysqldump -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" > /data/wifiplatform_backup.sql |
| ``` |
|
|
| Then start the v2 Space. On its first run, `entrypoint.sh` initializes `/data/wifiplatform-v2/mysql` and restores `RESTORE_SQL_PATH`. |
|
|