fix(account): close deletion cache gap
CI and Deploy / test (pull_request) Successful in 5m22s
CI and Deploy / deploy (pull_request) Has been skipped

Require authenticated sidecar cache purge before a deletion can complete and keep failures retryable. Mount tombstones outside restored application data while leaving deletion disabled by default.
This commit is contained in:
cesnimda
2026-08-15 19:40:07 +02:00
parent c0e190d5b5
commit 7185491a05
14 changed files with 134 additions and 20 deletions
+15 -3
View File
@@ -175,6 +175,7 @@ if EAGER_MODEL_LOAD and not SKIP_MODEL_LOAD:
_ensure_runtime_loaded()
cache = TTLCache(maxsize=1024, ttl=60 * 60)
cache_lock = threading.Lock()
class SummarizeRequest(BaseModel):
@@ -959,8 +960,10 @@ async def summarize(req: SummarizeRequest):
raise HTTPException(status_code=400, detail="min_length must be smaller than max_length.")
key = _key(req.text, req.max_length, req.min_length, req.top_skills)
if key in cache:
return {"summary": cache[key], "cached": True}
with cache_lock:
cached_summary = cache.get(key)
if cached_summary is not None:
return {"summary": cached_summary, "cached": True}
info = _role_focused_excerpt(req.text)
summary = _model_summarize(info["focused_input"], req.max_length, req.min_length)
@@ -1028,10 +1031,19 @@ async def summarize(req: SummarizeRequest):
lines.append("- Prepare examples showing relevant impact, collaboration, and delivery.")
out = "\n".join(lines).strip()
cache[key] = out
with cache_lock:
cache[key] = out
return {"summary": out, "cached": False}
@app.delete("/maintenance/cache")
async def purge_cache():
with cache_lock:
cleared = len(cache)
cache.clear()
return {"cleared": cleared}
def _normalize_text(value: str) -> str:
value = value.replace("\x00", " ")
return re.sub(r"\s+", " ", value).strip()
+16
View File
@@ -510,6 +510,22 @@ def test_health_stays_open_so_probes_and_healthchecks_work(monkeypatch):
assert client.get("/health").status_code == 200
def test_cache_purge_requires_service_token_and_clears_content(monkeypatch):
module = load_app_module(monkeypatch, service_token="s3cret")
module.cache["synthetic-key"] = "synthetic-summary"
client = TestClient(module.app)
assert client.delete("/maintenance/cache").status_code == 401
response = client.delete(
"/maintenance/cache",
headers={"X-Ai-Service-Token": "s3cret"},
)
assert response.status_code == 200
assert response.json() == {"cleared": 1}
assert len(module.cache) == 0
def test_endpoints_stay_open_when_no_token_is_configured(monkeypatch):
module = load_app_module(monkeypatch)
client = TestClient(module.app)