Architecture
High-level overview
┌─────────────────────────────────────────────────────────────────┐
│ Client (Browser) │
└───────────────────────────────┬─────────────────────────────────┘
│ HTTP
┌───────────────────────────────▼─────────────────────────────────┐
│ Frontend (React + Vite + Nginx) Port 8080 │
│ - Admin panel UI │
│ - Proxies /api/* to backend in Docker │
└───────────────────────────────┬─────────────────────────────────┘
│
┌───────────────────────────────▼─────────────────────────────────┐
│ Backend (Express + TypeScript) Port 3001 │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────────────┐ │
│ │ Routes │→ │ Services │→ │ Repositories │ │
│ └─────────────┘ └──────────────┘ └───────────┬─────────────┘ │
│ ┌─────────────────────────────────────────────┐ │ │
│ │ Middleware: Auth, RBAC, RateLimit, Error │ │ │
│ └─────────────────────────────────────────────┘ │ │
│ ┌─────────────────────────────────────────────┐ │ │
│ │ Dynamic Engine (runtime API handler) │ │ │
│ └─────────────────────────────────────────────┘ │ │
└──────────────────────────────────────────────────┼───────────────┘
│
┌──────────────────────────────────────────────────▼───────────────┐
│ MongoDB 7 Port 27017 │
│ Collections: users, groups, endpoints, endpointgroups, │
│ endpointdata, logs, systemsettings │
└──────────────────────────────────────────────────────────────────┘
Request flow
Management API request
Client → Express Route → authenticate → requirePermission → Service → Repository → MongoDB
Dynamic API request
Client → /api/* (dynamic.routes) → DynamicEngine
→ Load endpoint definition from MongoDB (path + method)
→ Check access (public / JWT / group)
→ Validate body against schema (POST/PUT/PATCH)
→ Read/write EndpointData collection
→ Log api_call → Return JSON response
Backend layers
Routes (backend/src/routes/)
Thin HTTP handlers. Parse query/body, call services, return JSON.
| Route prefix | Purpose |
|---|---|
/api/auth |
Login, logout, refresh, register |
/api/users |
User CRUD |
/api/groups |
RBAC group CRUD |
/api/profile |
Current user profile |
/api/endpoints |
Endpoint & endpoint group management |
/api/dashboard |
Stats, logs, system info |
/api/database |
Raw MongoDB explorer (manage_users only) |
/api/settings |
Platform settings |
/api/* |
Dynamic engine (catch-all) |
Services (backend/src/services/)
Business logic, validation, audit logging.
| Service | Responsibility |
|---|---|
authService |
Authentication, tokens |
userService |
Users and groups |
endpointService |
Endpoint CRUD, testing, docs |
dashboardService |
Statistics aggregation |
logService |
Audit log queries |
systemService |
OS/CPU/memory/disk info |
settingsService |
Cached settings, rate limit config |
Repositories (backend/src/repositories/)
MongoDB access only. No business logic.
Models (backend/src/models/)
| Model | Description |
|---|---|
User |
Accounts with group assignments |
Group |
RBAC groups with permissions |
Endpoint |
API definition (path, method, schema, access) |
EndpointGroup |
UI organization for endpoints |
EndpointData |
Stored records for dynamic endpoints |
Log |
Audit trail |
SystemSettings |
Key-value platform settings |
Note: The endpoint schema is stored in field
fieldson the model (notschema) due to MongooseDocument.schemanaming conflict. API DTOs still acceptschemain requests.
Frontend architecture
App.tsx
└── AuthProvider
└── Layout (sidebar navigation)
└── Pages (Dashboard, Endpoints, Users…)
└── components/UI.tsx (shared components)
└── services/api.ts (HTTP client)
Key frontend patterns
- JWT stored in localStorage with automatic refresh on 401
- SearchInput +
matchesSearch/useDebouncedValuefor list filtering - Pagination component with server-side (Users, Logs) and client-side (Endpoint Groups) modes
- Grouped endpoint tables — one collapsible section per endpoint group
Data model relationships
User ──many-to-many──▶ Group
Endpoint ──optional──▶ EndpointGroup
Endpoint / EndpointGroup ──networkAccess──▶ allowed domains + IP/CIDR rules
Endpoint ──one-to-many──▶ EndpointData (via endpointId + resourcePath)
EndpointData ──reference fields──▶ EndpointData (cross-endpoint links via `reference` schema fields)
Log ──optional──▶ User, Endpoint
Security architecture
Request
→ Helmet headers
→ CORS check
→ Rate limit (dynamic from settings)
→ JWT verification (if required)
→ Dynamic engine: network access (domains / IP pools)
→ Dynamic engine: endpoint access type (public / authenticated / group)
→ Permission check (RBAC, management API)
→ Handler
→ Audit log (on significant actions)
Docker architecture (Variant 1)
| Container | Image | Role |
|---|---|---|
dap-mongodb |
mongo:7 | Database |
dap-backend |
Custom Node build | API server |
dap-frontend |
Custom Nginx build | Static SPA + API proxy |
Volumes:
dap_mongodb_data— persistent databasedap_backend_logs— application logs
Deployment variants
| Variant | File / path | MongoDB |
|---|---|---|
| 1 — Docker single | docker-compose.yml |
1 node |
| 2 — Docker replica set | docker-compose.replica.yml |
3 nodes, rs0 |
| 3 — Kubernetes | k8s/ |
StatefulSet ×3, rs0 |
Guides: Deployment Variants · MongoDB Replica Set · Kubernetes
Seed data
On first startup, seedDatabase() creates:
- 5 system RBAC groups
- Admin user (Super Admin group)
- 7 system endpoints (auth, users, groups, profile)
- 3 default endpoint groups (CRM, SHOP, DEVICES)
- Default system settings