feat: enforce shared UI foundations and pin reference journey
Dependency Audit / dependency-audit (push) Successful in 1m57s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Successful in 12m24s

This commit is contained in:
2026-08-18 21:32:25 +02:00
parent a1b80eda27
commit e2f505eeab
11 changed files with 445 additions and 64 deletions
+39 -29
View File
@@ -2,6 +2,8 @@ from __future__ import annotations
from dataclasses import dataclass, replace
from datetime import UTC, datetime, timedelta
import json
from pathlib import Path
import unittest
from sqlalchemy import create_engine
@@ -66,6 +68,11 @@ from govoplan_services.backend.service import SqlServiceDefinitionProvider, reco
NOW = datetime(2026, 8, 1, 10, 0, tzinfo=UTC)
JOURNEY = json.loads(
(Path(__file__).parent / "fixtures/resident_parking_permit_journey.json").read_text(
encoding="utf-8"
)
)
def _reference(
@@ -177,31 +184,31 @@ class InstitutionalGovernanceJourneyTests(unittest.TestCase):
service = ServiceDefinition(
reference=_reference(
"service",
"permit-service",
JOURNEY["service"]["object_id"],
owner="services",
version="5",
version=JOURNEY["service"]["version"],
),
key="permit.apply",
key=JOURNEY["service"]["key"],
temporal=TemporalRevision(
revision="5",
revision=JOURNEY["service"]["version"],
valid_from=NOW - timedelta(days=1),
valid_to=NOW + timedelta(days=30),
recorded_at=NOW - timedelta(days=2),
change_reason="Service published.",
),
title="Apply for a permit",
title=JOURNEY["title"],
audience=("resident",),
legal_bases=(legal_basis,),
required_evidence_types=("application", "identity"),
channels=("portal", "postbox"),
required_evidence_types=tuple(JOURNEY["service"]["required_evidence_types"]),
channels=tuple(JOURNEY["service"]["channels"]) + ("postbox",),
responsible_organization_ref=organization,
responsible_function_ref=function,
mandate_ref=mandate_ref,
jurisdiction_refs=(jurisdiction,),
bindings=(
ServiceBinding("case", "permit-application"),
ServiceBinding("workflow", "workflow:permit-review"),
ServiceBinding("result", "decision:permit"),
ServiceBinding("case", JOURNEY["case"]["type_key"]),
ServiceBinding("workflow", "workflow:resident-parking-permit-review"),
ServiceBinding("result", f"decision:{JOURNEY['decision']['type']}"),
),
remedy_refs=("review:administrative-court",),
publication_state="published",
@@ -230,37 +237,40 @@ class InstitutionalGovernanceJourneyTests(unittest.TestCase):
upsert_case_status(
session,
principal,
status_key="intake",
status_key=JOURNEY["case"]["initial_status"],
label="Intake",
)
upsert_case_status(
session,
principal,
status_key="decided",
status_key=JOURNEY["case"]["decided_status"],
label="Decided",
category="decided",
)
upsert_case_type(
session,
principal,
type_key="permit-application",
label="Permit application",
initial_status_key="intake",
allowed_status_keys=("intake", "decided"),
type_key=JOURNEY["case"]["type_key"],
label=JOURNEY["title"],
initial_status_key=JOURNEY["case"]["initial_status"],
allowed_status_keys=(
JOURNEY["case"]["initial_status"],
JOURNEY["case"]["decided_status"],
),
)
case_record = create_case_from_intake(
session,
principal,
plan=intake,
case_number="PERMIT-2026-0001",
title="Permit application",
status_key=None,
case_number=JOURNEY["case"]["number"],
title=JOURNEY["title"],
status_key=JOURNEY["case"]["initial_status"],
opened_at=NOW,
recorded_at=NOW,
change_reason="Portal application received.",
idempotency_key="journey-case-create",
evidence_refs=(application_evidence,),
deadline_at=NOW + timedelta(days=30),
deadline_at=NOW + timedelta(days=JOURNEY["case"]["deadline_days"]),
)
applicant = _reference("party", "applicant", owner="parties")
@@ -333,7 +343,7 @@ class InstitutionalGovernanceJourneyTests(unittest.TestCase):
change_reason="Permit authority delegated.",
),
task_types=("committee.formal_decision",),
authority_types=("permit",),
authority_types=(JOURNEY["decision"]["type"],),
organization_unit_refs=(organization,),
function_refs=(function,),
jurisdiction_refs=(jurisdiction,),
@@ -380,7 +390,7 @@ class InstitutionalGovernanceJourneyTests(unittest.TestCase):
object_id="item-1",
revision=1,
state="deliberating",
title="Permit application",
title=JOURNEY["title"],
parent_id=meeting.object_id,
recorded_at=NOW,
change_reason="Agenda item entered deliberation.",
@@ -398,7 +408,7 @@ class InstitutionalGovernanceJourneyTests(unittest.TestCase):
object_id="vote-1",
revision=1,
state="closed",
title="Vote on permit application",
title=f"Vote on {JOURNEY['title'].lower()}",
parent_id=agenda.object_id,
recorded_at=NOW,
change_reason="Vote result accepted.",
@@ -445,7 +455,7 @@ class InstitutionalGovernanceJourneyTests(unittest.TestCase):
effective_at=NOW,
meeting_ref="meeting-1",
agenda_item_ref="item-1",
decision_type="permit",
decision_type=JOURNEY["decision"]["type"],
subject_refs=(case_record.reference,),
organization_unit_ref=organization,
function_ref=function,
@@ -461,8 +471,8 @@ class InstitutionalGovernanceJourneyTests(unittest.TestCase):
),
fact_evidence=(application_evidence, address_evidence),
legal_bases=(legal_basis,),
operative_result="Permit granted.",
reasoning="The application satisfies the effective rule.",
operative_result=JOURNEY["decision"]["operative_result"],
reasoning=JOURNEY["decision"]["reasoning"],
case_ref=case_record.reference,
jurisdiction_refs=(jurisdiction,),
party_refs=(applicant, representative),
@@ -475,7 +485,7 @@ class InstitutionalGovernanceJourneyTests(unittest.TestCase):
classification="restricted",
purposes=("permit-decision", "party-delivery"),
legal_basis_refs=("permit-law:3@2026-01",),
retention_policy_ref="records:permit",
retention_policy_ref=JOURNEY["records"]["retention_policy_ref"],
disclosure_state="partly_disclosable",
),
),
@@ -568,7 +578,7 @@ class InstitutionalGovernanceJourneyTests(unittest.TestCase):
get_case(session, principal, case_id="case-1"),
)
self.assertEqual(
"decided",
JOURNEY["case"]["decided_status"],
get_workspace_object(
session,
principal,
@@ -583,7 +593,7 @@ class InstitutionalGovernanceJourneyTests(unittest.TestCase):
self.assertEqual("confirmed", reconstruction["observed_effects"][0]["state"])
self.assertEqual("audit:delivery-1", reconstruction["observed_effects"][0]["audit_event_refs"][0])
self.assertEqual("application-1", reconstruction["fact_evidence"][0]["evidence_id"])
self.assertEqual("The application satisfies the effective rule.", reconstruction["reasoning"])
self.assertEqual(JOURNEY["decision"]["reasoning"], reconstruction["reasoning"])
self.assertEqual("review:administrative-court", reconstruction["review_refs"][0])