94 lines
3.6 KiB
Python
94 lines
3.6 KiB
Python
from fastapi import APIRouter, Depends, Query
|
|
from uuid import UUID
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from database.postgres import get_pg_session
|
|
from auth.dependencies import require_permission
|
|
from auth.models import TokenPayload
|
|
from notes import service
|
|
from notes.models import EntryCreate, EntryUpdate, EntryOut, EntryListResponse, LinksReplaceIn
|
|
from shared.audit import log_action
|
|
|
|
router = APIRouter(prefix="/api/notes", tags=["notes"])
|
|
|
|
|
|
@router.get("", response_model=EntryListResponse)
|
|
async def list_entries(
|
|
type: str | None = Query(None),
|
|
status: str | None = Query(None),
|
|
severity: str | None = Query(None),
|
|
category: str | None = Query(None),
|
|
page: int = Query(1, ge=1),
|
|
limit: int = Query(25, ge=1, le=100),
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "view")),
|
|
):
|
|
rows, total = await service.list_entries(db, type, status, severity, category, page, limit)
|
|
return {"data": rows, "pagination": {"page": page, "limit": limit, "total": total}}
|
|
|
|
|
|
@router.get("/by-entity/{entity_type}/{entity_id}", response_model=list[EntryOut])
|
|
async def list_by_entity(
|
|
entity_type: str, entity_id: str,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "view")),
|
|
):
|
|
return await service.list_entries_for_entity(db, entity_type, entity_id)
|
|
|
|
|
|
@router.get("/{entry_id}", response_model=EntryOut)
|
|
async def get_entry(
|
|
entry_id: UUID,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "view")),
|
|
):
|
|
return await service.get_entry(db, entry_id)
|
|
|
|
|
|
@router.post("", response_model=EntryOut, status_code=201)
|
|
async def create_entry(
|
|
body: EntryCreate,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "add")),
|
|
):
|
|
entry = await service.create_entry(db, body, _user.sub, _user.name or _user.email)
|
|
await log_action(db, _user.sub, _user.name or _user.email, "CREATE", "note",
|
|
str(entry.id), entry.title or entry.type)
|
|
return entry
|
|
|
|
|
|
@router.patch("/{entry_id}", response_model=EntryOut)
|
|
async def update_entry(
|
|
entry_id: UUID, body: EntryUpdate,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "edit")),
|
|
):
|
|
entry = await service.update_entry(db, entry_id, body)
|
|
await log_action(db, _user.sub, _user.name or _user.email, "UPDATE", "note",
|
|
str(entry_id), entry.title or entry.type)
|
|
return entry
|
|
|
|
|
|
@router.patch("/{entry_id}/links", response_model=EntryOut)
|
|
async def replace_links(
|
|
entry_id: UUID, body: LinksReplaceIn,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "edit")),
|
|
):
|
|
entry = await service.replace_links(db, entry_id, body.links)
|
|
await log_action(db, _user.sub, _user.name or _user.email, "UPDATE", "note",
|
|
str(entry_id), entry.title or entry.type,
|
|
meta={"action_detail": "links_updated"})
|
|
return entry
|
|
|
|
|
|
@router.delete("/{entry_id}", status_code=204)
|
|
async def delete_entry(
|
|
entry_id: UUID,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "delete")),
|
|
):
|
|
entry = await service.get_entry(db, entry_id)
|
|
await service.delete_entry(db, entry_id)
|
|
await log_action(db, _user.sub, _user.name or _user.email, "DELETE", "note",
|
|
str(entry_id), entry.title or entry.type if entry else str(entry_id))
|