User journey catalogue¶
Purpose and responsibility¶
This is the living behavioural model for LMSTool. It records realistic journeys, current evidence, coverage gaps, workflow matrices, and the bounded golden backlog. The rules are defined in the user journey testing strategy.
This catalogue does not own current test totals, skip budgets, fixture-variable inventories, CI results, or live demo commands. Those remain in Playwright E2E coverage and demo environment acceptance testing.
Journey index¶
| Journey | Area | Behaviour | Actors | Start → outcome | Golden / priority | Disposition | Evidence / gap |
|---|---|---|---|---|---|---|---|
| UJ-AUTH-001 | AUTH |
Anonymous entry and authenticated map home | ANONYMOUS, dataset actor |
Signed out → login/map | No / P2 | COVERED |
Mapping |
| UJ-AUTH-002 | AUTH |
Successful and failed login | ANONYMOUS, SUPERUSER |
Credentials → session or safe error | No / P2 | COVERED |
Mapping |
| UJ-ACCESS-001 | ACCESS |
Switch active dataset | Dataset actor | Dataset A → scoped Dataset B | Yes / P1 | COVERED |
Mapping |
| UJ-ACCESS-002 | ACCESS |
Cross-dataset non-disclosure | All dataset roles | Visible dataset → foreign UUID denied | Yes / P1 | COVERED |
Mapping |
| UJ-PARCEL-001 | PARCEL |
View, search, map, and history | Dataset reader | Active dataset → scoped inspection | No / P2 | COVERED |
Mapping |
| UJ-PARCEL-002 | PARCEL |
Browser-based parcel authoring | EDITOR |
Existing/new parcel → valid draft change | No / P2 | GAP/PARTIAL_EVIDENCE |
Gap |
| UJ-PARCEL-003 | PARCEL |
Approved parcel GPKG export/re-upload | EDITOR |
Filtered parcels → upload preview | No / P2 | COVERED |
Mapping |
| UJ-DRAFT-001 | DRAFT |
Independent review and approval through public API | Editor, reviewer, approver | DRAFT → APPROVED |
No / P1 | COVERED |
Mapping |
| UJ-DRAFT-002 | DRAFT |
Complete browser review and approval | Editor, reviewer, approver | Source draft → approved successor | Yes / P1 | COVERED |
Mapping |
| UJ-DRAFT-003 | DRAFT |
Reject, correct, resubmit, approve | Editor, reviewer, approver | SUBMITTED → corrected APPROVED |
Yes / P1 | COVERED |
Mapping |
| UJ-DRAFT-004 | DRAFT |
Two-editor collaboration and attribution | Two editors, reviewer, approver | One editor creates → another submits | No / P2 | COVERED |
Mapping |
| UJ-DRAFT-005 | DRAFT |
State-specific cancellation | Editor/reviewer/approver | Active draft → CANCELLED |
No / P2 | COVERED |
Mapping |
| UJ-DRAFT-006 | DRAFT |
Stale/revoked/concurrent safety | Workflow actors | Stale authority/state → no partial mutation | Yes / P1 | COVERED |
Mapping |
| UJ-EXCH-001 | EXCH |
Externally edited GPKG round trip | EDITOR |
Download → external edit → imported draft | Yes / P1 | COVERED |
Mapping |
| UJ-EXCH-002 | EXCH |
Inspection export and import denial | Reviewer, approver | Inspection package → visible, not importable | No / P1 | COVERED |
Mapping |
| UJ-EXCH-003 | EXCH |
GeoJSON/KML production import | Any actor | Export-only file → import rejected | No / P1 | INTENTIONALLY_UNSUPPORTED |
Contract |
| UJ-UPLOAD-001 | UPLOAD |
Upload, preview, create drafts, continue | EDITOR |
Projected file → workflow drafts | Yes / P1 | COVERED |
Mapping |
| UJ-UPLOAD-002 | UPLOAD |
Invalid/stale/duplicate recovery | EDITOR |
Bad or repeated preview → safe recovery | No / P1 | COVERED |
Mapping |
| UJ-UPLOAD-003 | UPLOAD |
Upload role denial | Non-editor dataset actors | Upload route/request → no mutation | No / P1 | COVERED |
Mapping |
| UJ-TOPO-001 | TOPO |
Atomic split through approval | Editor, reviewer, approver | One source → two versioned outputs | Yes / P1 | COVERED |
Mapping |
| UJ-TOPO-002 | TOPO |
Edge-connected merge through approval | Editor, reviewer, approver | Several sources → one output | Yes / P1 | COVERED |
Mapping |
| UJ-TOPO-003 | TOPO |
Corner-only merge rejection | EDITOR |
Invalid sources → no request | No / P2 | COVERED |
Mapping |
| UJ-TOPO-004 | TOPO |
Conflict, stale-state, and rollback safety | Workflow actors | Conflicting request → no partial writes | Yes / P1 | COVERED |
Mapping |
| UJ-OVERLAP-001 | OVERLAP |
Live overlap advisory before save | EDITOR |
Proposed geometry → accessible warning | Yes / P1 | COVERED |
Mapping |
| UJ-OVERLAP-002 | OVERLAP |
Authoritative overlap prevention | Workflow actors/direct writer | Conflicting geometry → submit/DB denial | Yes / P1 | COVERED |
Mapping |
| UJ-SNAP-001 | SNAP |
Snap settings persist and propagate | Authenticated user | Settings change → editor consumers update | No / P2 | COVERED |
Mapping |
| UJ-SNAP-002 | SNAP |
Snap/trace save and workflow revalidation | EDITOR, reviewer, approver |
Browser snap → canonical approved geometry | Yes / P1 | COVERED |
Mapping |
| UJ-BASEMAP-001 | BASEMAP |
Basemap choice inheritance and fallback | Dataset reader | Select provider → inherited/fallback map | No / P2 | COVERED |
Mapping |
| UJ-BASEMAP-002 | BASEMAP |
Basemap catalogue administration | SUPERUSER |
Admin selection → atomic default/subset | No / P2 | COVERED |
Mapping |
| UJ-ROLE-001 | ROLE |
Exact roles and separation of duties | All workflow actors | Crafted or visible action → correct allow/deny | Yes / P1 | COVERED |
Mapping |
| UJ-ROLE-002 | ROLE |
System administration without workflow authority | SUPERUSER |
Django admin access → dataset workflow denied | Yes / P1 | COVERED |
Mapping |
Critical-browser implementation evidence¶
The fixed golden journeys are COVERED by the completed, unfiltered mandatory
browser run and their independent persisted-state/invariant controls. Every
required subcase passes in its declared browser projects. The corner-only merge
and controlled-basemap companions also have complete bounded evidence, without
adding golden journeys or proving live provider availability. Broader parcel
authoring remains partial. The owner explicitly deferred Package 2 performance
follow-up on 2026-09-08 as non-blocking for publication, not performance-passed;
real-container acceptance remains separately blocked. Current results, earlier
failed attempts, artifacts and these separate dispositions belong in
Playwright E2E coverage.
All locators below resolve to executed tests. Their assertion boundaries define
the covered behaviour, not a broader release-readiness claim. Every case uses
the independently prepared slot and fresh read-only
tests/e2e/fixtures/scenario.ts::observeScenario observations. The
tests/e2e/fixtures/scenarios.json registry supplies exact
case/project membership; no required recovery case may be replaced by a
remaining journey tag.
| Journey | Primary browser evidence | Assertion boundary |
|---|---|---|
UJ-ACCESS-001 |
tests/e2e/cache-authorization.spec.ts::ACCESS-SWITCH-RELOAD |
Profile switch, warmed map/list scope and reload; independent selected-dataset and unchanged-domain snapshot. |
UJ-ACCESS-002 |
tests/e2e/cache-authorization.spec.ts::ACCESS-FOREIGN-DENIAL; tests/e2e/cache-authorization.spec.ts::ACCESS-ANONYMOUS-DENIAL |
Guessed parcel/draft/topology pages and API reads deny safely without foreign metadata/geometry or state changes. |
UJ-DRAFT-002 |
tests/e2e/parcel-draft-workflow.spec.ts::DRAFT-APPROVE-CHAIN |
Visible save/submit/review/approve and reload; fixtures/workflow.ts::expectApprovedChain checks one successor, source retirement and ordered actor-attributed events. |
UJ-DRAFT-003 |
tests/e2e/parcel-draft-workflow.spec.ts::DRAFT-REJECT-CORRECT-CHAIN |
Visible rejection and correction via a new draft on the same parcel/source chain; original rejection and distinct draft IDs remain auditable. |
UJ-DRAFT-006 |
tests/e2e/parcel-draft-workflow.spec.ts::DRAFT-STALE-ACTION; tests/e2e/parcel-draft-workflow.spec.ts::DRAFT-REVOKED-ACTION |
Loaded actions become stale or lose their grant; fixtures/workflow.ts::expectDeniedDraftUnchanged checks revision/domain state and only permitted denial audit. |
UJ-EXCH-001 |
tests/e2e/draft-editing-exchange.spec.ts::EXCHANGE-EDIT-ROUNDTRIP; tests/e2e/draft-editing-exchange.spec.ts::EXCHANGE-RECOVERABLE-ERROR |
Actual download/edit/upload, digest evidence and recoverable stale package; assertImportedDraft checks geometry/revision/import actor/CRS, while reference attributes remain unchanged. |
UJ-UPLOAD-001 |
tests/e2e/upload-draft-workflow.spec.ts::UPLOAD-MIXED-APPLY-FOLLOWUP; tests/e2e/upload-draft-workflow.spec.ts::UPLOAD-REPEAT-APPLY; tests/e2e/upload-draft-workflow.spec.ts::UPLOAD-STALE-PREVIEW; tests/e2e/upload-draft-workflow.spec.ts::UPLOAD-NONEDITOR-DENIAL |
File chooser, mixed preview, apply/status/created-draft submission, repeated/stale/non-editor controls; expectMixedApplication checks drafts/results/CRS and no direct official mutation. |
UJ-TOPO-001 |
tests/e2e/parcel-topology-workflow.spec.ts::TOPO-SPLIT-APPROVE |
Pointer-drawn split and visible independent stages; expectAtomicTopology compares outputs, lineage, one transaction, events and PostGIS union/area. |
UJ-TOPO-002 |
tests/e2e/parcel-topology-workflow.spec.ts::TOPO-MERGE-APPROVE; tests/e2e/parcel-topology-workflow.spec.ts::TOPO-MERGE-CORNER-DENIAL; tests/e2e/parcel-topology-workflow.spec.ts::TOPO-MERGE-FOREIGN-DENIAL |
Visible source/donor selection and stages; expectAtomicTopology checks atomic merge, with corner/foreign denial snapshots. |
UJ-TOPO-004 |
tests/e2e/parcel-topology-workflow.spec.ts::TOPO-LATE-CONFLICT-RECOVERY |
Submit a loaded stale page, observe conflict, reload and continue review; official/request/output/lineage/transaction snapshots remain unchanged except defined denial audit. |
UJ-OVERLAP-001 |
tests/e2e/parcel-overlap-governance.spec.ts::OVERLAP-ADVISORY-CORRECTION; tests/e2e/parcel-overlap-governance.spec.ts::OVERLAP-PROTECTED-DENIAL |
Actual geometry change/advisory/correction and protected access control; independent no-write snapshots. |
UJ-OVERLAP-002 |
tests/e2e/parcel-overlap-governance.spec.ts::OVERLAP-LOSING-SUBMIT |
Competing visible submissions leave one reservation and an editable denied proposal; independent official/draft/event observations. |
UJ-SNAP-002 |
tests/e2e/parcel-snapping.spec.ts::SNAP-POINT-EDGE-TRACE-APPROVE; tests/e2e/parcel-snapping.spec.ts::SNAP-STALE-TARGET; tests/e2e/parcel-snapping.spec.ts::SNAP-INACCESSIBLE-TARGET |
authorSnappedDraft uses actual point/edge/trace controls; proposal/approved storage geometry, provenance, events, unchanged targets and later denial are checked. |
UJ-ROLE-001 |
tests/e2e/exact-role-boundaries.spec.ts::ROLE-EXACT-STAGES; tests/e2e/exact-role-boundaries.spec.ts::ROLE-MULTI-ACTOR-SEPARATION |
Visible exact-stage controls, crafted wrong-stage/self-decision denial, independent successful actors and fresh domain/audit observations. |
UJ-ROLE-002 |
tests/e2e/superuser-dataset-boundary.spec.ts::ROLE-ADMIN-WITHOUT-GRANTS |
Real administrator surface with no grants/active dataset; authoring forms/actions deny and independent domain/grant snapshot remains unchanged. |
The fixtures/workflow.ts references in this table are relative to
tests/e2e/; other named assertion helpers are in the cited spec file.
COMP-* scenarios retain the original exact titles and locators in the
registry. In particular, ordinary API approval/rejection/cancellation and
collaboration, exchange inspection exports, upload scaffolding/denial,
topology API/corner cases, cache revocation/deactivation, and map/precision
controls remain supporting evidence. They are not deleted, optionalized, or
promoted into proof of browser interactions they do not perform.
Evidence registry¶
Locators below were checked against current source. Playwright titles were reconciled manually by file and complete title because collector output uses a different separator format.
| Evidence | Stable locator and source | Layer / contribution | Proves | Limitation |
|---|---|---|---|---|
EV-AUTH-LOGIN |
tests/test_login_e2e.py::LoginE2ETests::test_admin_login_success and tests/test_login_e2e.py::LoginE2ETests::test_admin_login_failure |
Browser / primary | Successful session and safe invalid-credential feedback | Django-admin surface, not every dataset persona |
EV-AUTH-HOME |
tests/e2e/map-home-navigation.spec.ts::Map home navigation > anonymous users opening home log in before seeing the parcel map |
Browser / primary | Anonymous redirect, signed-in map landing, toolbar navigation | Does not prove credential validation |
EV-ACCESS-BROWSER |
tests/test_dataset_access_e2e.py::DatasetAccessE2ETests::test_dataset_switch_and_unauthorized_direct_access |
Browser / primary | Active-dataset switch and unauthorized direct access | Python browser family is outside TypeScript skip budget |
EV-ACCESS-SCOPE |
apps/parcels/tests/test_dataset_scoping.py::DatasetScopingRegressionTests::test_switching_active_dataset_changes_scope and apps/parcels/tests/test_dataset_rbac_enforcement.py::DatasetRbacEnforcementTests::test_detail_view_denies_cross_dataset_uuid_access |
API/view / primary | Query scoping, role-preserved reads, cross-dataset concealment | Does not exercise browser controls |
EV-PARCEL-WORKSPACE |
tests/e2e/shared-polygon-map.spec.ts::Shared Polygon Map > parcel detail, draft detail, and update reuse the shared workspace shell |
Browser / primary | Shared parcel/draft workspace and overlays | Inspection-focused, not complete authoring |
EV-PARCEL-AUTHOR |
tests/test_parcel_workflow_e2e.py::ParcelWorkflowE2ETests::test_parcel_creation_basic and tests/test_parcel_workflow_e2e.py::ParcelWorkflowE2ETests::test_parcel_creation_validation |
Browser / supporting | Browser drawing and validation | Legacy superuser/direct-authoring assumptions do not prove current exact-editor draft workflow |
EV-PARCEL-EXPORT |
tests/e2e/approved-parcel-export.spec.ts::editor exports and re-uploads filtered approved parcels as GeoPackage |
Browser / primary | Filter, download, file signature, re-upload, preview | File is not externally modified and no draft is updated |
EV-DRAFT-API |
tests/e2e/parcel-draft-workflow.spec.ts::ParcelDraft workflow API > editor -> reviewer -> approver final approval flow |
API/view / primary | Public API transitions, final state, official-version event | Does not click server-rendered workflow controls |
EV-DRAFT-COLLAB |
tests/e2e/parcel-draft-workflow.spec.ts::ParcelDraft workflow API > two editors collaborate before independent review and approval |
API/view / primary | Two editor IDs, submit attribution, independent decisions | Browser queue/detail flow not exercised |
EV-DRAFT-REJECT |
tests/e2e/parcel-draft-workflow.spec.ts::ParcelDraft workflow API > reviewer can reject submitted draft with reason |
API/view / supporting | Reviewer rejection and reason | No correction, resubmission, or later approval |
EV-DRAFT-CANCEL |
tests/e2e/parcel-draft-workflow.spec.ts::ParcelDraft workflow API > cancel authority matrix sample and apps/parcels/tests/test_parcel_draft_services.py::ParcelDraftWorkflowServiceTests::test_cancel_authority_matrix |
API/view + integration/service / primary | State-specific cancellation roles and persisted reason | Representative browser cancellation prompt not exercised |
EV-DRAFT-SERVICE |
apps/parcels/tests/test_parcel_draft_services.py::ParcelDraftWorkflowServiceTests::test_review_accept_and_final_approve_creates_new_official_version |
Integration/service / invariant | Locked workflow, storage-SRID persistence, version creation, events | Not a user-visible path |
EV-DRAFT-CONCURRENCY |
apps/parcels/tests/test_parcel_draft_concurrency.py::ParcelDraftApprovalRaceTests::test_separate_transactions_approve_only_once_with_ordered_events; retained ParcelDraftConcurrencyTests::test_locked_transition_uses_current_role_after_revocation and test_prevent_double_approval in the same module |
Integration/service / invariant | Real separate-transaction approval contention, one version/transaction, ordered actor-attributed terminal/denial events and unchanged winner revision | Sequential duplicate and revoked-role controls remain separate; not a browser stale-page test |
EV-DRAFT-UI |
tests/e2e/workflow-ui-mvp.spec.ts::Workflow UI MVP > workflow queue opens an enabled task and detail action prompts for confirmation |
Browser / supporting | Queue/detail navigation and confirmation surface | Does not complete multi-role lifecycle |
EV-EXCH-PACKAGE |
apps/parcels/tests/test_draft_exchange_package.py::DraftExchangePackageTests::test_edit_package_round_trip_has_manifest_and_edit_layer |
Integration/service / invariant | Versioned manifest and editable projected layer | Does not model external user edit or browser upload |
EV-EXCH-IMPORT |
apps/parcels/tests/test_draft_exchange_service.py::DraftExchangeServiceTests::test_another_authorized_editor_can_atomically_import |
Integration/service / supporting | Geometry import, atomicity, authorized second editor, audit | Browser download/edit/upload/reload chain absent |
EV-EXCH-VIEWS |
apps/parcels/tests/test_draft_exchange_views.py::DraftExchangeViewTests::test_reviewer_can_download_inspection_package and apps/parcels/tests/test_draft_exchange_views.py::DraftExchangeViewTests::test_reviewer_and_approver_cannot_open_import_form |
API/view / primary | Inspection export allowed and import form denied | Browser test checks actions but not package content |
EV-EXCH-BROWSER |
tests/e2e/draft-editing-exchange.spec.ts::editor workflow exposes separate edit, inspect, and import actions |
Browser / supporting | Correct role-specific actions are visible | Controls-only companion, not the actual file round trip |
EV-UPLOAD-APPLY |
apps/parcels/tests/test_parcel_enhanced_views.py::ParcelBulkUploadWorkflowViewsTestCase::test_upload_preview_apply_create_drafts_creates_source_and_new_chain_drafts |
Integration/service / supporting | Projected upload preview creates correct draft kinds and audit metadata | Full browser flow absent |
EV-UPLOAD-RECOVERY |
apps/parcels/tests/test_parcel_upload_apply_guard.py::UploadApplyDecisionTests::test_reapplying_completed_upload_raises_conflict and apps/parcels/tests/test_parcel_upload_apply_guard.py::UploadPreviewPayloadFreshnessTests::test_payload_with_stale_crs_contract_is_discarded |
Integration/service / primary | Duplicate apply, stale preview, safe conflict/recovery | Does not prove user-facing recovery copy |
EV-UPLOAD-ROLE |
apps/parcels/tests/test_parcel_enhanced_views.py::ParcelBulkUploadWorkflowViewsTestCase::test_upload_routes_require_explicit_editor_role |
API/view / primary | Viewer, reviewer, approver, and superuser upload-route denial without mutation | Does not exercise browser form submission |
EV-UPLOAD-BROWSER |
tests/e2e/upload-draft-workflow.spec.ts::Upload Draft Workflow > status page links created drafts back into workflow |
Browser / supporting | Preview/status scaffolding, continuation link, role denial | Scaffolding companion, not the actual upload/apply chain |
EV-TOPO-SPLIT |
tests/e2e/parcel-topology-workflow.spec.ts::Parcel topology workflow > editor, reviewer, and approver complete one atomic split |
Browser + API/view / supporting | Split line, rendered outputs, reload, state transitions, atomic receipt | Most transitions use request context rather than visible controls |
EV-TOPO-MERGE |
tests/e2e/parcel-topology-workflow.spec.ts::Parcel topology workflow > edge-connected sources complete one atomic merge and tests/e2e/parcel-topology-workflow.spec.ts::Parcel topology workflow > corner-only merge is rejected before request creation |
API/view / supporting | Valid merge lineage and invalid corner-only rejection | No merge workspace browser interaction |
EV-TOPO-GEOMETRY |
apps/parcels/tests/test_parcel_topology_geometry.py::ParcelTopologyGeometryTests::test_merge_requires_positive_shared_boundary_not_corner_contact |
Unit / invariant | Authoritative positive-length shared-boundary rule rejects point contact | Does not prove request-level non-persistence or user feedback |
EV-TOPO-SERVICE |
apps/parcels/tests/test_parcel_split_requests.py::ParcelSplitRequestServiceTests::test_approval_retires_source_and_creates_two_new_lineage_chains and apps/parcels/tests/test_parcel_merge_requests.py::ParcelMergeRequestServiceTests::test_approval_retires_all_sources_and_creates_one_many_to_one_result |
Integration/service / invariant | Source retirement, outputs, lineage, rollback | Not user-visible |
EV-TOPO-CONFLICT |
apps/parcels/tests/test_parcel_change_request_conflicts.py::ParcelChangeRequestConflictTests::test_topology_transition_uses_current_role_after_revocation and apps/parcels/tests/test_parcel_change_request_conflicts.py::ParcelChangeRequestCreationRaceTests::test_competing_ordinary_and_topology_creation_allows_only_one |
Integration/service / invariant | Revocation, late conflicts, cross-workflow race safety | No stale browser-page presentation |
EV-OVERLAP-LIVE |
tests/e2e/parcel-overlap-governance.spec.ts::Parcel overlap governance > advisory API returns versioned safe conflict evidence |
Browser + API/view / supporting | Accessible workspace and safe advisory contract | API companion does not prove actual geometry gestures |
EV-OVERLAP-BACKSTOP |
apps/parcels/tests/test_overlap_governance_workflow.py::AuthoritativeOverlapBackstopTests::test_direct_overlapping_insert_raises_stable_constraint and apps/parcels/tests/test_overlap_governance_workflow.py::OverlapGovernanceWorkflowTests::test_first_submission_reserves_area_and_second_is_denied |
Integration/service / invariant | Submit serialization and PostGIS backstop | Browser warning/recovery not exercised |
EV-SNAP-SETTINGS |
tests/e2e/parcel-snapping.spec.ts::Parcel boundary snapping > main Map Settings persists independent snap modes and limits |
Browser / primary | Settings persistence and consumer inheritance | Requires E2E actor/editor environment |
EV-SNAP-WORKFLOW |
apps/parcels/tests/test_snapping_workflow.py::SnappedProposalCanonicalizationTests::test_snapped_draft_full_workflow_uses_draft_dataset_roles and apps/parcels/tests/test_snapping_workflow.py::SnappedProposalCanonicalizationTests::test_submit_rejects_stale_target_and_preserves_draft_state |
Integration/service / supporting | Canonical storage geometry, provenance, stale recheck through approval | No browser drawing gestures |
EV-SNAP-GEOMETRY |
apps/parcels/tests/test_snapping_geometry.py::SnapCandidateGeometryTests::test_vertex_candidate_returns_exact_authoritative_coordinate and apps/parcels/tests/test_snapping_geometry.py::SnapCandidateGeometryTests::test_trace_returns_both_exact_exterior_ring_directions |
Integration/service / invariant | PostGIS candidate and trace authority | No user interaction |
EV-BASEMAP-USER |
tests/e2e/centralized-basemap.spec.ts::Centralized basemap inheritance > provider rejection falls back without changing preference or controls and tests/e2e/maptiler-basemaps.spec.ts::MapTiler Basemaps > parcel map selects MapTiler Streets without losing map controls |
Browser / primary | Choice inheritance, rejection fallback, attribution | Controlled resources do not prove live provider availability |
EV-BASEMAP-ADMIN |
apps/core/tests/test_map_background_catalog.py::BasemapCatalogAdminWorkflowTestCase::test_admin_can_save_subset_and_default_atomically and tests/e2e/pmtiles-basemap-admin.spec.ts::PMTiles Basemap Admin > admin page exposes subset/default controls for background catalog |
Integration/service + browser / primary | Atomic catalogue invariants and admin controls | Does not prove every external provider |
EV-ROLE-EXACT |
tests/e2e/exact-role-boundaries.spec.ts::Exact dataset workflow roles > higher roles cannot craft an editor-only topology create and tests/e2e/exact-role-boundaries.spec.ts::Exact dataset workflow roles > a multi-role creator cannot review its own ordinary draft |
Browser + API/view / primary | Exact roles, crafted request denial, actor separation | Representative surfaces, supported by broader lower layers |
EV-ROLE-POLICY |
apps/parcels/tests/test_workflow_authorization.py::WorkflowAuthorizationPolicyTests::test_creator_submitter_or_reviewer_cannot_approve and apps/core/tests/test_dataset_permissions.py::DatasetPermissionResolutionTests::test_explicit_role_helper_does_not_treat_higher_role_as_editor |
Unit + integration/service / invariant | Exact role sets, state policy, separation, superuser exclusion | Pure/lower-level evidence |
EV-ROLE-SUPERUSER |
tests/e2e/superuser-dataset-boundary.spec.ts::system administrator keeps Django admin access without dataset workflow access |
Browser / primary | Django admin succeeds while dataset workflow is absent/denied | Does not cover every admin model |
Additional invariant locators¶
| Evidence | Stable locator | Proves | Limitation |
|---|---|---|---|
EV-TOPO-APPROVAL-RACE |
apps/parcels/tests/test_parcel_split_requests.py::ParcelTopologyApprovalRaceTests::test_separate_transactions_approve_split_without_duplicate_outputs |
Two lock-contending transactions, one approval, two outputs/lineage edges, one transaction and ordered terminal/denial events | Lower-layer evidence, not browser acceptance |
EV-TOPO-ROLLBACK |
apps/parcels/tests/test_parcel_split_requests.py::ParcelSplitRequestServiceTests::test_final_approval_rolls_back_every_write_when_output_creation_fails; apps/parcels/tests/test_parcel_merge_requests.py::ParcelMergeRequestServiceTests::test_merge_approval_rolls_back_source_retirement_on_output_failure |
Injected output failure preserves complete official/request/output/event snapshots; no lineage or approval transaction | Lower-layer evidence, not browser acceptance |
EV-OVERLAP-RACE |
apps/parcels/tests/test_overlap_governance_workflow.py::OverlapReservationRaceTests::test_separate_transactions_reserve_overlapping_area_only_once |
Real overlapping proposal submission race, one reservation, one editable denial, no official/transaction/use writes | Lower-layer evidence, not browser acceptance |
EV-EXCH-IDENTITY |
apps/parcels/tests/test_draft_exchange_service.py::DraftExchangeServiceTests::test_tampered_identity_rejects_entire_batch_without_domain_or_file_residue |
Real GeoPackage draft/chain/dataset tampering rejects the entire batch; no domain or file residue beyond permitted rejected audit | Lower-layer evidence, not browser acceptance |
EV-EXCH-ROLLBACK |
apps/parcels/tests/test_draft_exchange_service.py::DraftExchangeServiceTests::test_stale_member_rolls_back_the_whole_batch; apps/parcels/tests/test_draft_exchange_service.py::DraftExchangeServiceTests::test_geometry_failure_labels_only_the_causal_record_invalid |
Complete domain snapshots survive stale and injected second-record failures; no successful import event or updated result | Lower-layer evidence, not browser acceptance |
EV-EXCH-DENIAL |
apps/parcels/tests/test_draft_exchange_views.py::DraftExchangeViewTests::test_non_editor_import_posts_leave_no_domain_audit_or_file_residue; apps/parcels/tests/test_draft_exchange_service.py::DraftExchangeServiceTests::test_all_non_editor_roles_are_denied_before_inspection_without_residue |
Viewer/reviewer/approver/grant-free administrator calls deny before inspection or import, preserving database and temporary files | Lower-layer evidence, not browser acceptance |
EV-DRAFT-DENIAL-REVISION |
apps/parcels/tests/test_parcel_draft_services.py::ParcelDraftWorkflowServiceTests::test_denied_stage_actions_preserve_draft_revision; apps/parcels/tests/test_parcel_draft_services.py::ParcelDraftWorkflowServiceTests::test_stale_stage_actions_preserve_draft_revision |
Wrong-role and stale stage denials preserve full draft/official/transaction state and retain only sanitized denial audit | Lower-layer evidence, not browser acceptance |
EV-ROLE-CREATE-GUARD |
apps/parcels/tests/test_workflow_ui_entrypoints.py::WorkflowUiEntrypointsTestCase::test_create_view_requires_exact_editor_before_rendering_form |
Authenticated exact editor retains the create form; other exact roles and grant-free administrator receive denial before authoring controls | Lower-layer evidence, not browser acceptance |
Named storage/constraint/trigger boundaries and strict file-CRS controls are
mapped in the lower-layer invariant inventory
and specs/030-critical-browser-journeys/data-model.md.
An error diagnostic emitted by the overlap trigger is not a separate
pg_constraint row.
Evidence mapping¶
| Journey | Evidence and contribution | Assertion scope |
|---|---|---|
UJ-AUTH-001 |
EV-AUTH-HOME primary |
Anonymous redirect and authenticated home/map navigation |
UJ-AUTH-002 |
EV-AUTH-LOGIN primary |
Valid and invalid login |
UJ-ACCESS-001 |
Primary browser evidence in the implementation table; EV-ACCESS-SCOPE supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-ACCESS-002 |
Primary browser evidence in the implementation table; EV-ACCESS-SCOPE, EV-ROLE-POLICY supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-PARCEL-001 |
EV-PARCEL-WORKSPACE primary; EV-ACCESS-SCOPE invariant |
Scoped inspection and history |
UJ-PARCEL-002 |
EV-PARCEL-AUTHOR, EV-DRAFT-UI supporting |
Drawing and workflow surfaces exist; exact-editor browser completion is missing |
UJ-PARCEL-003 |
EV-PARCEL-EXPORT primary |
Approved GPKG download and preview re-upload |
UJ-DRAFT-001 |
EV-DRAFT-API primary; EV-DRAFT-SERVICE invariant |
Complete public API lifecycle and official version |
UJ-DRAFT-002 |
Primary browser evidence in the implementation table; EV-DRAFT-API, EV-DRAFT-SERVICE supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-DRAFT-003 |
Primary browser evidence in the implementation table; EV-DRAFT-REJECT, EV-DRAFT-SERVICE supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-DRAFT-004 |
EV-DRAFT-COLLAB primary |
Two-editor attribution and independent decisions |
UJ-DRAFT-005 |
EV-DRAFT-CANCEL primary |
State-specific cancellation |
UJ-DRAFT-006 |
Primary browser evidence in the implementation table; EV-DRAFT-CONCURRENCY, EV-DRAFT-DENIAL-REVISION supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-EXCH-001 |
Primary browser evidence in the implementation table; EV-EXCH-IDENTITY, EV-EXCH-ROLLBACK, EV-EXCH-DENIAL, EV-EXCH-PACKAGE supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-EXCH-002 |
EV-EXCH-VIEWS primary; EV-EXCH-BROWSER supporting |
Inspection allowed, import denied |
UJ-EXCH-003 |
Product CRS/import contract | GeoJSON/KML import is intentionally excluded |
UJ-UPLOAD-001 |
Primary browser evidence in the implementation table; EV-UPLOAD-APPLY, EV-UPLOAD-RECOVERY, EV-UPLOAD-ROLE supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-UPLOAD-002 |
UPLOAD-REPEAT-APPLY, UPLOAD-STALE-PREVIEW primary browser; EV-UPLOAD-RECOVERY invariant |
Visible recovery and independent no-duplicate/no-partial-write checks |
UJ-UPLOAD-003 |
UPLOAD-NONEDITOR-DENIAL primary browser; EV-UPLOAD-ROLE, EV-ROLE-POLICY invariant; retained browser controls |
Visible non-editor authoring denial and unchanged upload/draft state |
UJ-TOPO-001 |
Primary browser evidence in the implementation table; EV-TOPO-SERVICE, EV-TOPO-ROLLBACK, EV-TOPO-APPROVAL-RACE supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-TOPO-002 |
Primary browser evidence in the implementation table; EV-TOPO-SERVICE, EV-TOPO-ROLLBACK, EV-TOPO-GEOMETRY supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-TOPO-003 |
TOPO-MERGE-CORNER-DENIAL primary browser; EV-TOPO-GEOMETRY invariant; retained API companion |
Visible denial and independent unchanged request/source assertions |
UJ-TOPO-004 |
Primary browser evidence in the implementation table; EV-TOPO-CONFLICT, EV-TOPO-ROLLBACK, EV-TOPO-APPROVAL-RACE supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-OVERLAP-001 |
Primary browser evidence in the implementation table; EV-OVERLAP-LIVE supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-OVERLAP-002 |
Primary browser evidence in the implementation table; EV-OVERLAP-BACKSTOP, EV-OVERLAP-RACE supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-SNAP-001 |
EV-SNAP-SETTINGS primary |
User settings and inherited consumers |
UJ-SNAP-002 |
Primary browser evidence in the implementation table; EV-SNAP-WORKFLOW, EV-SNAP-GEOMETRY supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-BASEMAP-001 |
EV-BASEMAP-USER primary |
Controlled-provider choice, inheritance and rejection fallback; not live provider availability |
UJ-BASEMAP-002 |
EV-BASEMAP-ADMIN primary |
Atomic admin subset/default and UI |
UJ-ROLE-001 |
Primary browser evidence in the implementation table; EV-ROLE-EXACT, EV-ROLE-POLICY, EV-DRAFT-DENIAL-REVISION supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
UJ-ROLE-002 |
Primary browser evidence in the implementation table; EV-ROLE-SUPERUSER, EV-ROLE-POLICY, EV-ROLE-CREATE-GUARD supporting/invariant |
Visible actions/reloads and independent persisted-state checks pass; retained controls prove supporting invariants |
Role-action matrix¶
Each dataset-role column assumes only that exact grant.
| Context/action | Anonymous | Viewer | Editor | Reviewer | Approver | Superuser | Notes |
|---|---|---|---|---|---|---|---|
| Open application map | Login redirect | ALLOW |
ALLOW |
ALLOW |
ALLOW |
Admin only | Dataset readers require an accessible active dataset |
| Read active-dataset parcel/draft/history | NON_DISCLOSE |
ALLOW |
ALLOW |
ALLOW |
ALLOW |
NON_DISCLOSE |
Hierarchical dataset reading |
| Read foreign-dataset UUID | NON_DISCLOSE |
NON_DISCLOSE |
NON_DISCLOSE |
NON_DISCLOSE |
NON_DISCLOSE |
NON_DISCLOSE |
Existing 404/non-disclosure behaviour |
| Create/update/submit ordinary draft | DENY |
DENY |
ALLOW |
DENY |
DENY |
DENY |
Exact editor |
| Review/reject submitted draft | DENY |
DENY |
DENY |
ALLOW |
DENY |
DENY |
Creator/submitter separation still applies |
| Approve/reject reviewed draft | DENY |
DENY |
DENY |
DENY |
ALLOW |
DENY |
Creator/submitter/reviewer separation applies |
| Export draft for editing/import edits | DENY |
DENY |
ALLOW |
DENY |
DENY |
DENY |
Inspection export is separate |
| Export draft for inspection | DENY |
Existing read contract | Existing read contract | ALLOW |
ALLOW |
DENY |
Package remains non-importable |
| Upload/analyse/apply parcel file | DENY |
DENY |
ALLOW |
DENY |
DENY |
DENY |
Exact editor |
| Create/edit/validate/submit split or merge | DENY |
DENY |
ALLOW |
DENY |
DENY |
DENY |
Exact editor |
| Review submitted split or merge | DENY |
DENY |
DENY |
ALLOW |
DENY |
DENY |
Same separation rules as ordinary drafts |
| Approve reviewed split or merge | DENY |
DENY |
DENY |
DENY |
ALLOW |
DENY |
Same separation rules as ordinary drafts |
| Request live snap/overlap authoring support | DENY |
DENY |
ALLOW |
DENY |
DENY |
DENY |
Authorization precedes geometry validation |
| Manage own map/snap settings | Login redirect | ALLOW |
ALLOW |
ALLOW |
ALLOW |
Existing authenticated contract | Settings do not grant workflow authority |
| Manage basemap catalogue in Django admin | DENY |
DENY |
DENY |
DENY |
DENY |
ALLOW |
System administration, not dataset role |
State-transition matrices¶
The evidence-scope column describes individual action controls. It is not a second journey disposition and does not enlarge the bounded browser contracts in the index and coverage views. Lower-layer-only cells remain explicit.
Ordinary drafts¶
stateDiagram-v2
[*] --> DRAFT
DRAFT --> SUBMITTED: submit / exact editor
DRAFT --> CANCELLED: cancel / editor
SUBMITTED --> REVIEWED: review accept / independent reviewer
SUBMITTED --> REJECTED: reject / independent reviewer
SUBMITTED --> CANCELLED: cancel / editor or reviewer
REVIEWED --> APPROVED: final approve / independent approver
REVIEWED --> REJECTED: reject / independent approver
REVIEWED --> CANCELLED: cancel / reviewer or approver
Text equivalent: A draft begins in DRAFT. An exact editor may submit or
cancel it. In SUBMITTED, an independent reviewer may accept or reject it, and
an editor or reviewer may cancel. In REVIEWED, an independent approver may
approve or reject it, and a reviewer or approver may cancel. Approved, rejected,
and cancelled states are terminal.
| Start | Action | Outcome | Exact role | Material denial | Journey | Evidence scope |
|---|---|---|---|---|---|---|
DRAFT |
Update | DRAFT |
Editor | Wrong role/state, invalid geometry, stale source | UJ-PARCEL-002 |
GAP |
DRAFT |
Submit | SUBMITTED |
Editor | Wrong role, missing/invalid geometry, conflict | UJ-DRAFT-001 |
Lower-layer evidence |
DRAFT |
Cancel | CANCELLED |
Editor | Wrong role/state | UJ-DRAFT-005 |
Lower-layer evidence |
SUBMITTED |
Review accept | REVIEWED |
Reviewer | Creator/submitter, revoked role, stale state | UJ-ROLE-001, UJ-DRAFT-006 |
Lower-layer evidence |
SUBMITTED |
Reject | REJECTED |
Reviewer | Creator/submitter, blank reason | UJ-DRAFT-003 |
Browser rejection, new correction draft and independent approval; original rejection retained |
SUBMITTED |
Cancel | CANCELLED |
Editor or reviewer | Wrong role/state | UJ-DRAFT-005 |
Lower-layer evidence |
REVIEWED |
Final approve | APPROVED |
Approver | Prior actor, stale source, overlap/conflict | UJ-DRAFT-001, UJ-DRAFT-006 |
Lower-layer evidence |
REVIEWED |
Reject | REJECTED |
Approver | Prior actor, blank reason | UJ-ROLE-001 |
Lower-layer evidence |
REVIEWED |
Cancel | CANCELLED |
Reviewer or approver | Wrong role/state | UJ-DRAFT-005 |
Lower-layer evidence |
| Terminal | Any transition | Unchanged | None | Invalid state | UJ-DRAFT-006 |
Lower-layer evidence |
Split and merge requests¶
Topology requests use the same workflow states and decision separation. Exact edit-stage actions include source selection, output editing/import, split-line editing, validation, and submission.
| Start | Action | Outcome | Exact role | Material denial | Journey | Evidence scope |
|---|---|---|---|---|---|---|
| No request | Create valid split | DRAFT, two outputs |
Editor | Wrong role, wrong source count, active conflict | UJ-TOPO-001 |
Browser creation/approval with independent output and source checks |
| No request | Create valid merge | DRAFT, one output |
Editor | Wrong role, invalid donor/connectivity, active conflict | UJ-TOPO-002 |
Browser creation/approval and corner/foreign denial controls |
| No request | Create corner-only merge | No request | None | Positive-length edge requirement | UJ-TOPO-003 |
Browser denial with independent unchanged request/source state |
DRAFT |
Edit/import output or split line | DRAFT |
Editor | Wrong role/state, bad CRS/geometry | UJ-TOPO-001 |
Browser split-line persistence; lower-layer output/edit guards |
DRAFT |
Submit | SUBMITTED |
Editor | Wrong role, stale/conflicting sources | UJ-TOPO-004 |
Lower-layer evidence |
SUBMITTED |
Review accept/reject | REVIEWED/REJECTED |
Reviewer | Prior actor, revoked role, stale state | UJ-ROLE-001, UJ-TOPO-004 |
Lower-layer evidence |
REVIEWED |
Final approve | APPROVED |
Approver | Prior actor, stale/conflict/output failure | UJ-TOPO-001, UJ-TOPO-002, UJ-TOPO-004 |
Browser split/merge approval; independent lineage/output state; lower-layer rollback and transaction races |
| Active | State-specific cancel | CANCELLED |
Contract role | Wrong role/state | UJ-TOPO-004 |
Lower-layer evidence |
| Terminal | Any transition | Unchanged | None | Invalid state | UJ-TOPO-004 |
Lower-layer evidence |
Journey-layer matrix¶
Evidence IDs identify current proof. GAP means the required behaviour at that
layer or across layers remains incomplete.
| Journey | Unit | Integration/service | API/view | Browser | Owner acceptance |
|---|---|---|---|---|---|
UJ-AUTH-001 |
— | — | EV-AUTH-HOME supporting |
EV-AUTH-HOME |
— |
UJ-AUTH-002 |
— | — | Authentication view tests | EV-AUTH-LOGIN |
— |
UJ-ACCESS-001 |
EV-ROLE-POLICY |
EV-ACCESS-SCOPE |
EV-ACCESS-SCOPE |
Primary browser evidence in the implementation table | — |
UJ-ACCESS-002 |
EV-ROLE-POLICY |
EV-ACCESS-SCOPE |
EV-ACCESS-SCOPE |
Primary browser evidence in the implementation table | — |
UJ-PARCEL-001 |
— | Overlay/scoping suites | Parcel views | EV-PARCEL-WORKSPACE |
— |
UJ-PARCEL-002 |
Validation suites | Draft service suites | Workflow views | GAP |
— |
UJ-PARCEL-003 |
— | Export CRS integration | Export/upload views | EV-PARCEL-EXPORT |
— |
UJ-DRAFT-001 |
EV-ROLE-POLICY |
EV-DRAFT-SERVICE |
EV-DRAFT-API |
UJ-DRAFT-002 is the browser equivalent |
— |
UJ-DRAFT-002 |
EV-ROLE-POLICY |
EV-DRAFT-SERVICE |
EV-DRAFT-API |
Primary browser evidence in the implementation table | — |
UJ-DRAFT-003 |
Policy/service tests | Rejection tests | EV-DRAFT-REJECT |
Primary browser evidence in the implementation table | — |
UJ-DRAFT-004 |
Policy tests | Attribution/event tests | EV-DRAFT-COLLAB |
GAP for visible multi-user flow |
— |
UJ-DRAFT-005 |
EV-ROLE-POLICY |
EV-DRAFT-CANCEL |
EV-DRAFT-CANCEL |
GAP for prompts |
— |
UJ-DRAFT-006 |
EV-ROLE-POLICY |
EV-DRAFT-CONCURRENCY |
Conflict responses | Primary browser evidence in the implementation table | — |
UJ-EXCH-001 |
Package helpers | EV-EXCH-PACKAGE, EV-EXCH-IMPORT |
EV-EXCH-VIEWS |
Primary browser evidence in the implementation table | — |
UJ-EXCH-002 |
Package contract | Service denial | EV-EXCH-VIEWS |
EV-EXCH-BROWSER supporting |
— |
UJ-EXCH-003 |
Format contract | Rejection suites | Import view rejection | N/A | — |
UJ-UPLOAD-001 |
Parser/decision tests | EV-UPLOAD-APPLY |
Upload views | Primary browser evidence in the implementation table | — |
UJ-UPLOAD-002 |
Decision tests | EV-UPLOAD-RECOVERY |
Preview/apply guards | UPLOAD-REPEAT-APPLY, UPLOAD-STALE-PREVIEW |
— |
UJ-UPLOAD-003 |
EV-ROLE-POLICY |
Role guards | EV-UPLOAD-ROLE |
UPLOAD-NONEDITOR-DENIAL primary; retained controls supporting |
— |
UJ-TOPO-001 |
Geometry policy | EV-TOPO-SERVICE |
Topology API/view tests | Primary browser evidence in the implementation table | — |
UJ-TOPO-002 |
Geometry policy | EV-TOPO-SERVICE |
Topology API/view tests | Primary browser evidence in the implementation table | — |
UJ-TOPO-003 |
EV-TOPO-GEOMETRY |
Merge service tests | Topology API/view tests | TOPO-MERGE-CORNER-DENIAL |
— |
UJ-TOPO-004 |
Policy tests | EV-TOPO-CONFLICT |
Conflict responses | Primary browser evidence in the implementation table | — |
UJ-OVERLAP-001 |
Tolerance rules | Advisory service | Advisory API | Primary browser evidence in the implementation table | — |
UJ-OVERLAP-002 |
Tolerance rules | EV-OVERLAP-BACKSTOP |
Workflow denials | Primary browser evidence in the implementation table | Performance evidence owned separately |
UJ-SNAP-001 |
Settings constraints | Settings service | Settings API | EV-SNAP-SETTINGS |
— |
UJ-SNAP-002 |
Candidate/path rules | EV-SNAP-WORKFLOW, EV-SNAP-GEOMETRY |
Snap APIs | Primary browser evidence in the implementation table | — |
UJ-BASEMAP-001 |
Provider normalization | Catalogue/runtime services | Map views | EV-BASEMAP-USER |
External provider evidence owned separately |
UJ-BASEMAP-002 |
Catalogue constraints | EV-BASEMAP-ADMIN |
Admin view | EV-BASEMAP-ADMIN |
— |
UJ-ROLE-001 |
EV-ROLE-POLICY |
Role/service suites | EV-ROLE-EXACT |
Primary browser evidence in the implementation table | Demo separation links to live runbook |
UJ-ROLE-002 |
EV-ROLE-POLICY |
Admin permission suites | Admin/dataset views | Primary browser evidence in the implementation table | Demo separation links to live runbook |
Coverage views¶
Covered¶
UJ-AUTH-001, UJ-AUTH-002, UJ-ACCESS-001, UJ-ACCESS-002,
UJ-PARCEL-001, UJ-PARCEL-003, UJ-DRAFT-001, UJ-DRAFT-002,
UJ-DRAFT-003, UJ-DRAFT-004, UJ-DRAFT-005, UJ-DRAFT-006,
UJ-EXCH-001, UJ-EXCH-002, UJ-UPLOAD-001, UJ-UPLOAD-002,
UJ-UPLOAD-003, UJ-TOPO-001, UJ-TOPO-002, UJ-TOPO-003,
UJ-TOPO-004, UJ-OVERLAP-001, UJ-OVERLAP-002, UJ-SNAP-001,
UJ-SNAP-002, UJ-BASEMAP-001, UJ-BASEMAP-002, UJ-ROLE-001,
UJ-ROLE-002.
The selected golden journeys have complete mandatory-browser evidence and independent persisted-state/invariant checks. Companions retain their documented lower-layer or bounded browser contracts. These dispositions do not waive separate performance, live-provider or real-container acceptance gates.
Gaps¶
| Journey | Reason | Missing evidence | Intended layer |
|---|---|---|---|
UJ-PARCEL-002 |
PARTIAL_EVIDENCE |
Complete exact-editor authoring contract beyond the retained source-draft case | Browser plus persisted state |
Intentionally unsupported¶
| Journey | Contract |
|---|---|
UJ-EXCH-003 |
The versioned import contract requires explicit projected CRS metadata and keeps GeoJSON/KML export-only |
Golden journey backlog¶
All selected journeys are P1 under the strategy's deterministic rule. The initial bound is exactly 15; no P2 candidate is promoted.
The following P1 IDs are companion behaviours, not separate golden
implementations: UJ-DRAFT-001 is the API control for UJ-DRAFT-002;
UJ-EXCH-002 is the inspection/denial control within UJ-EXCH-001; and
UJ-UPLOAD-002 plus UJ-UPLOAD-003 are recovery and authorization variants
within UJ-UPLOAD-001. UJ-EXCH-003 is intentionally unsupported and is not an
automation candidate. This consolidation keeps every supported P1 behaviour in
the bounded suite without duplicating end-to-end setup.
| Journey | User impact | Data integrity | Authorization | Regression | Selection reason |
|---|---|---|---|---|---|
UJ-ACCESS-001 |
High | Medium | High | Medium | Wrong active scope can expose or mutate the wrong dataset |
UJ-ACCESS-002 |
High | Medium | High | High | Cross-dataset disclosure is a security boundary |
UJ-DRAFT-002 |
High | High | High | High | Primary multi-role business workflow through the browser |
UJ-DRAFT-003 |
High | High | High | Medium | Corrective workflow must remain usable without bypassing review |
UJ-DRAFT-006 |
Medium | High | High | High | Stale/revoked/concurrent actions must not partially mutate |
UJ-EXCH-001 |
High | High | High | High | Crosses browser, external GIS file, CRS, workflow, and audit boundaries |
UJ-UPLOAD-001 |
High | High | High | High | Bulk file path creates authoritative workflow proposals |
UJ-TOPO-001 |
High | High | High | High | Split retires one source and creates lineage atomically |
UJ-TOPO-002 |
High | High | High | High | Merge retires several sources and creates lineage atomically |
UJ-TOPO-004 |
Medium | High | High | High | Conflicts and output failures require complete rollback |
UJ-OVERLAP-001 |
High | High | Medium | High | Editor needs pre-submit warning for material conflict |
UJ-OVERLAP-002 |
High | High | Medium | High | PostGIS backstop protects authoritative parcel integrity |
UJ-SNAP-002 |
High | High | High | High | Browser convenience must reproduce authoritative coordinates |
UJ-ROLE-001 |
High | High | High | High | Exact roles and actor separation protect every mutation stage |
UJ-ROLE-002 |
High | Medium | High | High | System administration must not bypass dataset workflow roles |
Detailed journeys¶
UJ-AUTH-001 — Anonymous entry and authenticated map home¶
- Intent: Users reach the parcel map only after authentication.
- Actors:
ANONYMOUS; any authenticated dataset actor. - Preconditions: Dataset actor has an accessible active dataset.
- Sequence: Open
/; anonymous user is sent to login; authenticated user reaches the parcel map; toolbar brand returns to the same map. - Outcome: No protected map data appears before authentication.
- Evidence:
EV-AUTH-HOMEprimary. - Risk: Medium user impact and authorization; P2, not selected as golden.
UJ-AUTH-002 — Successful and failed login¶
- Intent: Valid credentials establish a session; invalid credentials reveal no protected content.
- Actors:
ANONYMOUS, demonstrated withSUPERUSER. - Sequence: Submit valid and invalid credentials on the login surface.
- Outcome: Valid login reaches administration; invalid login shows a safe error and remains unauthenticated.
- Evidence:
EV-AUTH-LOGINprimary. - Risk: P2, not selected as golden.
UJ-ACCESS-001 — Switch active dataset¶
- Intent: A granted user can deliberately change active scope without data from the prior dataset leaking into the new view.
- Actors: Any dataset actor with grants on two active datasets.
- Preconditions: Isolated datasets A and B each contain identifiable parcels.
- Starting state: Dataset A is active and only A records are visible.
- Sequence: Login, select B from profile, return to parcel/map views, reload.
- Visible outcome: B is selected and only B content appears.
- Persisted outcome: Profile
active_dataset_idis B; parcel data is unchanged. - Unchanged state: Grants and parcel rows in both datasets remain unchanged.
- Audit/re-query: No workflow event is expected; a fresh request and browser reload both resolve B as the active scope.
- Authorization: A dataset without a grant cannot be selected.
- Evidence:
ACCESS-SWITCH-RELOAD; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Risk: High authorization; P1 golden.
UJ-ACCESS-002 — Cross-dataset non-disclosure¶
- Intent: Guessing a foreign UUID never reveals record existence or content.
- Actors: Each exact dataset role; anonymous and superuser controls.
- Preconditions: Actor can read dataset A but has no grant on B.
- Starting state: Dataset A is active; a known record exists only in B.
- Sequence: Open/list/API-read B identifiers while A is active.
- Visible outcome: Existing non-disclosure response; no B label, geometry, history, events, or validation detail.
- Persisted outcome: The denied read creates no persisted side effect.
- Unchanged state: Records, grants, active scope, and workflow events remain unchanged.
- Audit/re-query: Repeat the request after reload and through an independent query; the response remains non-disclosing.
- Authorization: Exact roles do not cross dataset boundaries; superuser status alone grants no dataset read.
- Evidence:
ACCESS-FOREIGN-DENIAL,ACCESS-ANONYMOUS-DENIAL; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Risk: High authorization and regression likelihood; P1 golden.
UJ-PARCEL-001 — View, search, map, and history¶
- Intent: Dataset readers can inspect scoped current parcels and history.
- Actors: Viewer, editor, reviewer, approver.
- Sequence: Open list/map/detail, search/filter, toggle surroundings/history, reload.
- Outcome: Shared workspace and overlays remain scoped and readable.
- Evidence:
EV-PARCEL-WORKSPACEprimary; scoping suites invariant. - Risk: P2, not selected as golden.
UJ-PARCEL-002 — Browser-based parcel authoring¶
- Intent: An exact editor can create or amend a parcel through the current draft-oriented browser workflow and recover from validation errors.
- Actors: Editor; viewer/reviewer/approver denial controls.
- Preconditions: Isolated dataset, eligible source and new-chain IDs.
- Required sequence: Open create/edit, draw or modify geometry, trigger and correct one validation error, save draft, reload and compare persisted storage-CRS geometry/attributes.
- Expected unchanged state: Official source remains unchanged before final approval.
- Evidence:
EV-PARCEL-AUTHORandEV-DRAFT-UIsupporting. - Gap:
PARTIAL_EVIDENCE; legacy browser authoring does not prove current exact-editor draft persistence. - Intended layer: Browser plus independent persisted-state query.
- Risk: P2 gap, not golden because the bounded P1 set is full.
UJ-PARCEL-003 — Approved parcel GeoPackage export and preview¶
- Intent: An editor can export filtered approved parcels in the storage CRS and return the package to ordinary upload analysis.
- Outcome: GPKG file has a valid SQLite signature; preview identifies it.
- Spatial boundary: Storage-CRS GPKG export; server reads declared CRS on re-upload.
- Evidence:
EV-PARCEL-EXPORTprimary. - Limitation: No external modification or draft update.
UJ-DRAFT-001 — Independent review and approval API workflow¶
- Intent: Public workflow endpoints complete an independently attributed approval and create an official version.
- Actors: Editor, distinct reviewer, distinct approver.
- Sequence: Create, submit, review accept, final approve, list events.
- Persisted outcome:
APPROVED, official version/event present. - Evidence:
EV-DRAFT-APIprimary;EV-DRAFT-SERVICEinvariant. - Risk: P1 behaviour, represented in the golden backlog by its missing
browser equivalent
UJ-DRAFT-002.
UJ-DRAFT-002 — Complete browser review and approval workflow¶
- Intent: Three people can complete the principal business workflow using the visible queue, detail, forms, confirmations, and feedback.
- Actors: Exact editor, independent reviewer, independent approver.
- Preconditions: Isolated source/current version and three sessions.
- Starting state: Eligible current source with no competing active proposal.
- Sequence: Editor creates/edits/submits; reviewer opens the submitted draft and accepts; approver opens the reviewed draft and approves; each reloads after its action. Queue navigation remains a separate companion control.
- Visible outcome: Controls follow current role/state and terminal approval receipt is visible.
- Persisted outcome: One official version plus complete actor, transition, and approval-event attribution.
- Unchanged state: Unrelated parcels and datasets remain unchanged; no new official successor exists before final approval.
- Audit/re-query: Reload after each role action and independently query the final draft, official version, and ordered events.
- Authorization: Read-only and wrong-stage roles cannot mutate; creator, submitter, and reviewer separation is enforced.
- Spatial boundary: Any edited browser geometry is transformed and validated at the server boundary, then persisted in the frozen storage CRS.
- Companion coverage:
UJ-DRAFT-001remains the public API control for the same lifecycle. - Evidence:
DRAFT-APPROVE-CHAIN; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Intended layer: Browser journey with independent persisted-state queries.
- Risk: High across all dimensions; P1 golden.
UJ-DRAFT-003 — Reject, correct, resubmit, and approve¶
- Intent: Review feedback leads to a corrected proposal without bypassing independent decisions.
- Actors: Editor, reviewer, approver.
- Preconditions: Isolated submitted draft, known original proposal, and distinct actor sessions.
- Starting state: Draft is
SUBMITTEDwith no official version created. - Sequence: Submit, reject with reason, return to the source and create a correction draft with a distinct draft ID on the same parcel/source chain, resubmit, independently accept/approve, and reload history. The rejected row remains terminal; no reopen transition is invented.
- Visible outcome: Rejection reason is visible to the editor; corrected values and later terminal approval are visible after reload.
- Persisted outcome: Final approved version reflects correction; rejection reason and all actors remain auditable.
- Unchanged state: No official version is created at rejection or resubmit.
- Audit/re-query: Original rejected draft/events and the new correction draft's create/submit/review/approve events survive reload and independent observation; both draft IDs and their shared parcel/source identity are checked.
- Authorization: Only an editor corrects/resubmits; independent reviewer and approver perform their exact-stage actions.
- Spatial boundary: A geometry correction, when present, is compared and persisted in the frozen storage CRS.
- Evidence:
DRAFT-REJECT-CORRECT-CHAIN; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Intended layer: Browser plus API/view and persisted-state assertions.
- Risk: High integrity and authorization; P1 golden.
UJ-DRAFT-004 — Two-editor collaboration and attribution¶
- Intent: One editor may create and another submit while history preserves both actors and decisions remain independent.
- Evidence:
EV-DRAFT-COLLABprimary. - Outcome: Distinct create/submit actor IDs and eventual approval.
- Risk: P2, not selected as golden.
UJ-DRAFT-005 — State-specific cancellation¶
- Intent: Contract roles can cancel active work with a persisted reason and no ownership requirement.
- Evidence:
EV-DRAFT-CANCELprimary. - Outcome:
CANCELLED, reason/actor audited, no official version. - Risk: P2, not selected as golden.
UJ-DRAFT-006 — Stale, revoked, and concurrent transition safety¶
- Intent: Long-lived pages and competing requests cannot use stale authority or produce duplicate/partial approval.
- Actors: Workflow actor whose grant/state changes; competing approvers.
- Preconditions: Isolated active draft, mutable grant, and two requests that can act from the same observed revision.
- Starting state: The action appears valid before a role or state change.
- Sequence: Render/prepare action, revoke grant or advance state, submit; issue competing approval attempts.
- Visible outcome: The stale or losing request receives a stable denial or conflict and can refresh to the authoritative state.
- Persisted outcome: Current locked decision wins; at most one transition; monotonic events; no partial version.
- Unchanged state: Denied requests create no duplicate official version, successful/terminal event, revision, or attribution change. Only the contract-defined sanitized denial event may be appended.
- Audit/re-query: Re-query under a fresh transaction and reload the page to confirm one terminal state and one complete event sequence.
- Authorization: Authority is re-evaluated while locked; revoked or wrong exact roles cannot complete the transition.
- Evidence:
DRAFT-STALE-ACTION,DRAFT-REVOKED-ACTION; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Risk: High integrity, authorization, regression; P1 golden.
UJ-EXCH-001 — Externally edited GeoPackage round trip¶
- Intent: An editor can take a draft offline, edit it in GIS, and safely return the edited proposal to the same workflow.
- Actors: Exact editor; optionally a different authorized importing editor.
- Preconditions: Isolated
DRAFT, known original storage geometry and attributes, projected editable package, unchanged selected revision. - Starting state: Eligible draft is
DRAFT; official source and unrelated records have known baseline hashes/values. - Sequence:
- Select and download Export drafts for editing.
- Modify target geometry and permitted attributes in the GeoPackage using a controlled test helper that preserves identity and CRS metadata.
- Upload through Import edited drafts and confirm the result.
- Reopen/reload the draft.
- Visible outcome: Import identifies the intended draft and reports success.
- Persisted outcome: Draft geometry/allowed values equal the imported values
after server transformation to the frozen storage CRS; revision advances;
state remains
DRAFT. - Unchanged state: Context/reference and unrelated drafts/parcels are unchanged; no official version is created.
- Audit: Offline-import event, importing actor, source CRS, resulting storage CRS, operation/result linkage.
- Reload/re-query: Reopen the draft and independently query its revision, geometry, attributes, events, and linked import result.
- Authorization: Only an exact authorized editor may import; reviewer, approver, viewer, anonymous, and superuser attempts create no mutation.
- Spatial boundary: The package carries an explicit projected source CRS; the server validates linear units and transformation, then compares and stores geometry in the frozen parcel storage CRS.
- Companion coverage:
UJ-EXCH-002supplies inspection-export permission and editing-import denial controls. - Failure variants: Stale revision, wrong purpose, duplicate import, invalid geometry, missing/geographic/non-transformable CRS, tampered identity, and multi-record rollback.
- Evidence:
EXCHANGE-EDIT-ROUNDTRIP,EXCHANGE-RECOVERABLE-ERROR; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Intended layer: Browser plus controlled GPKG modification and independent persisted-state assertions.
- Risk: High across all dimensions; P1 golden.
UJ-EXCH-002 — Inspection export and import denial¶
- Intent: Reviewer and approver can inspect projected geometry offline but cannot mutate drafts through inspection packages.
- Evidence:
EV-EXCH-VIEWSprimary;EV-EXCH-BROWSERsupporting. - Outcome: Inspection download allowed; editing import absent/403; no change.
UJ-EXCH-003 — GeoJSON and KML production import¶
- Disposition:
INTENTIONALLY_UNSUPPORTED. - Contract: The versioned import contract requires explicit projected CRS metadata with known linear units and valid transformation. GeoJSON and KML are export-only.
- Expected outcome: File import path rejects them before mutation and never guesses storage CRS.
UJ-UPLOAD-001 — Upload, preview, apply, and continue workflow¶
- Intent: An editor uploads a projected dataset, understands classifications, applies valid decisions, and continues created drafts.
- Actors: Exact editor; viewer, reviewer, approver, and superuser denial controls.
- Preconditions: Isolated GPKG/Shapefile with create, duplicate, conflict, and invalid records plus explicit projected CRS.
- Starting state: No upload/result rows or workflow drafts exist for the fixture file; official parcels have recorded baseline values.
- Sequence: Upload/analyse, inspect filtered preview, choose create-drafts, apply, open status, follow created draft, reload.
- Visible outcome: Preview classifications and validation errors are clear; status links each successful result to its created draft.
- Persisted outcome: Correct source/new-chain drafts, completed upload/result rows, source/storage CRS audit, no direct official mutation.
- Unchanged state: Duplicate/conflicted/invalid official records unchanged; reapply creates nothing.
- Audit/re-query: Reload preview/status and independently query upload, result, draft, and audit metadata after apply.
- Authorization: Only an exact editor can upload, inspect authoring preview, or apply decisions; denied actors create no file-backed or database state.
- Spatial boundary: Input must declare a projected CRS with known linear units and a valid transformation; persisted proposal geometry uses the frozen storage CRS.
- Companion coverage:
UJ-UPLOAD-002supplies stale/duplicate recovery andUJ-UPLOAD-003supplies exact-role denial controls. - Evidence:
UPLOAD-MIXED-APPLY-FOLLOWUP,UPLOAD-REPEAT-APPLY,UPLOAD-STALE-PREVIEW,UPLOAD-NONEDITOR-DENIAL; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Intended layer: Browser plus isolated file-backed fixture and independent persisted-state queries.
- Risk: High across all dimensions; P1 golden.
UJ-UPLOAD-002 — Invalid, stale, and duplicate upload recovery¶
- Intent: Repeated apply or stale preview fails safely and supports a clean retry.
- Evidence:
UPLOAD-REPEAT-APPLYandUPLOAD-STALE-PREVIEWprimary browser evidence;EV-UPLOAD-RECOVERYremains invariant evidence. - Outcome: Stable conflict/redirect, stale payload discarded, no duplicate drafts or partial apply.
UJ-UPLOAD-003 — Upload authoring role denial¶
- Intent: Read roles cannot inspect or submit upload-authoring forms.
- Evidence:
EV-UPLOAD-ROLEprimary for the lower-layer denial contract;UPLOAD-NONEDITOR-DENIALsupplies primary browser evidence, with retained upload controls supporting. - Outcome: Form absent or denied; direct request creates no upload/draft.
UJ-TOPO-001 — Atomic split through approval¶
- Intent: One official source becomes exactly two valid versioned outputs.
- Actors: Editor, independent reviewer, independent approver.
- Preconditions: Isolated current source, deterministic valid split line, no active ordinary/topology proposal, and three sessions.
- Starting state: One current source parcel with known geometry and history.
- Sequence: Create split, draw/update line, inspect output areas, reload, submit, review, approve.
- Visible outcome: Two output polygons and storage-CRS areas remain visible after reload; terminal receipt identifies the retired source and outputs.
- Persisted outcome: Source retired; two outputs, two lineage edges, one transaction and approval receipt.
- Unchanged state: No source retirement or output survives any failed step.
- Audit/re-query: Reload before submission and after approval; independently query request, outputs, lineage, transaction, and ordered events.
- Authorization: Exact editor creates/edits/submits; independent reviewer and approver act only at their stages; denied actions change nothing.
- Spatial boundary: Browser display line enters server boundary; split, areas, validity, overlap, and persistence use frozen storage CRS/PostGIS.
- Evidence:
TOPO-SPLIT-APPROVE; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Intended layer: Browser + API/view with isolated topology fixture and independent persisted-state queries.
- Risk: High integrity/authorization/regression; P1 golden.
UJ-TOPO-002 — Atomic edge-connected merge through approval¶
- Intent: Edge-connected current parcels become one output with complete many-to-one lineage.
- Actors: Editor, independent reviewer, independent approver.
- Preconditions: Isolated edge-connected current sources, valid donor, no competing proposal, and three sessions.
- Starting state: Every source is current with known geometry and no lineage edge to the proposed result.
- Sequence: Select sources/donor, create, inspect output, submit, review, approve, reload result.
- Visible outcome: Selected sources, donor-derived attributes, merged output, and terminal receipt remain consistent after reload.
- Persisted outcome: Every source retired; one valid output; lineage edge per source; one atomic transaction.
- Unchanged state: Output failure rolls back all retirements and lineage.
- Audit/re-query: Independently query all sources, output, lineage, transaction, and ordered events after reload.
- Authorization: Exact editor creates/submits; independent reviewer and approver act only at their stages; corner-only or foreign sources are denied.
- Spatial boundary: Connectivity, union, validity, area, overlap, and persistence are authoritative in frozen storage CRS/PostGIS.
- Evidence:
TOPO-MERGE-APPROVE,TOPO-MERGE-CORNER-DENIAL,TOPO-MERGE-FOREIGN-DENIAL; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Intended layer: API/view plus browser result inspection using isolated topology fixtures and persisted-state queries.
- Risk: High integrity/authorization/regression; P1 golden.
UJ-TOPO-003 — Corner-only merge rejection¶
- Intent: Parcels touching only at a point cannot create an invalid merge.
- Evidence:
TOPO-MERGE-CORNER-DENIALis primary browser evidence;EV-TOPO-GEOMETRYand the retained API companion remain invariant/supporting. - Outcome: Stable validation denial before request creation; sources remain current and unchanged.
- Disposition:
COVERED; the fixture-owned browser companion independently verifies that no request is created and source state is unchanged. - Intended layer: Browser and API/view with isolated topology fixtures and independent request/source-state queries.
UJ-TOPO-004 — Topology conflict and rollback safety¶
- Intent: Ordinary drafts, topology requests, grant changes, and output failures cannot produce competing or partial parcel versions.
- Actors: Exact workflow actors, a revoked actor, and competing request clients.
- Preconditions: Isolated current sources, controllable role/state changes, and an injectable output failure.
- Starting state: Sources are current and no successful competing proposal or output exists.
- Sequence: Create competing work, revoke role or introduce late conflict, submit/approve, inject output failure.
- Visible outcome: Losing/stale actions receive stable conflict or denial feedback and can refresh to the authoritative state.
- Persisted outcome: At most one competing creation succeeds; current grants are used; failed approval leaves sources, outputs, lineage, and events consistent.
- Unchanged state: Failed actions retire no source and persist no partial output, lineage, transaction, or terminal event.
- Audit/re-query: Re-query in a fresh transaction and reload the affected request to confirm one consistent state and event sequence.
- Authorization: Current exact roles and separation rules are rechecked while locked; revoked authority never survives from a stale page.
- Spatial boundary: Geometry validation and source/output conflict checks use the frozen storage CRS and database transaction boundaries.
- Evidence:
TOPO-LATE-CONFLICT-RECOVERY; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Risk: High integrity/authorization/regression; P1 golden.
UJ-OVERLAP-001 — Live overlap advisory before save¶
- Intent: An editor receives accessible, safe, current conflict evidence while drawing before workflow submission.
- Actors: Exact editor; inaccessible parcel owner/data as the non-disclosure control.
- Preconditions: Deterministic approved target and browser geometry with known material overlap.
- Starting state: Editable proposal has not been submitted and official parcel geometry is unchanged.
- Sequence: Draw/modify proposal, wait for advisory, inspect map/list feedback, correct geometry, retry.
- Visible outcome: Versioned safe evidence identifies the conflict without protected owner/geometry disclosure; corrected geometry clears it.
- Persisted outcome: Advisory requests create no official parcel mutation.
- Unchanged state: Target parcel, unrelated parcels, grants, and workflow state remain unchanged until an authorized save/submit.
- Audit/re-query: Re-run advisory after correction and reload the editor; responses refer to current target versions without creating workflow events.
- Authorization: Evidence is filtered to information the editor may know and never discloses protected owner or full geometry data.
- Spatial boundary: Browser proposal coordinates are transformed at the server boundary; material overlap is computed authoritatively in storage CRS.
- Evidence:
OVERLAP-ADVISORY-CORRECTION,OVERLAP-PROTECTED-DENIAL; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Intended layer: Browser with deterministic approved target and overlap geometry, plus API response assertions.
- Risk: High user impact, integrity, regression; P1 golden.
UJ-OVERLAP-002 — Authoritative overlap prevention¶
- Intent: Advisory UI cannot be bypassed to persist material current overlap.
- Actors: Workflow actors and direct-write control.
- Preconditions: Two isolated proposals compete for the same area and a direct insert can exercise the database backstop.
- Starting state: Existing current parcels satisfy overlap constraints.
- Sequence: Submit competing proposals and attempt direct overlapping write.
- Visible outcome: The losing workflow action receives a stable denial and remains recoverable rather than partially approved.
- Persisted outcome: Dataset lock serializes proposals; loser remains editable/denied; PostGIS constraint rejects direct overlap.
- Unchanged state: Failed submit/write creates no current overlapping parcel, retirement, approval, or partial event.
- Audit/re-query: Query under a fresh transaction and reload both proposals to confirm one reservation and the denied proposal's consistent state.
- Authorization: Only the exact workflow role can attempt its transition; the database backstop applies regardless of application entry point.
- Spatial boundary: Material overlap and constraint enforcement use authoritative storage-CRS PostGIS geometry.
- Evidence:
OVERLAP-LOSING-SUBMIT; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Risk: High data integrity/regression; P1 golden.
UJ-SNAP-001 — Snap settings persist and propagate¶
- Intent: Authenticated users control independent snap modes and limits once, and every supported editor consumes them without duplicate panels.
- Evidence:
EV-SNAP-SETTINGSprimary. - Outcome: Settings survive reload and remain user-isolated; viewer settings do not grant editor authority.
UJ-SNAP-002 — Snap, trace, save, and workflow revalidation¶
- Intent: Browser snapping convenience produces exactly reproducible authoritative geometry throughout approval.
- Actors: Editor, independent reviewer, independent approver.
- Preconditions: Isolated editable proposal, visible eligible target versions, deterministic point/edge/trace coordinates, and three sessions.
- Starting state: Proposal is editable; target versions and snap settings have recorded baselines.
- Sequence: Enable settings, snap point/edge, optionally trace a boundary, save draft, submit, review, approve, reload.
- Visible outcome: Snap indicators and resulting proposal geometry remain consistent after save/reload; stale targets produce actionable denial.
- Persisted outcome: Server substitutes exact storage coordinates, stores provenance, and creates approved storage-CRS geometry.
- Unchanged state: Eligible target parcels are never modified; stale or unauthorized attempts preserve draft and official state.
- Audit/re-query: Independently query stored geometry, target/version provenance, workflow events, and final official version after reload.
- Authorization: Only an exact editor authors/submits; independent reviewer and approver decide; inaccessible targets cannot be used or disclosed.
- Spatial boundary: Browser display coordinates are hints only. PostGIS resolves authoritative storage-CRS candidates, trace paths, validation, and persistence.
- Failure variant: Supersede/restrict target after save; submit/approve fails closed and preserves draft/official state.
- Evidence:
SNAP-POINT-EDGE-TRACE-APPROVE,SNAP-STALE-TARGET,SNAP-INACCESSIBLE-TARGET; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Intended layer: Browser gestures plus API/view and independent storage-geometry assertions.
- Risk: High integrity/authorization/regression; P1 golden.
UJ-BASEMAP-001 — Basemap choice inheritance and fallback¶
- Intent: One preferred background follows the user across supported maps; rejected providers fall back without silently changing preference or controls.
- Evidence:
EV-BASEMAP-USERprimary under deterministic controlled provider/style/resource responses. - Disposition:
COVEREDfor choice, inheritance and rejection fallback; live external-provider availability remains separate owner acceptance. - Intended layer: Browser with deterministic intercepted provider responses.
- Risk: P2, not golden.
UJ-BASEMAP-002 — Superuser basemap catalogue administration¶
- Intent: A system administrator selects the available subset and valid default atomically.
- Evidence:
EV-BASEMAP-ADMINprimary. - Outcome: Default belongs to selected subset; non-admin mutation denied.
UJ-ROLE-001 — Exact role and separation-of-duties boundaries¶
- Intent: Every mutation is authorized by the actor's exact grant and an independent decision history, not role rank or hidden controls.
- Actors: Viewer, editor, reviewer, approver, multi-role actors.
- Preconditions: Isolated dataset, one exact-role session per actor, one declared multi-role session, and eligible ordinary/topology work.
- Starting state: Controls and workflow state are known before any direct or crafted request.
- Sequence: Inspect controls, craft direct requests for absent actions, create/submit with multi-role actor, attempt self-review/self-approval, then complete with independent actors.
- Visible outcome: Only exact-stage controls appear; crafted denied requests return stable non-disclosing or forbidden responses.
- Persisted outcome: Denied attempts change nothing and are safely audited; independent actions preserve attribution.
- Unchanged state: Wrong-role and self-decision attempts create no state transition, official version, topology output, or unauthorized grant.
- Audit/re-query: Reload each actor's view and independently query state and events to confirm only permitted actors appear.
- Authorization: Higher role names imply no lower mutation role; multi-role grants do not bypass creator/submitter/reviewer separation.
- Evidence:
ROLE-EXACT-STAGES,ROLE-MULTI-ACTOR-SEPARATION; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Risk: High across all dimensions; P1 golden.
UJ-ROLE-002 — Superuser administration without workflow authority¶
- Intent: The system administrator can manage Django administration but cannot read or mutate dataset workflow merely through superuser status.
- Actors:
SUPERUSER; one exact dataset actor as a positive control. - Preconditions: Superuser has Django admin access but no dataset grant; isolated dataset and eligible workflow routes exist.
- Starting state: Administrative access is available and dataset workflow is not granted.
- Sequence: Login to admin, inspect the allowed administrative surface, open dataset map/workflow and craft mutation.
- Visible outcome: Admin succeeds; dataset workflow access/actions remain absent or denied with no mutation.
- Persisted outcome: No dataset grant or workflow mutation is created implicitly; denied actions preserve domain state. This browser case does not exercise an administrative write.
- Unchanged state: Parcel, draft, topology, upload, and workflow event rows remain unchanged after denied dataset actions.
- Audit/re-query: Reload admin and dataset routes, then independently verify no dataset grant or workflow event was created.
- Authorization:
SUPERUSERis the system-administrator persona, not a dataset role and not a separate dataset-administrator boundary. - Evidence:
ROLE-ADMIN-WITHOUT-GRANTS; primary browser evidence with independent observations. Retained controls are mapped above. - Disposition:
COVERED; required browser cases and supporting invariants prove the documented boundary. - Risk: High authorization/regression; P1 golden.
Maintenance and traceability¶
For every golden ID, the journey index links to its canonical definition; the evidence mapping states current proof and limitations; the coverage views state the remaining gap. Operational fixture details link to Playwright E2E coverage, and public live evidence links to demo environment acceptance testing.
When behaviour or evidence changes, follow the maintenance workflow in the testing strategy. Do not update a disposition until the cited evidence resolves and proves the complete documented behaviour.
Precision coordinate evidence¶
These mandatory Chromium/Firefox obligations are additional evidence IDs, not new golden journeys. Both are covered by the complete default run in each required browser, including independently observed persisted geometry. The same marker-count, strict less-than-two-pixel map-layer displacement and strict 0.02 m stored-versus-dragged coordinate bounds remain in force. Persistence correctness and rendered performance are separate gates, with current outcomes and limitations recorded in the operational coverage guide.
| Evidence | Exact locator | Assertion boundary |
|---|---|---|
PRECISION-PARCEL-APPLY-DRAG-SAVE |
tests/e2e/precision-coordinates.spec.ts::PRECISION-PARCEL-APPLY-DRAG-SAVE |
Coordinate dialog Apply, subsequent actual pointer drag, normal draft save/reload and independently observed final storage geometry; stale applied coordinates must not overwrite the dragged position |
PRECISION-SPLIT-APPLY-DRAG-SAVE |
tests/e2e/precision-coordinates.spec.ts::PRECISION-SPLIT-APPLY-DRAG-SAVE |
Split-line coordinate Apply, actual drag, normal line save/reload and independent stored line/output comparison |
tests/e2e/precision-coordinates.spec.ts::applyPrecisionOffset drives the real
coordinate dialog. Read-only map projection/handle observations in
tests/e2e/fixtures/map-gestures.ts place actual pointer events; they do not
replace persistence assertions with screen geometry. Retained precision
companions cover preference visibility, ordinary-field shortcuts, read-only
mutation denial, vertex controls, cancellation and deferred split-line save.
Their precise COMP-PRECISION-* locators remain in the scenario registry.