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_idproperty 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.