fix: A26 + A33 + A34 + A35 + A36 + A43 — bande S/XS du P2 (v7.3.9)
- A26 — champ `standalone` mort supprimé (0 lecteur) ; `sqlite:////data/…` ne produit plus de chemin UNC sous Windows ; `.env.example` ne promet plus PostgreSQL ; raise au boot si `APP_SECRET_KEY` vaut la valeur par défaut - A33 — rate limit : préfixes manquants (`/scim/v2/`, `/workspace/`, `/db/` + non-GET sur `/s/` et `/f/`), limite lue dans `settings.rate_limit_requests` (60 annoncés / 100 codés en dur), clé `X-Forwarded-For` seulement derrière un proxy local (anti-spoof), `_store` épuré (mémoire bornée) + test dédié - A34 — `_spawn()` : les 10 schedulers loggent leur exception et redémarrent après 10 s au lieu de mourir en silence ; 2 `logger.debug` de scheduler → warning - A35 — OpenAPI régénéré 439 → 511 chemins (`info.version 7.3.9`), README (était v6.7.0), compteur API_GUIDE, titre dupliqué retiré du ROADMAP ; le drift Python 3.12/3.13 reste noté (rebuild d'image à valider) - A36 — 4 dépendances mortes purgées de requirements.txt (aiosqlite, slowapi, loguru, packaging = 0 import) ; pyproject reste sans [project] : Docker et la CI installent requirements.txt, dupliquer les 22 deps créerait 2 sources - A43 — 15 `datetime.utcnow()` → `now(UTC).replace(tzinfo=None)` (format ISO naïf identique, warnings de dépréciation divisés : 2374 → 926) suite **1029/1029** · `ruff check app tests` OK · docs/ROADMAP/CHANGELOG/WORKLOAD à jour
This commit is contained in:
@@ -24,7 +24,7 @@ import asyncio
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import UTC, datetime, timedelta
|
||||
|
||||
import httpx
|
||||
|
||||
@@ -420,7 +420,7 @@ def cron_due(expression: str, last_run_at: str | None, now: datetime | None = No
|
||||
expr = (expression or "").strip().lower()
|
||||
if not expr:
|
||||
return False
|
||||
now = now or datetime.utcnow()
|
||||
now = now or datetime.now(UTC).replace(tzinfo=None)
|
||||
minute = now.minute
|
||||
fields = expr.split()
|
||||
|
||||
@@ -488,7 +488,7 @@ async def automation_scheduler():
|
||||
from app.services.workers import run_due_workers
|
||||
await run_due_workers()
|
||||
except Exception: # noqa: BLE001
|
||||
logger.debug("worker cron iteration failed")
|
||||
logger.warning("worker cron iteration failed")
|
||||
except Exception: # noqa: BLE001
|
||||
logger.warning("automation_scheduler iteration failed")
|
||||
await asyncio.sleep(60)
|
||||
|
||||
@@ -466,7 +466,7 @@ async def calendar_sync_scheduler(interval_seconds: int = 900) -> None:
|
||||
except Exception as exc: # noqa: BLE001 — one link must not kill the loop
|
||||
logger.debug("calendar sync link %s failed: %s", link_id, exc)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
logger.debug("calendar_sync_scheduler: %s", exc)
|
||||
logger.warning("calendar_sync_scheduler: %s", exc)
|
||||
await asyncio.sleep(interval_seconds)
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import json
|
||||
import logging
|
||||
import sqlite3
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import UTC
|
||||
from typing import Any
|
||||
|
||||
from app.db import get_conn
|
||||
@@ -744,7 +745,7 @@ class DeleteDocument(Tool):
|
||||
return ToolResult(status="error", tool=self.name,
|
||||
message=f"Document #{pid} introuvable")
|
||||
conn.execute("UPDATE pages SET deleted_at=? WHERE id=?",
|
||||
(datetime.utcnow().isoformat(), pid))
|
||||
(datetime.now(UTC).replace(tzinfo=None).isoformat(), pid))
|
||||
conn.commit()
|
||||
return ToolResult(
|
||||
status="success", tool=self.name, target_type="document", target_id=pid,
|
||||
|
||||
@@ -10,7 +10,7 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import re
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import UTC, datetime, timedelta
|
||||
|
||||
from app.db import get_conn
|
||||
|
||||
@@ -46,7 +46,7 @@ def purge_expired(days: int = 30) -> dict:
|
||||
|
||||
Returns a summary of what was purged.
|
||||
"""
|
||||
cutoff = datetime.utcnow() - timedelta(days=days)
|
||||
cutoff = datetime.now(UTC).replace(tzinfo=None) - timedelta(days=days)
|
||||
purged: list[int] = []
|
||||
with get_conn() as conn:
|
||||
rows = conn.execute(
|
||||
|
||||
Reference in New Issue
Block a user