Release govoplan-docs v0.1.23: unify help discovery and batch semantic reads
Module Package Release / publish-packages (push) Successful in 12s
Module Package Release / publish-packages (push) Successful in 12s
This commit is contained in:
@@ -396,13 +396,21 @@ def semantic_entry_history(
|
||||
def current_revision(
|
||||
session: Session,
|
||||
entry: SemanticDocumentationEntry,
|
||||
*,
|
||||
revisions: Mapping[str, SemanticDocumentationRevision] | None = None,
|
||||
) -> SemanticDocumentationRevision:
|
||||
revision = (
|
||||
session.get(SemanticDocumentationRevision, entry.current_revision_id)
|
||||
if entry.current_revision_id
|
||||
else None
|
||||
)
|
||||
if revision is None or revision.entry_id != entry.id:
|
||||
revision = None
|
||||
if entry.current_revision_id:
|
||||
revision = (
|
||||
revisions.get(entry.current_revision_id)
|
||||
if revisions is not None
|
||||
else session.get(SemanticDocumentationRevision, entry.current_revision_id)
|
||||
)
|
||||
if (
|
||||
revision is None
|
||||
or revision.entry_id != entry.id
|
||||
or revision.tenant_id != entry.tenant_id
|
||||
):
|
||||
raise SemanticDocumentationError(
|
||||
"Semantic documentation current revision is unavailable."
|
||||
)
|
||||
@@ -412,14 +420,60 @@ def current_revision(
|
||||
def published_revision(
|
||||
session: Session,
|
||||
entry: SemanticDocumentationEntry,
|
||||
*,
|
||||
revisions: Mapping[str, SemanticDocumentationRevision] | None = None,
|
||||
) -> SemanticDocumentationRevision | None:
|
||||
if not entry.published_revision_id:
|
||||
return None
|
||||
revision = session.get(
|
||||
SemanticDocumentationRevision,
|
||||
entry.published_revision_id,
|
||||
revision = (
|
||||
revisions.get(entry.published_revision_id)
|
||||
if revisions is not None
|
||||
else session.get(SemanticDocumentationRevision, entry.published_revision_id)
|
||||
)
|
||||
return revision if revision is not None and revision.entry_id == entry.id else None
|
||||
if (
|
||||
revision is None
|
||||
or revision.entry_id != entry.id
|
||||
or revision.tenant_id != entry.tenant_id
|
||||
or revision.lifecycle_state != "published"
|
||||
):
|
||||
return None
|
||||
return revision
|
||||
|
||||
|
||||
def prefetch_semantic_revisions(
|
||||
session: Session,
|
||||
principal: object,
|
||||
*,
|
||||
entries: Sequence[SemanticDocumentationEntry],
|
||||
editor: bool,
|
||||
) -> dict[str, SemanticDocumentationRevision]:
|
||||
"""Load only the revisions this request may project, in bounded SQL batches.
|
||||
|
||||
This is request-local data loading, never an authorization cache. Payload
|
||||
projection still validates each entry/revision pair and its owner subject.
|
||||
Readers have no reason to load the bodies of pending unpublished drafts.
|
||||
"""
|
||||
tenant_id = _principal_tenant_id(principal)
|
||||
revision_ids = sorted({
|
||||
revision_id
|
||||
for entry in entries
|
||||
if entry.tenant_id == tenant_id
|
||||
for revision_id in (
|
||||
entry.published_revision_id,
|
||||
entry.current_revision_id if editor else None,
|
||||
)
|
||||
if revision_id
|
||||
})
|
||||
revisions: dict[str, SemanticDocumentationRevision] = {}
|
||||
for offset in range(0, len(revision_ids), 400):
|
||||
rows = session.query(SemanticDocumentationRevision).filter(
|
||||
SemanticDocumentationRevision.tenant_id == tenant_id,
|
||||
SemanticDocumentationRevision.id.in_(revision_ids[offset:offset + 400]),
|
||||
)
|
||||
if not editor:
|
||||
rows = rows.filter(SemanticDocumentationRevision.lifecycle_state == "published")
|
||||
revisions.update((revision.id, revision) for revision in rows)
|
||||
return revisions
|
||||
|
||||
|
||||
def entry_subject_reference(
|
||||
@@ -487,12 +541,16 @@ def semantic_entry_payload(
|
||||
entry: SemanticDocumentationEntry,
|
||||
editor: bool,
|
||||
requested_locale: str | None = None,
|
||||
revisions: Mapping[str, SemanticDocumentationRevision] | None = None,
|
||||
) -> dict[str, object] | None:
|
||||
current = current_revision(session, entry)
|
||||
published = published_revision(session, entry)
|
||||
selected = current if editor else published
|
||||
if entry.tenant_id != _principal_tenant_id(principal):
|
||||
return None
|
||||
published = published_revision(session, entry, revisions=revisions)
|
||||
selected = current_revision(session, entry, revisions=revisions) if editor else published
|
||||
if selected is None:
|
||||
return None
|
||||
if not content_visible_to_principal(selected.content, principal):
|
||||
return None
|
||||
resolution = resolve_entry_subject(
|
||||
session,
|
||||
registry,
|
||||
@@ -505,8 +563,6 @@ def semantic_entry_payload(
|
||||
unavailable = resolution.availability == "temporarily_unavailable"
|
||||
if unavailable and not editor:
|
||||
return None
|
||||
if not content_visible_to_principal(selected.content, principal):
|
||||
return None
|
||||
subject = resolution.subject
|
||||
required_scopes = subject.required_scopes if subject is not None else ()
|
||||
if any(not _principal_has(principal, scope) for scope in required_scopes):
|
||||
@@ -523,7 +579,7 @@ def semantic_entry_payload(
|
||||
"lifecycle_state": entry.lifecycle_state,
|
||||
"effective_state": selected.lifecycle_state,
|
||||
"pending_draft": bool(
|
||||
published is not None and current.id != published.id
|
||||
published is not None and entry.current_revision_id != published.id
|
||||
),
|
||||
"current_revision": entry.current_revision,
|
||||
"selected_revision": selected.revision,
|
||||
@@ -965,6 +1021,7 @@ __all__ = [
|
||||
"entry_subject_reference",
|
||||
"get_semantic_entry",
|
||||
"list_semantic_entries",
|
||||
"prefetch_semantic_revisions",
|
||||
"publication_policy",
|
||||
"publish_semantic_entry",
|
||||
"published_revision",
|
||||
|
||||
Reference in New Issue
Block a user