Approval-decision business logic for AUTO-003b.
Extracted from routes/tests.js so the route handlers stay thin
(HTTP shape only) and the provenance contract has a single home.
Three provenance shapes flow through this module:
PROVENANCE_CLEAR — null-out the four columns; written by every "return to draft" path (single restore, bulk restore, revoke). Previously duplicated in three handlers, where the single-restore copy went stale and shipped as a bug.
humanApproval() — provenance for a manual approve click. Carries
approvalSource: "human", approvedBy from
the actor, approvedAt from Date.now(),
and a null approvalThreshold (no threshold
was consulted).
computeStats() — counts (human/auto/draft/rejected) plus the
7-day revert rate, computed off the activity
log because the tests row only carries
current state and revoked tests have their
provenance cleared.
- Source:
Members
(static, constant) APPROVAL_SOURCE
tests.approvalSource enumeration.
- Source:
(static, constant) PROVENANCE_CLEAR
Provenance-clearing shape — pass to testRepo.update(...) together with
{ reviewStatus: "draft", reviewedAt: null } to fully revert an approval.
Frozen so a caller can't accidentally mutate it (the same object is reused across every restore/revoke path; mutation would leak between requests).
- Source:
Methods
(static) computeStats(projectId) → {Object}
Compute approval-decision counts and the 7-day revert rate for a project.
Counts are derived from the live tests table. The revert rate is derived
from the activity log because revoked tests have their provenance cleared
— only the audit trail can answer "was this auto-approval pulled back?".
The revert rate is deduped by testId so a test that round-trips
auto-approve → revoke → re-approve → revoke within the 7-day window counts
as a single revert (and a single auto-approval). The metric answers "what
fraction of auto-approved tests did humans pull back?", not "how many
revoke events fired?".
Defensive clamp: ratio capped at 1 so a backfill that produced more revokes than auto-approvals in the window can't render "117% revert rate".
Parameters:
| Name | Type | Description |
|---|---|---|
projectId |
string |
- Source:
Returns:
{ human, auto, draft, rejected, total, revertRate7d, autoApprovals7d, reverts7d } — all number.
- Type
- Object
(static) humanApproval(actorInfo) → {Object}
Build the provenance fields for a human approval, attributed to actorInfo.
The threshold is always null for human approvals (no threshold was consulted).
Parameters:
| Name | Type | Description | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
actorInfo |
Object | — caller identity from Properties
|
- Source:
Returns:
{ approvalSource, approvalThreshold, approvedAt, approvedBy }.
- Type
- Object