mirror of
https://github.com/idrainformatica/PecFlow.git
synced 2026-06-16 12:45:42 +02:00
Fix vari frontend
This commit is contained in:
@@ -21,6 +21,8 @@ from app.schemas.mailbox import (
|
||||
MailboxCreateRequest,
|
||||
MailboxListResponse,
|
||||
MailboxResponse,
|
||||
MailboxSyncResponse,
|
||||
MailboxUnreadCountsResponse,
|
||||
MailboxUpdateRequest,
|
||||
)
|
||||
from app.services.mailbox_service import MailboxService
|
||||
@@ -123,6 +125,52 @@ async def list_mailboxes(
|
||||
)
|
||||
|
||||
|
||||
@router.get("/unread-counts", response_model=MailboxUnreadCountsResponse)
|
||||
async def get_unread_counts(
|
||||
current_user: CurrentUser,
|
||||
db: DB,
|
||||
) -> MailboxUnreadCountsResponse:
|
||||
"""
|
||||
Restituisce il numero di messaggi non letti per ciascuna casella accessibile.
|
||||
Usato dalla sidebar per mostrare i badge per casella.
|
||||
- Admin: conta su tutte le caselle del tenant.
|
||||
- Operatori: solo le caselle con permesso can_read.
|
||||
"""
|
||||
from sqlalchemy import func, select
|
||||
from app.models.message import Message
|
||||
|
||||
# Determina le caselle visibili
|
||||
if current_user.is_admin:
|
||||
visible_ids = None # nessun filtro
|
||||
else:
|
||||
from app.services.permission_service import PermissionService
|
||||
perm_svc = PermissionService(db)
|
||||
visible_ids = await perm_svc.get_visible_mailboxes(current_user)
|
||||
if not visible_ids:
|
||||
return MailboxUnreadCountsResponse(counts={})
|
||||
|
||||
q = (
|
||||
select(Message.mailbox_id, func.count().label("cnt"))
|
||||
.where(
|
||||
Message.tenant_id == current_user.tenant_id,
|
||||
Message.is_read == False, # noqa: E712
|
||||
Message.direction == "inbound",
|
||||
Message.is_trashed == False, # noqa: E712
|
||||
Message.is_archived == False, # noqa: E712
|
||||
Message.parent_message_id.is_(None),
|
||||
)
|
||||
.group_by(Message.mailbox_id)
|
||||
)
|
||||
|
||||
if visible_ids is not None:
|
||||
from app.models.mailbox import Mailbox
|
||||
q = q.where(Message.mailbox_id.in_(visible_ids))
|
||||
|
||||
rows = (await db.execute(q)).all()
|
||||
counts = {str(row.mailbox_id): row.cnt for row in rows}
|
||||
return MailboxUnreadCountsResponse(counts=counts)
|
||||
|
||||
|
||||
@router.get("/{mailbox_id}", response_model=MailboxResponse)
|
||||
async def get_mailbox(
|
||||
mailbox_id: uuid.UUID,
|
||||
@@ -200,3 +248,52 @@ async def test_mailbox_connection(
|
||||
tenant_id=current_user.tenant_id,
|
||||
data=data,
|
||||
)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{mailbox_id}/sync",
|
||||
response_model=MailboxSyncResponse,
|
||||
)
|
||||
async def force_sync_mailbox(
|
||||
mailbox_id: uuid.UUID,
|
||||
current_user: AdminUser,
|
||||
db: DB,
|
||||
) -> MailboxSyncResponse:
|
||||
"""
|
||||
Forza una sincronizzazione IMAP immediata della casella.
|
||||
Accoda il job sync_mailbox nel worker tramite arq/Redis.
|
||||
Utile dopo un errore di connessione o per forzare un aggiornamento.
|
||||
Richiede ruolo **admin**.
|
||||
"""
|
||||
from app.core.exceptions import NotFoundError
|
||||
|
||||
svc = _svc(db)
|
||||
mailbox = await svc.get_mailbox(mailbox_id, current_user.tenant_id)
|
||||
|
||||
if mailbox.status == "deleted":
|
||||
raise NotFoundError("Casella non trovata o eliminata")
|
||||
|
||||
try:
|
||||
from arq.connections import RedisSettings, create_pool as arq_create_pool
|
||||
from app.config import get_settings
|
||||
|
||||
cfg = get_settings()
|
||||
arq_settings = RedisSettings.from_dsn(cfg.redis_url)
|
||||
arq_redis = await arq_create_pool(arq_settings)
|
||||
await arq_redis.enqueue_job("sync_mailbox", str(mailbox_id))
|
||||
await arq_redis.aclose()
|
||||
except Exception as exc:
|
||||
from app.core.logging import get_logger
|
||||
logger = get_logger(__name__)
|
||||
logger.error(f"[force_sync] Impossibile accodare job per {mailbox_id}: {exc}")
|
||||
return MailboxSyncResponse(
|
||||
status="error",
|
||||
mailbox_id=mailbox_id,
|
||||
message=f"Impossibile accodare il job: {exc}",
|
||||
)
|
||||
|
||||
return MailboxSyncResponse(
|
||||
status="enqueued",
|
||||
mailbox_id=mailbox_id,
|
||||
message=f"Sincronizzazione avviata per {mailbox.email_address}",
|
||||
)
|
||||
|
||||
@@ -116,3 +116,15 @@ class ConnectionTestResult(BaseModel):
|
||||
message: str
|
||||
latency_ms: float | None = None
|
||||
capabilities: list[str] | None = None # Solo per IMAP
|
||||
|
||||
|
||||
class MailboxSyncResponse(BaseModel):
|
||||
"""Risposta all'accodamento di un job di sincronizzazione manuale."""
|
||||
status: str
|
||||
mailbox_id: uuid.UUID
|
||||
message: str
|
||||
|
||||
|
||||
class MailboxUnreadCountsResponse(BaseModel):
|
||||
"""Conteggio messaggi non letti per casella."""
|
||||
counts: dict[str, int]
|
||||
|
||||
Reference in New Issue
Block a user