Add scoped postbox template previews

This commit is contained in:
2026-08-06 12:42:20 +02:00
parent c53646a8aa
commit d107c09f74
15 changed files with 1300 additions and 56 deletions
+60 -7
View File
@@ -1,5 +1,6 @@
from __future__ import annotations
from collections.abc import Mapping
from dataclasses import asdict
from typing import Literal
@@ -60,6 +61,8 @@ from govoplan_postbox.backend.schemas import (
PostboxTemplateCreateRequest,
PostboxTemplateItem,
PostboxTemplateListResponse,
PostboxTemplatePreviewRequest,
PostboxTemplatePreviewResponse,
PostboxTemplatePublishRequest,
PostboxTemplateReviseRequest,
)
@@ -252,6 +255,10 @@ def _template_item(template) -> PostboxTemplateItem:
"function_type_id": revision.function_type_id,
"scope_kind": revision.scope_kind,
"scope_id": revision.scope_id,
"scope_structure_id": revision.scope_structure_id,
"scope_relation_type_ids": list(
revision.scope_relation_type_ids or []
),
"name_pattern": revision.name_pattern,
"address_pattern": revision.address_pattern,
"classification": revision.classification,
@@ -271,18 +278,33 @@ def _template_item(template) -> PostboxTemplateItem:
)
def _grouping_item(grouping, *, visible_ids: set[str]) -> PostboxGroupingItem:
def _grouping_item(
grouping,
*,
visible_ids: set[str],
counts_by_postbox: Mapping[str, Mapping[str, int]] | None = None,
) -> PostboxGroupingItem:
visible_source_ids = [
source.postbox_id
for source in grouping.sources
if source.postbox_id in visible_ids
]
counts = counts_by_postbox or {}
return PostboxGroupingItem(
id=grouping.id,
name=grouping.name,
is_default=grouping.is_default,
resource_revision=grouping.resource_revision,
etag=grouping.strong_etag,
postbox_ids=[
source.postbox_id
for source in grouping.sources
if source.postbox_id in visible_ids
],
postbox_ids=visible_source_ids,
total_count=sum(
int(counts.get(postbox_id, {}).get("total", 0))
for postbox_id in visible_source_ids
),
unread_count=sum(
int(counts.get(postbox_id, {}).get("unread", 0))
for postbox_id in visible_source_ids
),
created_at=grouping.created_at,
updated_at=grouping.updated_at,
)
@@ -618,9 +640,19 @@ def api_list_postbox_groupings(
tenant_id=principal.tenant_id,
actor=actor,
)
counts_by_postbox = get_service().message_counts_by_postbox(
session,
tenant_id=principal.tenant_id,
postbox_ids=tuple(visible_ids),
actor=actor,
)
return PostboxGroupingListResponse(
groupings=[
_grouping_item(grouping, visible_ids=visible_ids)
_grouping_item(
grouping,
visible_ids=visible_ids,
counts_by_postbox=counts_by_postbox,
)
for grouping in groupings
]
)
@@ -881,6 +913,27 @@ def api_create_postbox_template(
return item
@router.post(
"/admin/templates/preview",
response_model=PostboxTemplatePreviewResponse,
)
def api_preview_postbox_template(
payload: PostboxTemplatePreviewRequest,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> PostboxTemplatePreviewResponse:
_require(principal, TEMPLATE_ADMIN_SCOPE)
try:
preview = get_service().preview_template_targets(
session,
tenant_id=principal.tenant_id,
**payload.model_dump(),
)
except PostboxError as exc:
raise _http_error(exc) from exc
return PostboxTemplatePreviewResponse.model_validate(preview)
@router.post(
"/admin/templates/{template_id}/revisions",
response_model=PostboxTemplateItem,