Phase 0 Complete by ClaudeCode
This commit is contained in:
10
backend/Dockerfile
Normal file
10
backend/Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
|
||||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
||||
0
backend/auth/__init__.py
Normal file
0
backend/auth/__init__.py
Normal file
1
backend/auth/dependencies.py
Normal file
1
backend/auth/dependencies.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: JWT verification, role checks
|
||||
1
backend/auth/models.py
Normal file
1
backend/auth/models.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: User/token Pydantic schemas
|
||||
1
backend/auth/router.py
Normal file
1
backend/auth/router.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Login / token endpoints
|
||||
1
backend/auth/utils.py
Normal file
1
backend/auth/utils.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Password hashing, token creation
|
||||
33
backend/config.py
Normal file
33
backend/config.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from pydantic_settings import BaseSettings
|
||||
from typing import List
|
||||
import json
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
# Firebase
|
||||
firebase_service_account_path: str = "./firebase-service-account.json"
|
||||
|
||||
# JWT
|
||||
jwt_secret_key: str = "change-me-in-production"
|
||||
jwt_algorithm: str = "HS256"
|
||||
jwt_expiration_minutes: int = 480
|
||||
|
||||
# MQTT
|
||||
mqtt_broker_host: str = "localhost"
|
||||
mqtt_broker_port: int = 1883
|
||||
mqtt_admin_username: str = "admin"
|
||||
mqtt_admin_password: str = ""
|
||||
mosquitto_password_file: str = "/etc/mosquitto/passwd"
|
||||
|
||||
# App
|
||||
backend_cors_origins: str = '["http://localhost:5173"]'
|
||||
debug: bool = True
|
||||
|
||||
@property
|
||||
def cors_origins(self) -> List[str]:
|
||||
return json.loads(self.backend_cors_origins)
|
||||
|
||||
model_config = {"env_file": ".env", "extra": "ignore"}
|
||||
|
||||
|
||||
settings = Settings()
|
||||
0
backend/devices/__init__.py
Normal file
0
backend/devices/__init__.py
Normal file
1
backend/devices/models.py
Normal file
1
backend/devices/models.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Device Pydantic schemas
|
||||
1
backend/devices/router.py
Normal file
1
backend/devices/router.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: CRUD endpoints for devices
|
||||
1
backend/devices/service.py
Normal file
1
backend/devices/service.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Device Firestore operations
|
||||
0
backend/equipment/__init__.py
Normal file
0
backend/equipment/__init__.py
Normal file
1
backend/equipment/models.py
Normal file
1
backend/equipment/models.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Equipment Pydantic schemas
|
||||
1
backend/equipment/router.py
Normal file
1
backend/equipment/router.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Complementary devices / notes endpoints
|
||||
1
backend/equipment/service.py
Normal file
1
backend/equipment/service.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Equipment Firestore operations
|
||||
29
backend/main.py
Normal file
29
backend/main.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from config import settings
|
||||
from shared.firebase import init_firebase, firebase_initialized
|
||||
|
||||
app = FastAPI(
|
||||
title="BellSystems Admin Panel",
|
||||
version="0.1.0",
|
||||
docs_url="/api/docs",
|
||||
openapi_url="/api/openapi.json",
|
||||
)
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=settings.cors_origins,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup():
|
||||
init_firebase()
|
||||
|
||||
|
||||
@app.get("/api/health")
|
||||
async def health_check():
|
||||
return {"status": "ok", "firebase": firebase_initialized}
|
||||
0
backend/melodies/__init__.py
Normal file
0
backend/melodies/__init__.py
Normal file
1
backend/melodies/models.py
Normal file
1
backend/melodies/models.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Melody Pydantic schemas
|
||||
1
backend/melodies/router.py
Normal file
1
backend/melodies/router.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: CRUD endpoints for melodies
|
||||
1
backend/melodies/service.py
Normal file
1
backend/melodies/service.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Melody Firestore operations
|
||||
0
backend/mqtt/__init__.py
Normal file
0
backend/mqtt/__init__.py
Normal file
1
backend/mqtt/client.py
Normal file
1
backend/mqtt/client.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: MQTT client wrapper (paho-mqtt)
|
||||
1
backend/mqtt/logger.py
Normal file
1
backend/mqtt/logger.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Log storage and retrieval
|
||||
1
backend/mqtt/mosquitto.py
Normal file
1
backend/mqtt/mosquitto.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Mosquitto password file management
|
||||
1
backend/mqtt/router.py
Normal file
1
backend/mqtt/router.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Command endpoints + WebSocket for live data
|
||||
9
backend/requirements.txt
Normal file
9
backend/requirements.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
fastapi==0.115.6
|
||||
uvicorn[standard]==0.34.0
|
||||
pydantic-settings==2.7.1
|
||||
python-dotenv==1.0.1
|
||||
firebase-admin==6.6.0
|
||||
paho-mqtt==2.1.0
|
||||
python-jose[cryptography]==3.3.0
|
||||
passlib[bcrypt]==1.7.4
|
||||
python-multipart==0.0.20
|
||||
0
backend/shared/__init__.py
Normal file
0
backend/shared/__init__.py
Normal file
1
backend/shared/exceptions.py
Normal file
1
backend/shared/exceptions.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: Custom error handlers
|
||||
24
backend/shared/firebase.py
Normal file
24
backend/shared/firebase.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import firebase_admin
|
||||
from firebase_admin import credentials, firestore
|
||||
from config import settings
|
||||
|
||||
db = None
|
||||
firebase_initialized = False
|
||||
|
||||
|
||||
def init_firebase():
|
||||
"""Initialize Firebase Admin SDK. Call once at app startup."""
|
||||
global db, firebase_initialized
|
||||
try:
|
||||
cred = credentials.Certificate(settings.firebase_service_account_path)
|
||||
firebase_admin.initialize_app(cred)
|
||||
db = firestore.client()
|
||||
firebase_initialized = True
|
||||
except Exception as e:
|
||||
print(f"[WARNING] Firebase init failed: {e}")
|
||||
firebase_initialized = False
|
||||
|
||||
|
||||
def get_db():
|
||||
"""Return the Firestore client. None if Firebase is not initialized."""
|
||||
return db
|
||||
0
backend/users/__init__.py
Normal file
0
backend/users/__init__.py
Normal file
1
backend/users/models.py
Normal file
1
backend/users/models.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: User Pydantic schemas
|
||||
1
backend/users/router.py
Normal file
1
backend/users/router.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: CRUD endpoints for users
|
||||
1
backend/users/service.py
Normal file
1
backend/users/service.py
Normal file
@@ -0,0 +1 @@
|
||||
# TODO: User Firestore operations
|
||||
Reference in New Issue
Block a user