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:
2026-05-10 11:43:28 +02:00
parent 16ac7ca2b9
commit ce8e150a61
110 changed files with 6935 additions and 4301 deletions

View File

@@ -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(...),