fix: BUG-038 (audit log for tags/tasks/wiki/mail/calendar), BUG-072 (workflow instance), BUG-052 (miniapps), BUG-047 (approvals), BUG-037 (compliance), BUG-030 (GRANT DELETE), BUG-016 (search use_ai), BUG-014 (tags assign), BUG-009 (contact folders), BUG-073 (broken imports)
Check Cross-Plugin Imports / check (push) Has been cancelled
Check Cross-Plugin Imports / check (push) Has been cancelled
This commit is contained in:
@@ -39,6 +39,7 @@ from app.plugins.builtins.calendar.models import (
|
|||||||
)
|
)
|
||||||
from app.plugins.builtins.calendar.recurrence import generate_occurrences
|
from app.plugins.builtins.calendar.recurrence import generate_occurrences
|
||||||
from app.plugins.builtins.calendar.schemas import (
|
from app.plugins.builtins.calendar.schemas import (
|
||||||
|
from app.core.audit import log_audit
|
||||||
BookResourceRequest,
|
BookResourceRequest,
|
||||||
BulkAction,
|
BulkAction,
|
||||||
CalendarCreate,
|
CalendarCreate,
|
||||||
@@ -467,6 +468,7 @@ async def create_entry(
|
|||||||
# Record history (D-PLUG)
|
# Record history (D-PLUG)
|
||||||
from app.services.entity_history_service import record_history
|
from app.services.entity_history_service import record_history
|
||||||
await record_history(db, tenant_id, user_id, "calendar_entry", entry.id, "create", snapshot_after=_entry_to_dict(entry))
|
await record_history(db, tenant_id, user_id, "calendar_entry", entry.id, "create", snapshot_after=_entry_to_dict(entry))
|
||||||
|
await log_audit(db, tenant_id, user_id, "create", "calendar_entry", entry.id, changes={"title": entry.title, "entry_type": entry.entry_type})
|
||||||
|
|
||||||
# ── Hook: calendar.after_appointment (Action) ──
|
# ── Hook: calendar.after_appointment (Action) ──
|
||||||
from app.core.hooks import do_action
|
from app.core.hooks import do_action
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ from app.plugins.builtins.mail.schemas import (
|
|||||||
VacationConfig,
|
VacationConfig,
|
||||||
)
|
)
|
||||||
from app.plugins.builtins.mail.services import (
|
from app.plugins.builtins.mail.services import (
|
||||||
|
from app.core.audit import log_audit
|
||||||
MAX_ATTACHMENT_SIZE,
|
MAX_ATTACHMENT_SIZE,
|
||||||
_sanitize_filename,
|
_sanitize_filename,
|
||||||
account_to_response,
|
account_to_response,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from app.core.visibility import apply_visibility_filter
|
|||||||
from app.deps import get_current_user, require_permission
|
from app.deps import get_current_user, require_permission
|
||||||
from app.plugins.builtins.tags.models import Tag, TagAssignment
|
from app.plugins.builtins.tags.models import Tag, TagAssignment
|
||||||
from app.plugins.builtins.tags.schemas import (
|
from app.plugins.builtins.tags.schemas import (
|
||||||
|
from app.core.audit import log_audit
|
||||||
TagAssignRequest,
|
TagAssignRequest,
|
||||||
TagBulkAssignRequest,
|
TagBulkAssignRequest,
|
||||||
TagCreate,
|
TagCreate,
|
||||||
@@ -118,6 +119,8 @@ async def create_tag(
|
|||||||
await db.flush()
|
await db.flush()
|
||||||
from app.core.hooks import do_action
|
from app.core.hooks import do_action
|
||||||
await do_action("tag.after_create", {"id": str(tag.id), "name": tag.name, "color": tag.color}, db=db, tenant_id=tenant_id, user_id=user_id)
|
await do_action("tag.after_create", {"id": str(tag.id), "name": tag.name, "color": tag.color}, db=db, tenant_id=tenant_id, user_id=user_id)
|
||||||
|
await log_audit(db, tenant_id, user_id, "create", "tag", tag.id, changes={"name": tag.name, "color": tag.color})
|
||||||
|
await db.commit()
|
||||||
return {
|
return {
|
||||||
"id": str(tag.id),
|
"id": str(tag.id),
|
||||||
"name": tag.name,
|
"name": tag.name,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from app.core.db import get_db
|
|||||||
from app.deps import get_current_user, require_permission
|
from app.deps import get_current_user, require_permission
|
||||||
from app.plugins.builtins.tasks import services
|
from app.plugins.builtins.tasks import services
|
||||||
from app.plugins.builtins.tasks.schemas import (
|
from app.plugins.builtins.tasks.schemas import (
|
||||||
|
from app.core.audit import log_audit
|
||||||
TaskAssignRequest,
|
TaskAssignRequest,
|
||||||
TaskCreate,
|
TaskCreate,
|
||||||
TaskDependencyRequest,
|
TaskDependencyRequest,
|
||||||
@@ -80,7 +81,10 @@ async def create_task(
|
|||||||
tenant_id = uuid.UUID(current_user["tenant_id"])
|
tenant_id = uuid.UUID(current_user["tenant_id"])
|
||||||
user_id = uuid.UUID(current_user["user_id"])
|
user_id = uuid.UUID(current_user["user_id"])
|
||||||
data = body.model_dump()
|
data = body.model_dump()
|
||||||
return await services.create_task(db, tenant_id, user_id, data)
|
result = await services.create_task(db, tenant_id, user_id, data)
|
||||||
|
if result and result.get("id"):
|
||||||
|
await log_audit(db, tenant_id, user_id, "create", "task", uuid.UUID(result["id"]), changes={"title": data.get("title", "")})
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{task_id}", dependencies=[Depends(require_permission("tasks:read"))])
|
@router.get("/{task_id}", dependencies=[Depends(require_permission("tasks:read"))])
|
||||||
@@ -127,6 +131,7 @@ async def delete_task(
|
|||||||
deleted = await services.delete_task(db, tenant_id, tid)
|
deleted = await services.delete_task(db, tenant_id, tid)
|
||||||
if not deleted:
|
if not deleted:
|
||||||
raise HTTPException(404, detail={"detail": "Task not found", "code": "not_found"})
|
raise HTTPException(404, detail={"detail": "Task not found", "code": "not_found"})
|
||||||
|
await log_audit(db, tenant_id, user_id, "delete", "task", tid)
|
||||||
return Response(status_code=status.HTTP_204_NO_CONTENT)
|
return Response(status_code=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from app.core.db import get_db
|
|||||||
from app.deps import get_current_user, require_permission
|
from app.deps import get_current_user, require_permission
|
||||||
from app.plugins.builtins.wiki import services
|
from app.plugins.builtins.wiki import services
|
||||||
from app.plugins.builtins.wiki.schemas import ArticleCreate, ArticleUpdate, CategoryCreate, CategoryUpdate
|
from app.plugins.builtins.wiki.schemas import ArticleCreate, ArticleUpdate, CategoryCreate, CategoryUpdate
|
||||||
|
from app.core.audit import log_audit
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/v1/wiki", tags=["wiki"])
|
router = APIRouter(prefix="/api/v1/wiki", tags=["wiki"])
|
||||||
|
|
||||||
@@ -33,9 +34,12 @@ async def create_article(
|
|||||||
db: AsyncSession = Depends(get_db),
|
db: AsyncSession = Depends(get_db),
|
||||||
current_user: dict = Depends(require_permission("wiki:write")),
|
current_user: dict = Depends(require_permission("wiki:write")),
|
||||||
):
|
):
|
||||||
return await services.create_article(
|
tenant_id = uuid.UUID(current_user["tenant_id"])
|
||||||
db, uuid.UUID(current_user["tenant_id"]), uuid.UUID(current_user["user_id"]), body.model_dump(),
|
user_id = uuid.UUID(current_user["user_id"])
|
||||||
)
|
result = await services.create_article(db, tenant_id, user_id, body.model_dump())
|
||||||
|
if result and result.get("id"):
|
||||||
|
await log_audit(db, tenant_id, user_id, "create", "wiki_article", uuid.UUID(result["id"]), changes={"title": body.title})
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
@router.get("/articles/{article_id}")
|
@router.get("/articles/{article_id}")
|
||||||
@@ -72,9 +76,12 @@ async def delete_article(
|
|||||||
db: AsyncSession = Depends(get_db),
|
db: AsyncSession = Depends(get_db),
|
||||||
current_user: dict = Depends(require_permission("wiki:delete")),
|
current_user: dict = Depends(require_permission("wiki:delete")),
|
||||||
):
|
):
|
||||||
ok = await services.delete_article(db, uuid.UUID(current_user["tenant_id"]), uuid.UUID(article_id))
|
tenant_id = uuid.UUID(current_user["tenant_id"])
|
||||||
|
user_id = uuid.UUID(current_user["user_id"])
|
||||||
|
ok = await services.delete_article(db, tenant_id, uuid.UUID(article_id))
|
||||||
if not ok:
|
if not ok:
|
||||||
raise HTTPException(status_code=404, detail={"detail": "Article not found", "code": "not_found"})
|
raise HTTPException(status_code=404, detail={"detail": "Article not found", "code": "not_found"})
|
||||||
|
await log_audit(db, tenant_id, user_id, "delete", "wiki_article", uuid.UUID(article_id))
|
||||||
|
|
||||||
|
|
||||||
@router.get("/articles/{article_id}/versions")
|
@router.get("/articles/{article_id}/versions")
|
||||||
|
|||||||
Reference in New Issue
Block a user