-
Notifications
You must be signed in to change notification settings - Fork 0
PEACH Integration
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.
- Guiding Principles
-
Design Modules
-
Record Parsing
- Background & Goals
- Executive Level Changes
- Architecture
- Detailed Design
- Error Handling
- (reserved for future features)
-
Record Parsing
- Configuration & Deployment
- Risks & Mitigations
- Open Questions & Future Work
- Authoritative Data - PEACH remains the single source of truth for permit information; PCNS only transforms for display.
- Server Side Transformation - All PEACH payloads are handled in the PCNS backend.
- Minimise Coupling - Future PEACH contract changes are isolated to a single service.
- Stateless Frontend - The UI never calls PEACH directly, preventing CORS, auth, and version issues.
- Extensibility - Each integration capability (e.g., Process Events, Record Linkage) lives in its own section under this hub document.
-
Adhere to Existing Convetntions - Use existing PCNS API architectural conventions (Router → Controller → Services) and reuse the established
axiospattern for third party API calls.
IMPORTANT: PCNS uses the Typscript types defined by PEACH in the backend peach layers and the PCNS file "re-defining" them will have to be updated when type/element changes are made to PEACH/PIES.
PCNS must display up-to-date permit lifecycle information drawn from PIES Records stored in PEACH. A Record groups authorization application events and process codes (e.g., Pre-Application, Referral, Decision) from a source system. One or more Records may be needed to be parsed to create complete tracking data for one authentication. (Note: Currently a record represents an entire authrorization of the associated record_id. This could be changed with upcoming Record Linkage changes.)
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 can be used to update PCNS DB.
-
New PCNS Endpoint
POST peach/record- This is a fetching endpoint coupled with a body (hence the post) that has permit tracking info to be used to call PEACH through PCNS' API and get up to date PEACH information for given tracking information. - No direct PEACH API calls from the frontend.
- PEACH Sync entry point and Cron Job - A PCNS pod "copy" to allow a CRON scheduled job to execute a script for syncing of PEACH data to PCNS.
- New PEACH route, controller, and service layer - Route to allow frontend to fetch PEACH data through PCNS, controller to facilitate new route and PEACH data syncing, service layer to connect to PEACH API.
-
Parser - Converts raw PIES
Recorddata from PEACH into status tracking data for a PCNS authorization.
graph LR
OpenShiftCronjob["CronJob"] -- run peachSync.ts --> Entrypoint["Entrypoint \n peachSync.ts"]
Entrypoint --> Controller["Controller \n peach.ts"]
Controller <--> PeachService["Service \n peach.ts"]
PeachService <-- HTTP GET peach/api/records --> PEACH["PEACH API"]
Controller --> PermitService["Service \n permit.ts"]
PermitService --> DB["PCNS DB"]
Frontend <-- POST pcns/peach/record --> Router[Router \n peach.ts]
Router <--> Controller
Controller <--> Parser["Parser \n peach.ts"]
Flow description - The CronJob calls peachSync.ts entry point script triggering the backend to fetch needed data from PEACH API, parse, and update PCNS DB Permit and Permit Treacking tables.
| Method | Path | Purpose |
|---|---|---|
POST |
peach/record |
A fetching endpoint. Allows frontend to fetch PEACH status data for immediate status updates in the frontend. |
-
200- Found and status data returned -
401- Unauthorized. -
420- Record not found. -
500- Internal Server Error.
findPriorityPermitTracking: Used to find the permit tracking with the highest priority to use for fetching most up to date PEACH data. (Note: this is in lieu of combining records to make one true sorce which was the original intention of PIES/PEACH. This may change with future versions of PEACH)
getPeachSummaryController: Calls PEACH API to get up to date status data and uses peachParser.ts to get a usable data format to return to frontend.
syncPeachRecords(req, res):
- Invokes Peach Service Layer function
getRecords().- If any PEACH error codes catch and throw as a PCNS Problem.
- Passes data to parser.
- Iterates through parser results to check differential and call Permit Service Layer
upsertPermit
Input: Raw PIES Records from PEACH API - PiesRecord[].
Output: parsedRecords: Record<string, PeachSummary> - Where the key is a concatination of the PiesRecord's record_id + system_id
PeachSummary - Is an interface that contains all needed status data parsed from the PIES Record
Rules/Steps:
Iterate through each given PIES Record and do the following:
- Sort the items in the Record's event sets (
process_event_setand/oron_hold_event_set) by the event'sstart_datetimeorevent.start_date. - Generate status data using the most recent process event or on hold event. The latest item is always used for status data, unless:
- The most recent item is an on hold event and it has an
end_datetimeorend_datethen the process event will be used. - The most recent item is an on hold event and the reason for the on hold is NOT missing information (
MISSING_INFORMATION). (*Note: This may be temporary depending on if PCNS decides to handle more on hold reasons)
- The most recent item is an on hold event and it has an
- Build
PeachSummaryobject(s) to reflect the status of the permits to be passed to PCNS DB.
Note: More logic/sorting for isolating/setting most recent/accurate process event beyond dates may be needed in the future.
Isolate PEACH api call(s).
getRecord(recordId, sourceSystemId?) - Returns a raw Record JSON from PEACH, using Axios.
No relational changes. Peach sync and parsing will intigrate into PCNS' data model so that non PEACH integrate permit types won't be affected.
- Continue to get tracking data with same service calls - no change.
- Prop side - Display Current Phase/Stage/Status in Tracker UI - no change.
- Prop side - Render timeline/tracker (component already exists - new design coming) - no change.
- Nav side - Grey out tracking fields for all PEACH integrated Permit types authorizations.
- Nav side - Trigger one time PEACH update for adding new authorizations on "Automate & Publish" button click. If no data return display popup message.
All errors from PEACH will be converted to a PCNS Problem
Will be deployed onto Openshift, simple CronJob to run peach sync script/entrypoint, described above.
ENV Variables/Secrets:
-
SERVER_PEACH_APIPATH- URL for PEACH API e.g.https://<AZURE_PEACH_API_URL>/api/v1. -
SERVER_PEACH_TOKENURL- Token url for keycloak. -
SERVER_PEACH_CLIENTID- Keycloak provide client id from PEACH. -
SERVER_PEACH_CLIENTSECRET- Keycloak provide client secret from PEACH.
- PEACH schema drift - Mitigated by single parsing service; update parser only.
- Rate limiting - Implement simple change detection in controller.
-
Do we need to persist any data in PCNS DB?Yes, for now until PEACH evolves -
Should we utilize an in memory cache to hold commonly fetched PEACH data and expose aCronJob to trigger script/entrypoint that updates PCNS DBPOST peach/process/:recordId/refreshor some kind of cronjob/scheduling for refreshing cache? -
Confirm final UI tracker/timeline design.Done
Currently, the PCNS ↔ PEACH integration is explicitly scoped to the Water and Lands business domains. Extending this integration to support additional domains will require updates in both backend and frontend. Changes include, but are not limited to:
-
Tracking ID Prioritization: The
findPriorityPermitTrackingfunction dictates which permit tracking ID is used to fetch the most up to date PEACH data. Different business domains may need different prioritization logic. At a bare minimum, any new domain's tracking IDs must be appended to thePEACH_TRACKING_PRIORITYconstant within the PEACH Controller to be utilizzed by the sync function. -
Source System Kinds: The
source_system_kinddatabase table will have to setintegratedfield totruefor all the corresponding row(s) for the new business domain tracking IDs. - Frontend Refactoring: The current UI implementation relies on specific components, props, local states, and constants tailored the current integrated business domains. Introducing a new domain requires evaluating and potentially refactoring these frontend elements to handle conditional rendering, new status types, and appropriate field-locking mechanisms.
Table of Contents
-
Software Design
-
Developer Resources
-
Product Roadmap