added frontend
This commit is contained in:
parent
fca4f99675
commit
b5fb4a8888
35 changed files with 7405 additions and 20 deletions
|
@ -3,6 +3,7 @@ from typing import List
|
|||
from models import CreateOrderRequest, Order, DrinkType, MateType
|
||||
from database import db
|
||||
from websocket_manager import websocket_manager
|
||||
import json
|
||||
|
||||
app = FastAPI(
|
||||
title="Tschunk Order API",
|
||||
|
@ -10,22 +11,8 @@ app = FastAPI(
|
|||
version="1.0.0"
|
||||
)
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
"""Root endpoint with API information."""
|
||||
return {
|
||||
"message": "Willkommen zur Tschunk Order API!",
|
||||
"version": "1.0.0",
|
||||
"endpoints": {
|
||||
"POST /orders": "Neue Bestellung erstellen",
|
||||
"GET /orders": "Alle Bestellungen abrufen",
|
||||
"DELETE /orders/{order_id}": "Bestellung löschen",
|
||||
"WS /ws": "WebSocket für Echtzeit-Updates"
|
||||
},
|
||||
"available_drinks": [drink.value for drink in DrinkType],
|
||||
"available_mate_types": [mate.value for mate in MateType]
|
||||
}
|
||||
# Datenbank-Referenz im WebSocketManager setzen
|
||||
websocket_manager.set_database(db)
|
||||
|
||||
|
||||
@app.websocket("/ws")
|
||||
|
@ -41,6 +28,9 @@ async def websocket_endpoint(websocket: WebSocket):
|
|||
- order_created: {"type": "order_created", "order": {...}}
|
||||
- order_deleted: {"type": "order_deleted", "order_id": "..."}
|
||||
- all_orders: {"type": "all_orders", "orders": [...]}
|
||||
- create_order: {"type": "create_order", "drinks": [...]}
|
||||
- get_all_orders: {"type": "get_all_orders"}
|
||||
- delete_order: {"type": "delete_order", "order_id": "..."}
|
||||
"""
|
||||
await websocket_manager.connect(websocket)
|
||||
|
||||
|
@ -51,12 +41,31 @@ async def websocket_endpoint(websocket: WebSocket):
|
|||
|
||||
# Halte die Verbindung aufrecht und warte auf Nachrichten
|
||||
while True:
|
||||
# Warte auf Nachrichten vom Client (kann für Pings/Pongs verwendet werden)
|
||||
# Warte auf Nachrichten vom Client
|
||||
data = await websocket.receive_text()
|
||||
|
||||
# Optional: Echo für Pings
|
||||
if data == "ping":
|
||||
await websocket.send_text("pong")
|
||||
try:
|
||||
# Versuche JSON zu parsen
|
||||
message = json.loads(data)
|
||||
message_type = message.get("type")
|
||||
|
||||
if message_type == "ping":
|
||||
await websocket.send_text("pong")
|
||||
elif message_type == "create_order":
|
||||
await websocket_manager.handle_create_order(websocket, message)
|
||||
elif message_type == "get_all_orders":
|
||||
await websocket_manager.handle_get_all_orders(websocket)
|
||||
elif message_type == "delete_order":
|
||||
await websocket_manager.handle_delete_order(websocket, message)
|
||||
else:
|
||||
print(f"Unbekannte Nachrichtenart: {message_type}")
|
||||
|
||||
except json.JSONDecodeError:
|
||||
# Fallback für einfache Textnachrichten (z.B. "ping")
|
||||
if data == "ping":
|
||||
await websocket.send_text("pong")
|
||||
else:
|
||||
print(f"Ungültige JSON-Nachricht: {data}")
|
||||
|
||||
except WebSocketDisconnect:
|
||||
websocket_manager.disconnect(websocket)
|
||||
|
|
|
@ -3,11 +3,17 @@ from typing import List, Dict, Any
|
|||
import json
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
from models import CreateOrderRequest, Drink
|
||||
|
||||
|
||||
class WebSocketManager:
|
||||
def __init__(self):
|
||||
self.active_connections: List[WebSocket] = []
|
||||
self.db = None # Wird später gesetzt
|
||||
|
||||
def set_database(self, database):
|
||||
"""Setzt die Datenbank-Referenz (Dependency Injection)."""
|
||||
self.db = database
|
||||
|
||||
async def connect(self, websocket: WebSocket):
|
||||
"""Neue WebSocket-Verbindung hinzufügen."""
|
||||
|
@ -42,6 +48,144 @@ class WebSocketManager:
|
|||
for connection in disconnected:
|
||||
self.disconnect(connection)
|
||||
|
||||
async def send_to_client(self, websocket: WebSocket, message: Dict[str, Any]):
|
||||
"""Nachricht an einen spezifischen Client senden."""
|
||||
try:
|
||||
message_json = json.dumps(message, default=str)
|
||||
await websocket.send_text(message_json)
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Senden an WebSocket: {e}")
|
||||
self.disconnect(websocket)
|
||||
|
||||
async def handle_create_order(self, websocket: WebSocket, data: Dict[str, Any]):
|
||||
"""Behandelt eine Bestellungsanfrage über WebSocket."""
|
||||
try:
|
||||
# Validierung der Anfrage
|
||||
if "drinks" not in data or not data["drinks"]:
|
||||
await self.send_to_client(websocket, {
|
||||
"type": "order_created_response",
|
||||
"success": False,
|
||||
"error": "Mindestens ein Getränk muss bestellt werden",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
return
|
||||
|
||||
# Drinks aus der Anfrage erstellen
|
||||
drinks = []
|
||||
for drink_data in data["drinks"]:
|
||||
drink = Drink(
|
||||
drink_type=drink_data["drink_type"],
|
||||
mate_type=drink_data["mate_type"],
|
||||
quantity=drink_data["quantity"],
|
||||
notes=drink_data.get("notes", "")
|
||||
)
|
||||
drinks.append(drink)
|
||||
|
||||
# Bestellung in der Datenbank erstellen
|
||||
if self.db:
|
||||
order = await self.db.create_order(drinks)
|
||||
|
||||
# Erfolgsantwort an den Client senden
|
||||
await self.send_to_client(websocket, {
|
||||
"type": "order_created_response",
|
||||
"success": True,
|
||||
"order": order.model_dump(),
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
else:
|
||||
await self.send_to_client(websocket, {
|
||||
"type": "order_created_response",
|
||||
"success": False,
|
||||
"error": "Datenbank nicht verfügbar",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Erstellen der Bestellung über WebSocket: {e}")
|
||||
await self.send_to_client(websocket, {
|
||||
"type": "order_created_response",
|
||||
"success": False,
|
||||
"error": f"Fehler beim Erstellen der Bestellung: {str(e)}",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
async def handle_get_all_orders(self, websocket: WebSocket):
|
||||
"""Sendet alle Bestellungen an den anfragenden Client."""
|
||||
try:
|
||||
if self.db:
|
||||
orders = self.db.get_all_orders()
|
||||
await self.send_to_client(websocket, {
|
||||
"type": "all_orders",
|
||||
"orders": [order.model_dump() for order in orders],
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
else:
|
||||
await self.send_to_client(websocket, {
|
||||
"type": "all_orders",
|
||||
"orders": [],
|
||||
"error": "Datenbank nicht verfügbar",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Abrufen aller Bestellungen: {e}")
|
||||
await self.send_to_client(websocket, {
|
||||
"type": "all_orders",
|
||||
"orders": [],
|
||||
"error": f"Fehler beim Abrufen der Bestellungen: {str(e)}",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
async def handle_delete_order(self, websocket: WebSocket, data: Dict[str, Any]):
|
||||
"""Behandelt eine Bestelllöschung über WebSocket."""
|
||||
try:
|
||||
# Validierung der Anfrage
|
||||
if "order_id" not in data or not data["order_id"]:
|
||||
await self.send_to_client(websocket, {
|
||||
"type": "order_deleted_response",
|
||||
"success": False,
|
||||
"error": "Order ID ist erforderlich",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
return
|
||||
|
||||
order_id = data["order_id"]
|
||||
|
||||
# Bestellung in der Datenbank löschen
|
||||
if self.db:
|
||||
success = await self.db.delete_order(order_id)
|
||||
|
||||
if success:
|
||||
# Erfolgsantwort an den Client senden
|
||||
await self.send_to_client(websocket, {
|
||||
"type": "order_deleted_response",
|
||||
"success": True,
|
||||
"message": f"Bestellung {order_id} wurde erfolgreich gelöscht",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
else:
|
||||
await self.send_to_client(websocket, {
|
||||
"type": "order_deleted_response",
|
||||
"success": False,
|
||||
"error": "Bestellung nicht gefunden",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
else:
|
||||
await self.send_to_client(websocket, {
|
||||
"type": "order_deleted_response",
|
||||
"success": False,
|
||||
"error": "Datenbank nicht verfügbar",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Löschen der Bestellung über WebSocket: {e}")
|
||||
await self.send_to_client(websocket, {
|
||||
"type": "order_deleted_response",
|
||||
"success": False,
|
||||
"error": f"Fehler beim Löschen der Bestellung: {str(e)}",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
async def broadcast_order_created(self, order: Dict[str, Any]):
|
||||
"""Broadcast für neue Bestellung."""
|
||||
message = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue