# 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) ```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