luplo.core.qa

QA check domain — a thin wrapper around items where item_type='qa_check'.

Tasks/items get verified by qa_checks. State changes initiated by users (start/pass/fail/block/skip/assign) are supersede operations; the revalidation trigger that demotes passedpending after a target item gets superseded is in-place + audit (P8) and lives in LocalBackend.create_item — not here.

Targets are stored as context.target_item_ids and context.target_task_ids arrays. GIN indexes from migration 0003 make reverse lookups fast.

Attributes

Functions

create_qa(→ luplo.core.models.Item)

Create a new qa_check in pending status.

get_qa(→ luplo.core.models.Item | None)

Fetch the head of the chain containing qa_id.

list_qa(→ list[luplo.core.models.Item])

List qa_check heads in project_id, optionally filtered.

list_pending_for_task(→ list[luplo.core.models.Item])

qa_checks targeting task_id that are not yet passed (GIN-hit).

list_pending_for_item(→ list[luplo.core.models.Item])

qa_checks targeting item_id that are not yet passed (GIN-hit).

list_pending_for_wu(→ list[luplo.core.models.Item])

All pending qa_checks attached to work_unit_id.

start_qa(→ luplo.core.models.Item)

pass_qa(→ luplo.core.models.Item)

fail_qa(→ luplo.core.models.Item)

block_qa(→ luplo.core.models.Item)

skip_qa(→ luplo.core.models.Item)

assign_qa(→ luplo.core.models.Item)

Assign a qa_check to assignee_actor_id. actor_id ≠ assignee

Module Contents

luplo.core.qa.ITEM_TYPE = 'qa_check'
async luplo.core.qa.create_qa(conn: psycopg.AsyncConnection[Any], *, project_id: str, title: str, actor_id: str, coverage: str, areas: list[str] | None = None, target_item_ids: list[str] | None = None, target_task_ids: list[str] | None = None, work_unit_id: str | None = None, body: str | None = None, context_extra: dict[str, Any] | None = None) luplo.core.models.Item

Create a new qa_check in pending status.

coverage must be one of auto_partial / human_only.

async luplo.core.qa.get_qa(conn: psycopg.AsyncConnection[Any], qa_id: str, *, project_id: str | None = None) luplo.core.models.Item | None

Fetch the head of the chain containing qa_id.

Accepts a full UUID or hex prefix (≥8 chars). Returns None if nothing matches; raises AmbiguousIdError if a prefix resolves to multiple distinct chains.

async luplo.core.qa.list_qa(conn: psycopg.AsyncConnection[Any], project_id: str, *, status: str | None = None, work_unit_id: str | None = None) list[luplo.core.models.Item]

List qa_check heads in project_id, optionally filtered.

async luplo.core.qa.list_pending_for_task(conn: psycopg.AsyncConnection[Any], task_id: str) list[luplo.core.models.Item]

qa_checks targeting task_id that are not yet passed (GIN-hit).

async luplo.core.qa.list_pending_for_item(conn: psycopg.AsyncConnection[Any], item_id: str) list[luplo.core.models.Item]

qa_checks targeting item_id that are not yet passed (GIN-hit).

async luplo.core.qa.list_pending_for_wu(conn: psycopg.AsyncConnection[Any], work_unit_id: str) list[luplo.core.models.Item]

All pending qa_checks attached to work_unit_id.

async luplo.core.qa.start_qa(conn: psycopg.AsyncConnection[Any], qa_id: str, *, actor_id: str, project_id: str | None = None) luplo.core.models.Item
async luplo.core.qa.pass_qa(conn: psycopg.AsyncConnection[Any], qa_id: str, *, actor_id: str, evidence: str | None = None, project_id: str | None = None) luplo.core.models.Item
async luplo.core.qa.fail_qa(conn: psycopg.AsyncConnection[Any], qa_id: str, *, actor_id: str, reason: str, project_id: str | None = None) luplo.core.models.Item
async luplo.core.qa.block_qa(conn: psycopg.AsyncConnection[Any], qa_id: str, *, actor_id: str, reason: str, project_id: str | None = None) luplo.core.models.Item
async luplo.core.qa.skip_qa(conn: psycopg.AsyncConnection[Any], qa_id: str, *, actor_id: str, project_id: str | None = None) luplo.core.models.Item
async luplo.core.qa.assign_qa(conn: psycopg.AsyncConnection[Any], qa_id: str, *, actor_id: str, assignee_actor_id: str, project_id: str | None = None) luplo.core.models.Item

Assign a qa_check to assignee_actor_id. actor_id ≠ assignee by design (the actor performing the assignment is rarely the assignee).