11 KiB
11 KiB
BellSystems Admin Panel — Strategy Guide
Project Overview
A self-hosted web-based admin panel for managing BellSystems devices, melodies, users, and MQTT communications. Built with Python (FastAPI) backend and React frontend, deployed on a VPS behind Nginx.
Deployment Architecture
[Browser] → [Nginx (VPS)]
├── / → React Frontend (static files)
└── /api → FastAPI Backend
├── Firestore (Google Cloud) via Admin SDK
├── Mosquitto (localhost on VPS)
└── Firebase Storage (for melody files)
Everything lives on the VPS:
- Nginx as reverse proxy + static file server
- FastAPI as the API backend
- Mosquitto MQTT broker (already running there)
- React frontend served as static files
- All containerized with Docker Compose
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React + Tailwind CSS + Vite |
| Backend | Python 3.11+ / FastAPI |
| Database | Firestore (via Firebase Admin SDK) |
| File Storage | Firebase Storage |
| MQTT | Mosquitto (local) + paho-mqtt |
| Auth | JWT (FastAPI) with role-based access |
| Deployment | Docker Compose + Nginx |
| VPS OS | Linux (existing VPS in Germany) |
Project Folder Structure
bellsystems-admin/
├── docker-compose.yml
├── .env # Secrets (gitignored)
├── .env.example # Template for env vars
├── README.md
│
├── backend/
│ ├── Dockerfile
│ ├── requirements.txt
│ ├── main.py # FastAPI app entry point
│ ├── config.py # Settings / env loading
│ │
│ ├── auth/
│ │ ├── __init__.py
│ │ ├── router.py # Login / token endpoints
│ │ ├── models.py # User/token schemas
│ │ ├── dependencies.py # JWT verification, role checks
│ │ └── utils.py # Password hashing, token creation
│ │
│ ├── melodies/
│ │ ├── __init__.py
│ │ ├── router.py # CRUD endpoints for melodies
│ │ ├── models.py # Pydantic schemas
│ │ └── service.py # Firestore operations
│ │
│ ├── devices/
│ │ ├── __init__.py
│ │ ├── router.py # CRUD endpoints for devices
│ │ ├── models.py # Pydantic schemas
│ │ └── service.py # Firestore operations
│ │
│ ├── users/
│ │ ├── __init__.py
│ │ ├── router.py # CRUD endpoints for users
│ │ ├── models.py # Pydantic schemas
│ │ └── service.py # Firestore operations
│ │
│ ├── mqtt/
│ │ ├── __init__.py
│ │ ├── router.py # Command endpoints + WebSocket for live data
│ │ ├── client.py # MQTT client wrapper (paho-mqtt)
│ │ ├── logger.py # Log storage and retrieval
│ │ └── mosquitto.py # Mosquitto password file management
│ │
│ ├── equipment/
│ │ ├── __init__.py
│ │ ├── router.py # Complementary devices / notes
│ │ ├── models.py
│ │ └── service.py
│ │
│ └── shared/
│ ├── __init__.py
│ ├── firebase.py # Firebase Admin SDK initialization
│ └── exceptions.py # Custom error handlers
│
├── frontend/
│ ├── Dockerfile
│ ├── package.json
│ ├── vite.config.js
│ ├── tailwind.config.js
│ ├── index.html
│ │
│ └── src/
│ ├── main.jsx
│ ├── App.jsx
│ │
│ ├── api/
│ │ └── client.js # Axios/fetch wrapper with JWT
│ │
│ ├── auth/
│ │ ├── LoginPage.jsx
│ │ └── AuthContext.jsx # JWT token state management
│ │
│ ├── layout/
│ │ ├── Sidebar.jsx # Navigation menu
│ │ ├── Header.jsx
│ │ └── MainLayout.jsx
│ │
│ ├── melodies/
│ │ ├── MelodyList.jsx
│ │ ├── MelodyForm.jsx # Add / Edit form
│ │ └── MelodyDetail.jsx
│ │
│ ├── devices/
│ │ ├── DeviceList.jsx
│ │ ├── DeviceForm.jsx
│ │ └── DeviceDetail.jsx
│ │
│ ├── users/
│ │ ├── UserList.jsx
│ │ ├── UserForm.jsx
│ │ └── UserDetail.jsx
│ │
│ ├── mqtt/
│ │ ├── MqttDashboard.jsx # Live data, logs, charts
│ │ └── CommandPanel.jsx # Send commands to devices
│ │
│ └── components/
│ ├── DataTable.jsx # Reusable table component
│ ├── SearchBar.jsx
│ ├── ConfirmDialog.jsx
│ └── StatusBadge.jsx
│
└── nginx/
└── nginx.conf # Nginx reverse proxy config
Auth & Roles
| Role | Access |
|---|---|
superadmin |
Everything — full CRUD on all resources |
melody_editor |
Melodies: full CRUD |
device_manager |
Devices + MQTT: full CRUD + commands |
user_manager |
Users: full CRUD |
viewer |
Read-only access to everything |
Admin users are stored in a separate Firestore collection (admin_users) or a local database (SQLite/PostgreSQL). JWT tokens carry the role, and FastAPI dependencies enforce permissions per endpoint.
Build Phases
Phase 0 — Project Scaffolding
- Initialize backend (FastAPI project structure)
- Initialize frontend (React + Vite + Tailwind)
- Docker Compose setup (backend + frontend + nginx)
- Environment variables / config
- Firebase Admin SDK setup (service account key)
- Verify Firestore connectivity
Phase 1 — Auth System
- Admin user model (Firestore or local DB)
- Login endpoint (email + password → JWT)
- JWT middleware for protected routes
- Role-based access control (RBAC) dependencies
- Login page (frontend)
- Auth context + protected routes (frontend)
Phase 2 — Melody Editor (Priority #1)
- Firestore melody document schema review
- Backend: CRUD endpoints (list, get, create, update, delete)
- Backend: Firebase Storage integration (upload/manage bin files)
- Frontend: Melody list with search/filter
- Frontend: Add/Edit melody form (all attributes)
- Frontend: Delete with confirmation
- Frontend: File upload for online melodies
Phase 3 — Device Editor
- Firestore device document schema review
- Backend: CRUD endpoints
- Backend: Serial number generation (unique)
- Backend: Mosquitto password registration (auto)
- Frontend: Device list with status indicators
- Frontend: Add/Edit device form
- Frontend: Delete with confirmation
Phase 4 — User Editor
- Firestore user document schema review
- Backend: CRUD endpoints
- Backend: User-device assignment management
- Frontend: User list with search/filter
- Frontend: Add/Edit user form
- Frontend: Block/unblock functionality
- Frontend: Device assignment UI
Phase 5 — MQTT Integration
- Backend: MQTT client (paho-mqtt) connecting to Mosquitto
- Backend: Send commands to devices via MQTT
- Backend: Receive and store device logs/heartbeats
- Backend: WebSocket endpoint for live MQTT data streaming
- Frontend: MQTT dashboard (live device status)
- Frontend: Command panel (send commands)
- Frontend: Log viewer with filtering
- Frontend: Basic charts/histograms (playback events, etc.)
Phase 6 — Equipment & Notes Tracking
- Backend: CRUD for complementary equipment notes
- Frontend: Simple note/log interface per device/user
Phase 7 — Polish & Deployment
- SSL certificates (Let's Encrypt via Certbot)
- Production Docker Compose config
- Nginx hardening
- Backup strategy for logs/data
- Error handling & loading states (frontend)
- Mobile responsiveness (basic)
Key Decisions
| Decision | Choice | Reason |
|---|---|---|
| Backend framework | FastAPI | Easy to learn, async, auto-docs |
| Frontend framework | React | Huge ecosystem, great for admin UIs |
| CSS framework | Tailwind CSS | Fast styling, no custom CSS needed |
| Build tool | Vite | Fast dev server, instant HMR |
| MQTT library | paho-mqtt (Python) | Standard, reliable, well-documented |
| Mosquitto auth | Password file (direct management) | Simple, no plugins needed |
| Deployment | Docker Compose on VPS | Single server, easy to manage |
| Admin auth storage | Firestore admin_users collection |
Consistent with existing data layer |
Environment Variables (.env)
# Firebase
FIREBASE_SERVICE_ACCOUNT_PATH=./firebase-service-account.json
# JWT
JWT_SECRET_KEY=your-secret-key-here
JWT_ALGORITHM=HS256
JWT_EXPIRATION_MINUTES=480
# MQTT
MQTT_BROKER_HOST=localhost
MQTT_BROKER_PORT=1883
MQTT_ADMIN_USERNAME=admin
MQTT_ADMIN_PASSWORD=your-mqtt-admin-password
MOSQUITTO_PASSWORD_FILE=/etc/mosquitto/passwd
# App
BACKEND_CORS_ORIGINS=["http://localhost:5173"]
DEBUG=true
First Steps for Claude Code
Once this strategy is reviewed and approved, the first command for Claude Code:
Initialize the bellsystems-admin project:
1. Create the folder structure as defined in the strategy guide
2. Set up the backend with FastAPI (main.py, config.py, requirements.txt)
3. Set up the frontend with React + Vite + Tailwind
4. Create docker-compose.yml with backend, frontend, and nginx services
5. Create the nginx.conf for reverse proxying
6. Create .env.example with all required variables
7. Wire up Firebase Admin SDK initialization (backend/shared/firebase.py)
8. Create a basic health-check endpoint to verify everything runs
Notes
- All Firestore document schemas will be reviewed together before building each module
- MQTT log storage strategy (local DB vs Firestore) to be decided in Phase 5
- The existing Flutter app (main product) remains unchanged — this admin panel is a separate tool
- OTA update management could be added as a future phase