Skip to content

Deletion API

scinr.newton.ingest.deletion.delete_document async

delete_document(
    path: str | None = None,
    version: int | None = None,
    *,
    tenant_id: str | None = None,
    created_by_user_id: str | None = None,
    job_id: str | None = None,
) -> DeletionResult

Completely delete Document node(s), their entire cascade, and orphans.

Unlike delete_document_content() (which only wipes content for in-place re-ingestion and keeps the :Document node), this permanently removes every :Document node matching the selector below along with:

  • Every descendant reached via IS_COMPOSED_OF* (folder-parent Document nodes, sibling documents, etc.).
  • All :StructureNode descendants (HAS_STRUCTURE / HAS_CHILD), their :InfoUnit, :ModelDecision, :ProposedModel, :ProposedField, and :ExtractionResult children.

Target selection

Exactly one of path or job_id must be provided (ValueError otherwise):

  • path: delete the Document at that path (all versions, or only version when given).
  • job_id: delete every Document whose job_id property equals this value — across all paths and versions of that ingestion run.

tenant_id and created_by_user_id, when given, are additional AND filters applied on top of either selector. A filter left as None means "do not filter on this property" (it does not mean "the property must be null"). version is also accepted as an extra filter in job_id mode.

Before any Neo4j deletion happens, this also deletes the documental storage records (raw binary + converted Markdown pages) for every non-empty raw_file_id found on the target Document(s) and their IS_COMPOSED_OF* descendants, via the configured storage backend (storage/factory.py::get_storage()). This step is fail-fast: if deleting storage for any raw_file_id raises an unexpected exception, it propagates immediately and the Neo4j cascade delete is never run.

After the cascade delete, runs two independent garbage-collection passes (up to :data:GC_MAX_PASSES iterations each) to remove any :Entity/:ModelInstance and :LabeledEntity nodes left orphaned by the deletion.

Opens and closes its own Neo4j driver — does not require the caller to manage one. The Neo4j-specific work (existence check, raw_file_id lookup, cascade delete, GC passes) uses the existing synchronous Neo4j driver under the hood, dispatched via asyncio.to_thread(); the storage deletion calls are awaited directly since storage repositories (Motor-backed) are natively async.

Returns

DeletionResult Structured counts of everything deleted. If no Document matches the selector, found is False and all counters are 0 (no storage, delete, or GC queries are executed in that case).

Raises

ValueError If neither or both of path and job_id are provided.