feat: add governed assisted form intake

This commit is contained in:
2026-08-19 02:45:53 +02:00
parent eea3db3d2e
commit d83bb92ec8
18 changed files with 1895 additions and 39 deletions
+64 -1
View File
@@ -34,10 +34,13 @@ from govoplan_core.core.institutional import (
ServiceLaunchResult,
)
from govoplan_forms_runtime.backend.db.models import (
FormAssistedConfirmation,
FormInstanceEvent,
FormInstanceIdentity,
FormInstanceRevision,
FormIntakeSession,
)
from govoplan_forms_runtime.backend.assisted import assisted_submission_payload_sha256
from govoplan_forms_runtime.backend.domain import FormInstance
from govoplan_forms_runtime.backend.evidence import FormEvidenceCoordinator
@@ -329,7 +332,7 @@ class FormRuntimeService:
action="submit",
instance=current,
)
return self._revise(
submitted = self._revise(
session,
principal,
current=current,
@@ -348,6 +351,21 @@ class FormRuntimeService:
definition=definition,
allowed_current_statuses=("started", "draft"),
)
assisted_session = (
session.query(FormIntakeSession)
.filter(
FormIntakeSession.tenant_id == submitted.tenant_id,
FormIntakeSession.instance_id == submitted.instance_id,
FormIntakeSession.mode == "assisted",
)
.one_or_none()
)
if assisted_session is not None and assisted_session.status != "submitted":
assisted_session.status = "submitted"
assisted_session.submitted_at = recorded_at
session.add(assisted_session)
session.flush()
return submitted
def transition_instance(
self,
@@ -821,6 +839,46 @@ class FormRuntimeService:
)
if replay is not None:
return replay
if operation == "submitted" and _is_assisted_instance(current):
assisted_session = (
session.query(FormIntakeSession)
.filter(
FormIntakeSession.tenant_id == current.tenant_id,
FormIntakeSession.instance_id == current.instance_id,
FormIntakeSession.mode == "assisted",
)
.one_or_none()
)
if (
assisted_session is None
or assisted_session.status != "active"
or _aware(assisted_session.expires_at) <= recorded_at
):
raise FormRuntimeError(
"Assisted intake submission requires an active, unexpired session."
)
expected_confirmation_digest = assisted_submission_payload_sha256(
current,
values=clean_values,
attachment_refs=attachments,
signature_refs=signatures,
)
confirmation = (
session.query(FormAssistedConfirmation)
.filter(
FormAssistedConfirmation.tenant_id == current.tenant_id,
FormAssistedConfirmation.instance_id == current.instance_id,
FormAssistedConfirmation.instance_revision == current.revision,
FormAssistedConfirmation.payload_sha256
== expected_confirmation_digest,
)
.order_by(FormAssistedConfirmation.confirmed_at.desc())
.first()
)
if confirmation is None:
raise FormRuntimeError(
"Assisted intake submission requires a current read-back confirmation for the exact values and evidence."
)
if allowed_current_statuses is not None and current.status not in set(
allowed_current_statuses
):
@@ -1123,6 +1181,11 @@ def validate_form_values(
return tuple(diagnostics)
def _is_assisted_instance(instance: FormInstance) -> bool:
intake = instance.metadata.get("intake")
return isinstance(intake, Mapping) and intake.get("mode") == "assisted"
def normalize_form_values(
definition: FormDefinition,
values: Mapping[str, object],