feat: homelab deployment - NPM + IONOS DNS + monitoring + NAS backup
- Restructured docker-compose for Nginx Proxy Manager (no custom nginx) - Added domain wordly.art configuration - Added Prometheus + Grafana monitoring stack with pre-configured dashboards - Added PostgreSQL backup script to NAS (daily/weekly/monthly rotation) - Added alert rules for backend, system, and Docker metrics - Updated deployment guide for NPM + IONOS DNS homelab setup - Added marketing plan document - PDF translator and watermark support - Enhanced middleware, routes, and translator modules Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -592,6 +592,34 @@ async def get_tracked_files(is_admin: bool = Depends(require_admin)):
|
||||
return {"count": len(tracked), "files": tracked}
|
||||
|
||||
|
||||
@router.post("/quota/reset")
|
||||
async def reset_translation_quotas(is_admin: bool = Depends(require_admin)):
|
||||
"""Reset monthly translation quotas for all free-tier users.
|
||||
Clears Redis keys matching quota:monthly:*
|
||||
"""
|
||||
try:
|
||||
from core.redis import get_async_redis
|
||||
redis_client = get_async_redis()
|
||||
if not redis_client:
|
||||
return {"status": "skipped", "message": "Redis not available, quotas are in-memory only"}
|
||||
|
||||
# Find all monthly quota keys
|
||||
keys = []
|
||||
async for key in redis_client.scan_iter(match="quota:monthly:*"):
|
||||
keys.append(key)
|
||||
|
||||
if keys:
|
||||
deleted = await redis_client.delete(*keys)
|
||||
logger.info("admin_quota_reset", keys_deleted=deleted)
|
||||
return {"status": "success", "keys_deleted": deleted, "message": f"Reset {deleted} quota counters"}
|
||||
else:
|
||||
return {"status": "success", "keys_deleted": 0, "message": "No active quotas to reset"}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Admin quota reset failed: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"Quota reset failed: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/config/provider")
|
||||
async def update_default_provider(
|
||||
provider: str = Form(...),
|
||||
|
||||
Reference in New Issue
Block a user