Skip to content

PEACH Integration

Quinn Hanson edited this page Jun 25, 2025 · 10 revisions

PCNS ↔ PEACH Integration Designs

This living document is the single home for all design work that connects the Permit Connect Navigator Service (PCNS) to the Permitting Exchange, Aggregation & Collection Hub (PEACH). Each integration feature is documented within the Design Modules section.


Table of Contents


Guiding Design Principles

  1. Authoritative Data - PEACH remains the single source of truth for permit information; PCNS only transforms for display.
  2. Server Side Transformation - All PEACH payloads are handled in the PCNS backend.
  3. Minimise Coupling - Future PEACH contract changes are isolated to a single service.
  4. Stateless Frontend - The UI never calls PEACH directly, preventing CORS, auth, and version issues.
  5. Extensibility - Each integration capability (e.g., Process Events, Record Linkage) lives in its own section under this hub document.
  6. Adhere to Existing Convetntions - Use existing PCNS API architectural conventions (Router → Controller → Services) and reuse the established axios pattern for third party API calls.

Design Modules

Process Event Set Parsing

Background & Goals

PCNS must display up-to-date permit lifecycle information drawn from PEACH Process Event Sets. A Process Event Set groups all application process codes (e.g., Pre-Application, Referral, Decision) for a single permit record.

The goals of this design are:

  • Automate tracker updates so that staff are not manually reconciling data.
  • Parse the raw PIES payload into a minimal object that the PCNS front-end can consume efficiently.

Executive Level Changes

  • No PEACH calls from the browser. Introduce a dedicated PeachProcessEventService in the PCNS back-end.
  • New PCNS Endpoint - GET peach/process/:recordId with optional system_id query param.
  • Parser - Converts raw ProcessEventSet to a compact summary DTO for the UI.

Architecture

graph LR
    UI["PCNS UI"] <-- GET peach/process-events --> Router["PeachProcessEvent Router"]
    Router <--> Controller["PeachProcessEvent Controller"]
    Controller <--> Service["PeachProcessEvent Service"]
    Service <-- "HTTP GET /process-events" --> PEACH["PEACH API"]
Loading

Flow description - The UI requests data from PCNS. The backend fetches from PEACH, parses, and returns DTO to the UI.

Detailed Design

API Layer

Method Path Purpose
GET peach/process/:recordId Authenticate and validate params / query. Return parsed process event summary for a given record. Accepts optional system_id to disambiguate 409 conflicts.
Query Parameters
  • system_id - optional string; recommended for clients that already know their LoB source system identifier.
Responses
  • 200 OK - Body contains ProcessEventSummary.
  • 404 Not Found - Record not found in PEACH.
  • 409 Conflict - Multiple records share record_id; client must retry with system_id.

Controller Layer

ProcessEventController.getProcessEventSet(req, res)

  1. Invoke peachProcessEventService.fetchProcessEvents(recordId, systemId?).
  2. Parse and return DTO.
  3. Handle and map PEACH error codes to PCNS error schema.
Process Event Parser

Input: Raw ProcessEventSet payload from PEACH. Output: ProcessEventSummary DTO

Rules/Steps:

  1. Sort process events in process event set by event.start_datetime || event.start_date or event.start_datetime || event.start_date if applicable.
  2. TODO: More logic/sorting for isolating most recent/accurate process event beyond dates will likely be needed
  3. “Current stage and status” is the "last/assigned" event in the sorted/transformed list.
  4. Build ts object to reflect defined type to be passed to UI (TODO: type not yet formalized)
type ProcessEventsSummary {
  recordId: string;
  systemId: string;
  stage: string;
  status: string;
  statusLastVerified: string;
  stageLastVerified: string;
}

Service Layer

PeachProcessEventService

Isolate all PEACH communication.

fetchProcessEvents(recordId, systemId?) - Returns raw ProcessEventSet JSON from PEACH, using axios.

Data Model

No relational changes.

Front-End Integration

  • Replace existing mock tracker data with a call to /records/:recordId/events.
  • Display Current Phase prominently.
  • Render timeline as a vertical stepper (component already exists) using start → end.
  • If API returns 202, show loading shimmer; retry after 2 s (max 5 attempts).

Error Handling  &  Retry Strategy

  • PEACH 409 - Controller forwards as 409; UI prompts user to retry with specific system_id.
  • Network / 5xx - Controller responds 503.

Configuration & Deployment

  • PEACH_API_BASE_URL - e.g. https://<PEACH_API_URL_TBD>/api/v1.
  • PEACH_CLIENT_ID / PEACH_CLIENT_SECRET - Injected by OpenShift secret.

Risks & Mitigations

  • PEACH schema drift - Mitigated by single parsing service; update parser only.
  • Rate limiting - Adopt conservative polling, (optional) implement a cache.

Open Questions & Future Work

  1. Do we need to persist any data in PCNS DB for analytics?
  2. Should we utilize an in memory cache to hold commonly fetched PEACH data and expose a POST peach/process/:recordId/refresh for refreshing cache?
  3. Confirm final UI tracker/timeline design.

Clone this wiki locally