fix(arch): externes Audit — 13 Backend-Fixes (Workspace-Modules, Tenant-Manifeste, Lifecycle, Contracts, Permissions)
Check Cross-Plugin Imports / check (push) Has been cancelled
Check Cross-Plugin Imports / check (push) Has been cancelled
Verifikation: Alle 17 Audit-Findings gegen den Code geprueft — alle bestaetigt. Backend-Lifecycle-Fixes umgesetzt; 4 Frontend-Plugin-Architektur-Punkte als Phase Q in die Roadmap eingeplant. - P1 list_workspaces: Module + User-Counts gebuendelt laden (Editor-Overwrite-Bug) - P1 active-manifests: Tenant-Deaktivierung (tenant_plugin_activation) filtern - P1 uninstall: volle Service-Deactivation VOR registry.uninstall() - P1 ContractRegistry: DB-Aktivstatus-Guard (Restart-Edge-Case) + Re-Activate - P1/P2 Field-Definitions: voller Lifecycle (register/unregister) im Service - P1/P2 Contact-Felddefinitionen (39) ins ContactsPlugin-Manifest verschoben - P1 12 fehlende Permission-Keys registriert (AST-Scan: 0 fehlend) - P2 contact_folder -> ContactsPlugin; ENTITY_PLUGIN_OWNERS wird befuellt - P2 Entity-Permission-Fallback fail-closed statt contacts:read - P2 forgejo_error_reporter is_core=False; DMS is_core=True (ADR-020) - P2 Worker: Contacts-Trash-Cleanup ins Plugin (get_job_modules-Discovery) - P1/P2 DSGVO-Export delegiert an DSAR-Collector (kein Core->Contacts) - P2 False-green Tests korrigiert (or True, veraltete Route-Count-Assertion) Verifikation: tests/test_audit_architecture_fixes.py 17/17; Regressionen gruen (contacts_lifecycle, entity_registry, workspace_scopes, rbac, lifecycle_service); Combo-Order-Test 35/35; Cross-Plugin-Checker 497/0; compileall sauber; ruff auf 7-Error-Baseline. Doku: PROGRESS.md Audit-Section, PLATFORM_ROADMAP.md Phase Q (Q1-Q4), plugin-development-guide.md Lifecycle, permissions.md Katalog.
This commit is contained in:
@@ -10,6 +10,7 @@ import logging
|
||||
|
||||
from app.plugins.base import BasePlugin
|
||||
from app.plugins.manifest import (
|
||||
FieldDefinition,
|
||||
FrontendDashboardWidget,
|
||||
FrontendMenuItem,
|
||||
FrontendPageRoute,
|
||||
@@ -106,18 +107,70 @@ class ContactsPlugin(BasePlugin):
|
||||
"contacts:write",
|
||||
"contacts:delete",
|
||||
],
|
||||
# Audit P1/P2: contact field definitions are plugin-owned (moved
|
||||
# from CORE_FIELD_DEFINITIONS) — registered at activation time via
|
||||
# register_field_definitions() and removed on deactivation.
|
||||
field_definitions=[
|
||||
FieldDefinition(module="contacts", field="firstname", label="First Name", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="surname", label="Last Name", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="displayname", label="Display Name", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="name", label="Name", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="email_1", label="Email 1", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="email_2", label="Email 2", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="phone_1", label="Phone 1", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="phone_2", label="Phone 2", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="mobilephone", label="Mobile", sensitivity="sensitive"),
|
||||
FieldDefinition(module="contacts", field="function", label="Position", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="website", label="Website", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="status", label="Status", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="type", label="Type", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="gender", label="Gender", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="suffix", label="Suffix", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="ext_name_line", label="Extra Name Line", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="country", label="Country", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="code", label="Code", sensitivity="sensitive"),
|
||||
FieldDefinition(module="contacts", field="accounting_code", label="Accounting Code", sensitivity="sensitive"),
|
||||
FieldDefinition(module="contacts", field="vendor_accounting_code", label="Vendor Accounting Code", sensitivity="sensitive"),
|
||||
FieldDefinition(module="contacts", field="vat_code", label="VAT Code", sensitivity="sensitive"),
|
||||
FieldDefinition(module="contacts", field="fiscal_code", label="Fiscal Code", sensitivity="sensitive"),
|
||||
FieldDefinition(module="contacts", field="commerce_code", label="Commerce Code", sensitivity="sensitive"),
|
||||
FieldDefinition(module="contacts", field="purchase_number", label="Purchase Number", sensitivity="sensitive"),
|
||||
FieldDefinition(module="contacts", field="bic", label="BIC", sensitivity="sensitive"),
|
||||
FieldDefinition(module="contacts", field="mailing_street", label="Mailing Street", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="mailing_city", label="Mailing City", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="mailing_postalcode", label="Mailing Postal Code", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="mailing_country", label="Mailing Country", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="visit_street", label="Visit Street", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="visit_city", label="Visit City", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="visit_postalcode", label="Visit Postal Code", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="visit_country", label="Visit Country", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="invoice_street", label="Invoice Street", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="invoice_city", label="Invoice City", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="invoice_postalcode", label="Invoice Postal Code", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="invoice_country", label="Invoice Country", sensitivity="normal"),
|
||||
FieldDefinition(module="contacts", field="notes", label="Notes", sensitivity="sensitive"),
|
||||
FieldDefinition(module="contacts", field="tags", label="Tags", sensitivity="sensitive"),
|
||||
],
|
||||
is_core=True,
|
||||
author="LeoCRM Team",
|
||||
min_app_version="1.0.0",
|
||||
contract_version="1.0.0",
|
||||
)
|
||||
|
||||
def get_job_modules(self) -> list[str]:
|
||||
"""Worker discovers the contacts trash-cleanup job here (audit P2)."""
|
||||
return ["app.plugins.builtins.contacts.jobs"]
|
||||
|
||||
def get_entity_models(self) -> dict[str, type]:
|
||||
from app.models.contact import Contact
|
||||
from app.models.contact_folder import ContactFolder
|
||||
return {
|
||||
"contact": Contact,
|
||||
"contacts": Contact,
|
||||
"company": Contact,
|
||||
# Audit P2: contact_folder is contacts-plugin-owned domain data
|
||||
# (moved from the static core ENTITY_MODELS map).
|
||||
"contact_folder": ContactFolder,
|
||||
}
|
||||
|
||||
async def on_activate(self, db, service_container, event_bus) -> None:
|
||||
|
||||
Reference in New Issue
Block a user