Release govoplan-docs v0.1.23: unify help discovery and batch semantic reads
Module Package Release / publish-packages (push) Successful in 12s

This commit is contained in:
2026-09-08 01:32:36 +02:00
parent 1ae23b4e9d
commit cbe434de02
18 changed files with 842 additions and 81 deletions
+47 -14
View File
@@ -3,7 +3,7 @@ from __future__ import annotations
from collections.abc import Mapping, Sequence
from urllib.parse import quote
from sqlalchemy import func, select
from sqlalchemy import and_, func, select
from sqlalchemy.orm import Session
from govoplan_core.auth import ApiPrincipal
@@ -23,7 +23,11 @@ from govoplan_docs.backend.db.models import (
SemanticDocumentationEntry,
SemanticDocumentationRevision,
)
from govoplan_docs.backend.semantic_service import semantic_entry_payload
from govoplan_docs.backend.semantic_service import (
prefetch_semantic_revisions,
published_revision,
semantic_entry_payload,
)
PROVIDER_ID = "docs.semantic_documentation"
@@ -58,8 +62,12 @@ class SemanticDocumentationSearchSource:
select(SemanticDocumentationEntry, SemanticDocumentationRevision)
.join(
SemanticDocumentationRevision,
SemanticDocumentationRevision.id
== SemanticDocumentationEntry.published_revision_id,
and_(
SemanticDocumentationRevision.id == SemanticDocumentationEntry.published_revision_id,
SemanticDocumentationRevision.entry_id == SemanticDocumentationEntry.id,
SemanticDocumentationRevision.tenant_id == SemanticDocumentationEntry.tenant_id,
SemanticDocumentationRevision.lifecycle_state == "published",
),
)
.where(
SemanticDocumentationEntry.tenant_id == request.tenant_id,
@@ -105,15 +113,32 @@ class SemanticDocumentationSearchSource:
if not isinstance(principal, ApiPrincipal) or not principal.has(DOCS_READ_SCOPE):
return decisions
db = _session(session)
for item in requests:
reference = item.reference
valid_requests = [
item
for item in requests
if (
reference.tenant_id != principal.tenant_id
or reference.module_id != "docs"
or reference.resource_type != RESOURCE_TYPE
):
continue
entry = db.get(SemanticDocumentationEntry, reference.resource_id)
item.reference.tenant_id == principal.tenant_id
and item.reference.module_id == "docs"
and item.reference.resource_type == RESOURCE_TYPE
)
]
ids = sorted({item.reference.resource_id for item in valid_requests})
entries: dict[str, SemanticDocumentationEntry] = {}
for offset in range(0, len(ids), 400):
rows = db.scalars(
select(SemanticDocumentationEntry).where(
SemanticDocumentationEntry.id.in_(ids[offset:offset + 400]),
SemanticDocumentationEntry.tenant_id == principal.tenant_id,
SemanticDocumentationEntry.lifecycle_state.in_(("draft", "published")),
)
)
entries.update((entry.id, entry) for entry in rows)
revisions = prefetch_semantic_revisions(
db, principal, entries=tuple(entries.values()), editor=False,
)
for item in valid_requests:
reference = item.reference
entry = entries.get(reference.resource_id)
if (
entry is None
or entry.tenant_id != principal.tenant_id
@@ -127,6 +152,7 @@ class SemanticDocumentationSearchSource:
principal,
entry=entry,
editor=False,
revisions=revisions,
)
decisions[reference.key] = bool(
payload
@@ -153,8 +179,12 @@ class SemanticDocumentationSearchSource:
db = _session(session)
entry = db.get(SemanticDocumentationEntry, event.resource.id)
revision = (
db.get(SemanticDocumentationRevision, entry.published_revision_id)
if entry is not None and entry.published_revision_id
published_revision(db, entry)
if (
entry is not None
and entry.tenant_id == event.tenant.id
and entry.lifecycle_state in {"draft", "published"}
)
else None
)
visible = bool(
@@ -162,6 +192,9 @@ class SemanticDocumentationSearchSource:
and entry.tenant_id == event.tenant.id
and entry.lifecycle_state in {"draft", "published"}
and revision is not None
and revision.entry_id == entry.id
and revision.tenant_id == entry.tenant_id
and revision.lifecycle_state == "published"
)
cursor = event.event_id
document = _document(entry, revision, change_cursor=cursor) if visible else None