v1.3.0 — pannello admin completo, auth localStorage, Baileys WA, customers, calendario, paginazione, dashboard 7gg
This commit is contained in:
85
app/routers/settings.py
Normal file
85
app/routers/settings.py
Normal file
@@ -0,0 +1,85 @@
|
||||
"""Endpoint impostazioni — protetti con API key."""
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import text
|
||||
from app.database import get_db
|
||||
from app.routers.admin import verify_api_key
|
||||
|
||||
router = APIRouter(prefix="/api/admin/settings", tags=["settings"], dependencies=[Depends(verify_api_key)])
|
||||
|
||||
|
||||
@router.get("")
|
||||
def get_settings(db: Session = Depends(get_db)):
|
||||
"""Tutte le impostazioni come dict."""
|
||||
rows = db.execute(text("SELECT key, value FROM settings ORDER BY key")).fetchall()
|
||||
return {r[0]: r[1] for r in rows}
|
||||
|
||||
|
||||
@router.put("")
|
||||
def update_settings(data: dict, db: Session = Depends(get_db)):
|
||||
"""Aggiorna una o più impostazioni. Body: {"key": "value", ...}"""
|
||||
for k, v in data.items():
|
||||
db.execute(
|
||||
text("INSERT INTO settings (key, value, updated_at) VALUES (:k, :v, NOW()) "
|
||||
"ON CONFLICT (key) DO UPDATE SET value = :v, updated_at = NOW()"),
|
||||
{"k": k, "v": str(v)}
|
||||
)
|
||||
db.commit()
|
||||
return get_settings(db)
|
||||
|
||||
|
||||
@router.post("/test-email")
|
||||
async def test_email(db: Session = Depends(get_db)):
|
||||
"""Invia email di test con le impostazioni correnti."""
|
||||
rows = db.execute(text("SELECT key, value FROM settings WHERE key LIKE 'smtp_%'")).fetchall()
|
||||
cfg = {r[0]: r[1] for r in rows}
|
||||
|
||||
if not cfg.get("smtp_user"):
|
||||
raise HTTPException(400, "Credenziali SMTP non configurate")
|
||||
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
try:
|
||||
msg = MIMEText("<h2>Test notifiche Farmacia Ianni</h2><p>Le impostazioni email funzionano correttamente.</p>", "html")
|
||||
msg["Subject"] = "Test — Booking Farmacia Ianni"
|
||||
msg["From"] = cfg.get("smtp_from", cfg["smtp_user"])
|
||||
msg["To"] = cfg["smtp_user"]
|
||||
|
||||
with smtplib.SMTP(cfg.get("smtp_host", "smtp.gmail.com"), int(cfg.get("smtp_port", 587))) as server:
|
||||
server.starttls()
|
||||
server.login(cfg["smtp_user"], cfg.get("smtp_pass", ""))
|
||||
server.sendmail(msg["From"], cfg["smtp_user"], msg.as_string())
|
||||
return {"ok": True, "message": f"Email di test inviata a {cfg['smtp_user']}"}
|
||||
except Exception as e:
|
||||
raise HTTPException(500, f"Errore invio: {str(e)}")
|
||||
|
||||
|
||||
@router.get("/wa-status")
|
||||
async def wa_status(db: Session = Depends(get_db)):
|
||||
"""Stato connessione WhatsApp Baileys."""
|
||||
import httpx
|
||||
rows = db.execute(text("SELECT value FROM settings WHERE key = 'wa_service_url'")).fetchone()
|
||||
url = rows[0] if rows else "http://booking-wa:3100"
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=5) as client:
|
||||
r = await client.get(f"{url}/status")
|
||||
return r.json()
|
||||
except Exception as e:
|
||||
return {"connected": False, "error": str(e), "message": "Servizio WhatsApp non raggiungibile"}
|
||||
|
||||
|
||||
@router.get("/wa-qr")
|
||||
async def wa_qr(db: Session = Depends(get_db)):
|
||||
"""QR code per collegare WhatsApp."""
|
||||
import httpx
|
||||
rows = db.execute(text("SELECT value FROM settings WHERE key = 'wa_service_url'")).fetchone()
|
||||
url = rows[0] if rows else "http://booking-wa:3100"
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=10) as client:
|
||||
r = await client.get(f"{url}/qr")
|
||||
return r.json()
|
||||
except Exception as e:
|
||||
return {"qr": None, "error": str(e)}
|
||||
Reference in New Issue
Block a user