Skip to content

angee.knowledge.schema

Strawberry-Django schema contributions for the knowledge addon.

VaultType

python
@strawberry_django.type(Vault)
class VaultType(AngeeNode)

GraphQL projection of a vault.

owner

python
@strawberry_django.field(only=["owner_id"])
def owner() -> strawberry.ID | None

Return the owner's public id without exposing the user object.

owner_label

python
@strawberry_django.field(only=["owner_id"])
def owner_label(info: strawberry.Info) -> str | None

Return the owner's display label — no user object exposed.

OutlineEntryType

python
@strawberry.type
class OutlineEntryType()

One ATX heading in a page body's outline.

MarkdownPageType

python
@strawberry_django.type(MarkdownPage)
class MarkdownPageType(AngeeNode)

GraphQL projection of a page's markdown body sidecar.

page

python
@strawberry_django.field(only=["page_id"])
def page() -> strawberry.ID

Return the owning page's public id.

excerpt

python
@strawberry_django.field(only=["body"])
def excerpt() -> str

Return the leading body characters used for list previews.

outline

python
@strawberry_django.field(only=["body"])
def outline() -> list[OutlineEntryType]

Return the body's heading outline, derived like :attr:excerpt.

Parsed through the body's own structure owner (:meth:MarkdownPage.parse_outline) so the read field and the section-patch write share one markdown parser.

BacklinkType

python
@strawberry.type
class BacklinkType()

One resolved page that links to the page being viewed.

PageType

python
@strawberry_django.type(Page)
class PageType(AuthoredRefMixin, AngeeNode)

GraphQL projection of a page.

vault

python
@strawberry_django.field(only=["vault_id"])
def vault() -> strawberry.ID

Return the owning vault's public id without exposing the vault.

vault_label

python
@strawberry_django.field(only=["vault_id"])
def vault_label() -> str | None

Return the owning vault's display name — no vault object exposed.

Resolved under system_context so a page viewer who lacks vault read still sees where the page lives; only the name string leaves the resolver.

parent

python
@strawberry_django.field(only=["parent_id"])
def parent() -> strawberry.ID | None

Return the parent page's public id, if the page has one.

markdown

python
@strawberry_django.field(only=["id"])
def markdown() -> MarkdownPageType | None

Return the markdown body sidecar visible to the actor, if any.

python
@strawberry_django.field(only=["id"])
def backlinks() -> list[BacklinkType]

Return resolved pages linking here, scoped to readable sources.

The source title is annotated across the relation rather than select_related-ed: source_page is REBAC-guarded, so materializing it inside an actor-scoped resolver would fail.

PageBodyPayload

python
@strawberry.type
class PageBodyPayload()

Result of a markdown body write.

SectionOp

python
@strawberry.enum
class SectionOp(Enum)

How :meth:patch_page_section splices content into a section.

The member value is the op token the markdown owner (:meth:MarkdownPage.spliced_section) accepts; the upper-case member name is the wire enum value.

VaultWriteBackend

python
class VaultWriteBackend(AngeeHasuraWriteBackend)

Write semantics for vaults: create belongs to the manager factory.

create

python
def create(info: strawberry.Info, data: dict[str, Any]) -> Any

Create a vault owned by the requesting user.

PageWriteBackend

python
class PageWriteBackend(AngeeHasuraWriteBackend)

Write semantics for pages: create belongs to the manager factory.

create

python
def create(info: strawberry.Info, data: dict[str, Any]) -> Any

Create a page in a vault the requesting user can write.

MAX_SEARCH_PAGE_SIZE

Upper bound on :meth:KnowledgeQuery.search_pages first — every backend inherits it.

KnowledgeQuery

python
@strawberry.type
class KnowledgeQuery()

Knowledge content queries that span the page/body join.

search_pages

python
@strawberry.field
def search_pages(vault: PublicID,
                 query: str,
                 first: int = 20) -> list[PageType]

Return actor-visible pages in vault matching query.

The vault is both the search namespace and the selection point: this resolves it (gating the actor's read), then delegates to its bound :class:~angee.knowledge.retrieval.RetrievalBackend (default lexical), so a semantic plugin can swap the strategy without editing this resolver. Row scope is the backend's responsibility (apply_ambient_scope).

first is clamped here so every backend inherits the bound. The result is a materialized list, so a nested markdown/backlinks/vault_label selection runs a per-page resolver — a bounded N+1 accepted now that first is capped (a dataloader is the future optimization, not v1's concern).

KnowledgeMutation

python
@strawberry.type
class KnowledgeMutation()

Markdown body writes that belong to the Knowledge domain.

delete_vault

python
@strawberry.mutation(name="delete_vault")
def delete_vault(id: PublicID, confirm: bool = False) -> DeletePreview

Return or apply the authored vault cascade delete preview.

delete_page

python
@strawberry.mutation(name="delete_page")
def delete_page(id: PublicID, confirm: bool = False) -> DeletePreview

Return or apply the authored page cascade delete preview.

update_page_body

python
@strawberry.mutation(name="update_page_body")
def update_page_body(
    page: PublicID,
    body: str,
    expected_hash: Annotated[
        str | None,
        strawberry.argument(name="expected_hash"),
    ] = None
) -> PageBodyPayload

Write a page's markdown body, last-write-wins with a stale guard.

patch_page_section

python
@strawberry.mutation(name="patch_page_section")
def patch_page_section(
    page: PublicID,
    heading_path: list[str],
    op: SectionOp,
    content: str,
    expected_hash: Annotated[
        str | None,
        strawberry.argument(name="expected_hash"),
    ] = None
) -> PageBodyPayload

Replace/append/prepend the section at heading_path in a page body.

Mirrors :meth:update_page_body: same PublicID resolution, same :class:PageBodyPayload, same CAS via expected_hash; the splice is a fail-fast structured edit (SECTION_NOT_FOUND/AMBIGUOUS_MATCH).

replace_page_text

python
@strawberry.mutation(name="replace_page_text")
def replace_page_text(
    page: PublicID,
    old: str,
    new: str,
    expected_hash: Annotated[
        str | None,
        strawberry.argument(name="expected_hash"),
    ] = None
) -> PageBodyPayload

Replace the single occurrence of old with new in a page body.

Mirrors :meth:update_page_body; uniqueness is enforced by the markdown owner, so a non-unique or absent target fails fast with AMBIGUOUS_MATCH/SECTION_NOT_FOUND before any write.

append_to_page

python
@strawberry.mutation(name="append_to_page")
def append_to_page(
    page: PublicID,
    content: str,
    expected_hash: Annotated[
        str | None,
        strawberry.argument(name="expected_hash"),
    ] = None
) -> PageBodyPayload

Append content to the end of a page body.

Mirrors :meth:update_page_body: same PublicID resolution, same :class:PageBodyPayload, same CAS via expected_hash; the markdown owner joins content one blank line after the body (no markdown re-rendered), so the section seam stays consistent.

Released under the AGPL-3.0 License.