Hotspot billing system powered by nextjs, cloudflare, and intergrated with mikrotik and tenda AP
# We-Connect — Wi-Fi & TV Captive Billing Engine
**Gecab Systems Ltd**
This is a real billing system that moves real customer money through
a live M-Pesa Till/Paybill and controls real network access on a
production MikroTik router. Follow this guide in order — don't skip
the testing steps before flipping `MPESA_ENV=production`.
---
## 0. What you're deploying
- Windows PC/mini-PC running Node.js + Docker Desktop, on the same
network as the MikroTik router (or reachable to it).
- PostgreSQL + Redis in Docker containers (billing records + fast
session cache).
- A Next.js app: customer-facing captive portal + payment API +
M-Pesa webhook receiver, publicly reachable over HTTPS (Safaricom
will not call an HTTP or LAN-only callback URL).
- A MikroTik router (RouterOS v7.1+) as the enforcement point.
---
## 1. Prerequisites
1. **Windows 10/11 Pro or Server**, with virtualization enabled in
BIOS (Docker Desktop needs it).
2. **Docker Desktop for Windows** — install from docker.com, set the
backend to **WSL2** (Settings → General → "Use the WSL 2 based
engine"), and set it to **start on login** (Settings → General)
so all containers come back up after a reboot. This is the only
thing that's actually required to run the app now — Node.js
itself runs *inside* the containers, not on Windows directly.
**Store the project inside the WSL2 filesystem**, not on a Windows
drive (`C:\...`) — e.g. clone/unzip it under `\\wsl$\Ubuntu\home\ \we-connect`
or directly from within a WSL terminal. Bind-mounting a folder
that lives on the Windows NTFS side into a Linux container goes
through a translation layer that's noticeably slower and can miss
file-change events, which shows up as "I edited the file but
hot-reload didn't pick it up." Keeping the project inside WSL2
avoids that entirely.
3. **Node.js 18.18+ LTS** — optional. Only needed on the host if you
want to run one-off commands outside Docker (e.g. generating a
secret with `node -e ...`, or running `npm run dev` directly
ins …