fix(audit): P0-P3 audit fixes — 838 ruff errors → 0, 30 F821 bugs fixed, 118 files changed

- P0: hooks.py 3-tuple fix, trigger_dispatcher Contract, contacts/plugin unregister_actions_by_owner
- P0: 5 test files — check_permission mocks removed, hardcoded DB credential → env var
- P1: attachment_service DmsFile via Contract helper, restore_registry/history_hooks dedup
- P1: mail/plugin restore unregister, mcp_client datetime.now(UTC), saved_views/filters patterns
- P1: ProtectedRoute fail-closed, 13 test assertion fixes (bcrypt, DB-URLs, SECRET_KEYs)
- P2: deprecated notifications → post_system_message (3 files), forgejo Base, report_generator lazy import
- P2: webhooks permissions, deps.py/roles.py plugin perms removed, import_export default
- P2: address/tags/entity_links patterns removed, worker.py Contract-Umgehungen fixed
- P2: 28 frontend TODOs (hardcoded constants, deprecated notification API)
- P3: dead code, duplicates, deprecated imports, private attr, __import__ inline
- P3: 8 frontend TODOs (LucideIcons, inline styles, XSS, i18n)
- ruff: 838 → 0 (612 auto-fix + 246 manual + 27 F821 regression fix)
- F821: 30 → 0 (AutomationDefinition, DmsFile, user_id, Path, Any, String)
- Contract-Umgehungen: 2 neue gefunden (worker.py:169, worker.py:280) und gefixt
This commit is contained in:
Agent Zero
2026-08-16 01:17:18 +02:00
parent 3d9b76cea4
commit abbe7a18fc
306 changed files with 5912 additions and 1827 deletions
+11 -12
View File
@@ -4,7 +4,8 @@ from __future__ import annotations
import logging
import uuid
from datetime import datetime, timezone
from datetime import UTC, datetime
from typing import Any
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import text
@@ -12,7 +13,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from app.core.db import get_db
from app.core.jobs import enqueue_job
from app.core.permissions import resolve_permissions, filter_fields_by_permission
from app.core.permissions import filter_fields_by_permission, resolve_permissions
from app.deps import get_current_user, require_permission
from app.plugins.builtins.unified_search.provider_registry import get_search_registry
from app.plugins.builtins.unified_search.query_understanding import (
@@ -28,7 +29,6 @@ from app.plugins.builtins.unified_search.schemas import (
SearchResult,
SimilarRequest,
SimilarResponse,
SuggestRequest,
SuggestResponse,
)
from app.plugins.builtins.unified_search.search_engine import (
@@ -80,7 +80,7 @@ def _parse_date(value: str | None) -> datetime | None:
try:
dt = datetime.fromisoformat(value)
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
dt = dt.replace(tzinfo=UTC)
return dt
except ValueError:
return None
@@ -109,7 +109,7 @@ def _apply_filters_and_sort(
except ValueError:
continue
if ts.tzinfo is None:
ts = ts.replace(tzinfo=timezone.utc)
ts = ts.replace(tzinfo=UTC)
if date_from and ts < date_from:
continue
if date_to and ts > date_to:
@@ -169,7 +169,7 @@ async def _do_search(
resolved_perms = await resolve_permissions(db, user_id, tenant_id)
# Map entity_type to module name for field-level permissions
_ENTITY_TO_MODULE = {
_entity_to_module = {
"contact": "contacts",
"mail": "mail",
"file": "dms",
@@ -189,7 +189,7 @@ async def _do_search(
data=filter_fields_by_permission(
r.get("data", {}),
resolved_perms,
_ENTITY_TO_MODULE.get(r.get("entity_type", ""), r.get("entity_type", "")),
_entity_to_module.get(r.get("entity_type", ""), r.get("entity_type", "")),
),
)
for r in results
@@ -307,7 +307,7 @@ async def find_similar(
try:
entity_id = uuid.UUID(req.entity_id)
except ValueError:
raise HTTPException(status_code=400, detail="Invalid entity_id")
raise HTTPException(status_code=400, detail="Invalid entity_id") from None
similar = await find_similar_all_types(
db=db,
@@ -382,7 +382,7 @@ async def rebuild_entity_index(
try:
eid = uuid.UUID(entity_id)
except ValueError:
raise HTTPException(status_code=400, detail="Invalid entity_id")
raise HTTPException(status_code=400, detail="Invalid entity_id") from None
from app.plugins.builtins.unified_search.lifecycle import rebuild_index
@@ -407,9 +407,9 @@ async def purge_entity_index(
try:
eid = uuid.UUID(entity_id)
except ValueError:
raise HTTPException(status_code=400, detail="Invalid entity_id")
raise HTTPException(status_code=400, detail="Invalid entity_id") from None
from app.plugins.builtins.unified_search.lifecycle import remove_from_index, remove_chunks
from app.plugins.builtins.unified_search.lifecycle import remove_chunks, remove_from_index
await remove_from_index(db, entity_type, eid, tenant_id)
if entity_type == "file":
@@ -522,7 +522,6 @@ async def search_stats(
stats: dict = {}
tables = {
"contacts": "embedding",
"contacts": "embedding",
"mails": "embedding",
"files": "embedding",