app.services.approval_view¶
Approval part of the record detail page (read-only).
Builds ApprovalSummary for one record from its identity
siblings and decision events: the state of the current digest
(app.domain.approval.evaluate()), the full decision history of
the identity (each event marked current_digest), divergence
between published and accepted/candidate content, competing
candidates, and whether the caller may decide now
(app.services.decisions.decision_blocker(), the same rules as the
decision endpoint).
Divergence (divergence, at most one):
published_not_accepted– the record is published, its current digest is not accepted, and another digest of the identity was accepted (typically an accepted candidate whose content differs from what was published).other_record_idslists the rows currently holding that accepted digest (may be empty when no row holds it any more).published_differs– the record is a candidate and the identity’s published row holds different content.
Public API: PolicySummary, DecisionProvenance,
DecisionSummary, DivergenceKind,
DivergenceInfo, CompetingCandidate,
ApprovalSummary, is_approvable(),
decision_summary(), build_approval().
- class app.services.approval_view.ApprovalSummary(*, state, needs_approval, digest, policy, history, approvable, approval_blocker, last_accepted_digest, can_decide, decide_blocked_code, decide_blocked_reason, divergence, competing_candidates)¶
Bases:
objectApproval state of a record’s current content.
- Parameters:
state (
ApprovalStateCode) – The state code.needs_approval (
bool) – Whether the record is in “Needs approval”.digest (
str) – The current digest the state applies to.policy (
PolicySummary) – The applicable policy summary.history (
tuple[DecisionSummary,...]) – All decisions of this identity, oldest first.approvable (
bool) – Whether the content can be decided at all.approval_blocker (
str|None) – Why not, when not approvable.last_accepted_digest (
str|None) – Latest accepted other digest, set forchanged_since_acceptance.can_decide (
bool) – Whether the caller may decide now.decide_blocked_code (
str|None) – Stable code when the caller cannot.decide_blocked_reason (
str|None) – Reader-facing reason when not.divergence (
DivergenceInfo|None) – Published/accepted divergence, if any.competing_candidates (
tuple[CompetingCandidate,...]) – Other candidates of the identity with different content.
- state: ApprovalStateCode¶
- policy: PolicySummary¶
- history: tuple[DecisionSummary, ...]¶
- divergence: DivergenceInfo | None¶
- competing_candidates: tuple[CompetingCandidate, ...]¶
- class app.services.approval_view.CompetingCandidate(*, id, ref, path, digest, approval_state, approvable)¶
Bases:
objectAnother candidate of the identity with different content.
- Parameters:
- approval_state: ApprovalStateCode¶
- class app.services.approval_view.DecisionProvenance(*, record_id, kind, source_id, project, ref, path, source_url)¶
Bases:
objectThe decided row as it was at decision time.
- Parameters:
- class app.services.approval_view.DecisionSummary(*, id, digest, current_digest, action, actor_issuer, actor_subject, actor_display, comment, policy_id, policy_version, provenance, created_at)¶
Bases:
objectOne append-only decision event of the identity.
The reviewer’s email is not exposed to readers.
- Parameters:
id (
UUID) – Stable event id.digest (
str) – Digest the decision applies to.current_digest (
bool) – Whether digest is the viewed record’s current digest.action (
DecisionAction) – Accepted or rejected.actor_issuer (
str) – Reviewer token issuer.actor_subject (
str) – Reviewer token subject.actor_display (
str|None) – Reviewer display name, if known.policy_id (
str) – Applied policy id.policy_version (
int) – Applied policy version.provenance (
DecisionProvenance) – The decided row at decision time.created_at (
datetime) – Server timestamp of the decision.
- action: DecisionAction¶
- provenance: DecisionProvenance¶
- class app.services.approval_view.DivergenceInfo(*, kind, other_digest, other_record_ids, other_accepted, message)¶
Bases:
objectContent divergence within the identity.
- Parameters:
kind (
DivergenceKind) – Which divergence.other_digest (
str) – The accepted (or published) digest that differs from the current one.other_record_ids (
tuple[UUID,...]) – Rows currently holding other_digest.other_accepted (
bool) – Whether other_digest is accepted.message (
str) – Reader-facing explanation.
- kind: DivergenceKind¶
- class app.services.approval_view.DivergenceKind(*values)¶
Bases:
StrEnumKinds of published/accepted divergence (module docstring).
- PUBLISHED_NOT_ACCEPTED = 'published_not_accepted'¶
- PUBLISHED_DIFFERS = 'published_differs'¶
- class app.services.approval_view.PolicySummary(*, status, id, version, required, allow_self_approval)¶
Bases:
objectThe applicable approval policy, or why there is none.
- Parameters:
status (
PolicyStatus) – Configured, missing or invalid.required (
bool|None) – Whether approval is required, when configured.allow_self_approval (
bool|None) – Whether authors may decide their own content, when configured.
- status: PolicyStatus¶
- app.services.approval_view.build_approval(*, record, siblings, events, policy, policy_status, reviewer)¶
Build the approval summary of one record for one caller.
- Parameters:
record (
StoredRecord) – The viewed record.siblings (
Sequence[StoredRecord]) – Every row of its identity (including itself).events (
Sequence[DecisionEvent]) – Every decision event of its identity.policy_status (
PolicyStatus) – Configuration status of the policy.reviewer (
Reviewer|None) – The caller, orNone(then nobody can decide).
- Return type:
- Returns:
The summary.
- app.services.approval_view.decision_summary(event, current_digest)¶
Convert a stored event for the API.
- Parameters:
event (
DecisionEvent) – The stored event.current_digest (
str) – Digest of the viewed record.
- Return type:
- Returns:
The summary.
- app.services.approval_view.is_approvable(record)¶
Tell whether a stored row’s content may be decided at all.
- Parameters:
record (
Approvable) – The row.- Return type:
- Returns:
Truewithout identity or encoding errors.