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
+17 -13
View File
@@ -1,38 +1,37 @@
"""SQLAlchemy models for LeoCRM."""
from app.models.address import Address
from app.models.bank_account import BankAccount
from app.models.ai_conversation import AIConversation, AIMessage
from app.models.attachment import Attachment
from app.models.audit import AuditLog
from app.models.auth import ApiToken, PasswordResetToken
from app.models.backup import Backup
from app.models.bank_account import BankAccount
from app.models.consumer_inbox import ConsumerInbox
from app.models.contact import Contact, ContactPerson
from app.models.contact_folder import ContactFolder
from app.models.contact_merge import ContactMergeHistory
from app.models.entity_permission import EntityPermission
from app.models.consumer_inbox import ConsumerInbox
from app.models.outbox_delivery import OutboxDelivery
from app.models.entity_policy import EntityPolicy
from app.models.permission_template import PermissionTemplate
from app.models.permission_delegation import PermissionDelegation
from app.models.owned_mixin import OwnedMixin
from app.models.entity_history import EntityHistory
from app.models.currency import Currency
from app.models.custom_field_definition import CustomFieldDefinition
from app.models.entity_history import EntityHistory
from app.models.entity_permission import EntityPermission
from app.models.entity_policy import EntityPolicy
from app.models.group import Group, UserGroup
from app.models.notification import Notification, NotificationPreference, NotificationType
from app.models.owned_mixin import OwnedMixin
from app.models.permission_delegation import PermissionDelegation
from app.models.permission_template import PermissionTemplate
from app.models.plugin import Plugin, PluginMigration
from app.models.role import Role
from app.models.saved_view import SavedView
from app.models.sequence import Sequence
from app.models.session import Session
from app.models.system_settings import SystemSettings
from app.models.tax import TaxRate
from app.models.tenant import Tenant
from app.models.user import User, UserTenant
from app.models.backup import Backup
from app.models.custom_field_definition import CustomFieldDefinition
from app.models.webhook import Webhook
from app.models.workflow import Workflow, WorkflowInstance, WorkflowStepHistory
from app.models.saved_view import SavedView
__all__ = [
"Tenant",
@@ -79,4 +78,9 @@ __all__ = [
"SavedView",
]
from app.models.entity_attachment import EntityAttachment # noqa: F401
from app.models.workspace import Workspace, WorkspaceModule, WorkspaceUser, WorkspaceWidget # noqa: F401
from app.models.workspace import ( # noqa: F401
Workspace,
WorkspaceModule,
WorkspaceUser,
WorkspaceWidget,
)
-1
View File
@@ -11,7 +11,6 @@ from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
from app.core.db import Base, TenantMixin
from app.models.owned_mixin import OwnedMixin
class AIConversation(Base, TenantMixin):
+1 -2
View File
@@ -3,9 +3,8 @@
from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import DateTime, ForeignKey, Index, Integer, String
from sqlalchemy import ForeignKey, Index, Integer, String
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
-1
View File
@@ -19,7 +19,6 @@ from app.core.db import Base, TenantMixin
# Re-export EntityHistory as DeletionLog for backward compatibility.
# Tests import DeletionLog from app.models.audit and use entity_snapshot attribute.
from app.models.entity_history import EntityHistory as DeletionLog
class AuditLog(Base, TenantMixin):
+2 -3
View File
@@ -13,16 +13,15 @@ from typing import Any
from sqlalchemy import (
Computed,
Float,
ForeignKey,
Index,
Numeric,
String,
Text,
Float,
UniqueConstraint,
)
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.dialects.postgresql import TSVECTOR
from sqlalchemy.dialects.postgresql import JSONB, TSVECTOR
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column, relationship
+1 -2
View File
@@ -7,9 +7,8 @@ for manual ordering via drag & drop.
from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import DateTime, ForeignKey, Index, Integer, String, func
from sqlalchemy import ForeignKey, Index, Integer, String
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column, relationship
+1 -1
View File
@@ -5,7 +5,7 @@ from __future__ import annotations
import uuid
from typing import Any
from sqlalchemy import Boolean, Integer, JSON, String, UniqueConstraint
from sqlalchemy import JSON, Boolean, Integer, String, UniqueConstraint
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
+5 -5
View File
@@ -5,7 +5,7 @@ from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import DateTime, ForeignKey, Index, String
from sqlalchemy import DateTime, ForeignKey, Index, String, text
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
@@ -15,7 +15,7 @@ from app.models.owned_mixin import OwnedMixin
class EntityAttachment(Base, TenantMixin, OwnedMixin):
"""Links a DMS file to any entity (contact, address, invoice, etc.).
The actual file is stored in the DMS (files table).
This table only holds the reference + category + display_name.
"""
@@ -42,10 +42,10 @@ class EntityAttachment(Base, TenantMixin, OwnedMixin):
PGUUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True
)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=__import__('sqlalchemy').func.now()
DateTime(timezone=True), nullable=False, server_default=text('now()')
)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=__import__('sqlalchemy').func.now(),
onupdate=__import__('sqlalchemy').func.now(),
DateTime(timezone=True), nullable=False, server_default=text('now()'),
onupdate=text('now()'),
)
deleted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
-1
View File
@@ -23,7 +23,6 @@ import uuid
from datetime import datetime
from sqlalchemy import (
Boolean,
CheckConstraint,
DateTime,
ForeignKey,
+2 -2
View File
@@ -30,10 +30,10 @@ from sqlalchemy import (
Index,
Integer,
String,
Text,
func,
)
from sqlalchemy.dialects.postgresql import JSONB, UUID as PGUUID
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
from app.core.db import Base, TenantMixin
+1 -1
View File
@@ -6,7 +6,7 @@ import uuid
from datetime import datetime
from typing import Any
from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, UniqueConstraint, func
from sqlalchemy import DateTime, ForeignKey, Integer, String, UniqueConstraint, func
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
-1
View File
@@ -19,7 +19,6 @@ from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
from app.core.db import Base, TenantMixin
from app.models.owned_mixin import OwnedMixin
class Notification(Base, TenantMixin):
+1 -1
View File
@@ -15,7 +15,7 @@ from __future__ import annotations
import uuid
from sqlalchemy import ForeignKey, Index
from sqlalchemy import ForeignKey
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
+2 -2
View File
@@ -14,10 +14,10 @@ from sqlalchemy import (
CheckConstraint,
DateTime,
ForeignKey,
String,
func,
)
from sqlalchemy.dialects.postgresql import JSONB, UUID as PGUUID
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
from app.core.db import Base, TenantMixin
+2 -1
View File
@@ -15,7 +15,8 @@ from sqlalchemy import (
String,
func,
)
from sqlalchemy.dialects.postgresql import JSONB, UUID as PGUUID
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
from app.core.db import Base, TenantMixin
+1 -2
View File
@@ -3,9 +3,8 @@
from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import Boolean, DateTime, ForeignKey, String, Text, func
from sqlalchemy import Boolean, ForeignKey, String, Text
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
-1
View File
@@ -7,7 +7,6 @@ from datetime import datetime
from typing import Any
from sqlalchemy import DateTime, Integer, String, func
from sqlalchemy import Boolean
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
+1 -2
View File
@@ -3,9 +3,8 @@
from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import DateTime, Index, Integer, String
from sqlalchemy import Index, Integer, String
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
+1 -2
View File
@@ -3,9 +3,8 @@
from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import DateTime, ForeignKey, Index, Integer, String
from sqlalchemy import ForeignKey, Index, Integer, String
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
+1 -2
View File
@@ -3,10 +3,9 @@
from __future__ import annotations
import uuid
from datetime import datetime
from decimal import Decimal
from sqlalchemy import Boolean, DateTime, Index, Numeric, String
from sqlalchemy import Boolean, Index, Numeric, String
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
+1 -1
View File
@@ -4,7 +4,7 @@ from __future__ import annotations
import uuid
from sqlalchemy import Boolean, Integer, JSON, String
from sqlalchemy import JSON, Boolean, Integer, String
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column