This document is a course-oriented system architecture blueprint for building a multi-tenant Internet Service Provider (ISP) management and captive portal platform with NestJS, TypeScript, PostgreSQL, FreeRADIUS, Redis, WireGuard, and Vue.
It explains the architecture as a standalone NestJS system. The emphasis is on reusable engineering ideas: clear service boundaries, modular domain design, centralized authentication and accounting, payment-driven access, router automation, reliable financial records, and operational visibility.
1. Executive Summary and Architectural Philosophy
An ISP platform coordinates two very different worlds:
- a business system for vendors, customers, packages, billing, payments, support, and reporting; and
- a network control system for routers, subscriber authentication, accounting, access policies, and remote provisioning.
The platform uses a service-oriented NestJS monorepo with a modular domain core. A small set of independently deployable services owns the main technical boundaries, while the business capabilities live in cohesive NestJS modules inside the ISP service.
flowchart TD
subgraph Actors["Users and External Systems"]
Subscriber["Hotspot / PPPoE Subscriber"]
Vendor["ISP Vendor / Administrator"]
PaymentProvider["M-Pesa / Paystack"]
Router["MikroTik Router"]
end
subgraph Edge["Presentation and Edge"]
Web["Vue Web Application"]
Caddy["Caddy Edge Proxy"]
Gateway["NestJS API Gateway"]
end
subgraph NestServices["NestJS Services"]
Identity["Identity Service"]
ISP["ISP Service — Modular Domain Core"]
RouterService["Router Service"]
end
subgraph NetworkServices["Network Access Layer"]
Radius["FreeRADIUS"]
WireGuard["WireGuard VPN"]
end
subgraph Data["Platform Data and Infrastructure"]
Postgres[(PostgreSQL)]
Redis[(Redis)]
MinIO[(MinIO Object Storage)]
end
Vendor --> Web
Subscriber --> Caddy
Web --> Caddy
Caddy --> Gateway
Gateway --> Identity
Gateway --> ISP
Gateway --> RouterService
PaymentProvider -->|Callbacks| ISP
Router -->|RADIUS auth and accounting| Radius
Router <-->|Encrypted management tunnel| WireGuard
RouterService --> WireGuard
RouterService -->|RouterOS API| Router
Identity --> Postgres
ISP --> Postgres
ISP --> Redis
ISP --> MinIO
RouterService --> Postgres
Radius --> Postgres
Core architecture principles
- Separate technical boundaries, modularize business boundaries. Authentication and router control are isolated services. Related business domains remain modules in one ISP service, reducing unnecessary distributed-system complexity.
- PostgreSQL is the system of record. Business, payment, RADIUS, router-job, audit, and accounting data share one relational source of truth with explicit tenant relationships.
- FreeRADIUS owns the packet-level AAA path. NestJS manages policies and records; FreeRADIUS handles Authentication, Authorization, and Accounting using standard RADIUS tables.
- Every business record is tenant-scoped. Vendors own sites, users, packages, customers, subscriptions, payments, and operational data. Authorization must validate both identity and tenant scope.
- Network management uses a private control plane. WireGuard provides secure reachability to remote sites; the router service encapsulates RouterOS commands and provisioning workflows.
- Financial workflows are auditable and idempotent. Provider references are unique, callbacks can be retried safely, and money movements are represented by immutable ledger entries.
- Background work is explicit. NestJS scheduling handles periodic monitoring, quota evaluation, reminders, billing, recovery, and reconciliation without blocking user-facing requests.