3.8 KiB
3.8 KiB
Architecture
Process Model
ImEX RPS has two main runtimes:
- Electron main process: window lifecycle, native menus, file system access, estimate decoding, file watching/scanning, audit file dialogs, updater, app-level settings, analytics, and IPC.
- React renderer process: UI, routing, Redux state, Apollo GraphQL operations, Firebase auth, and renderer-side IPC listeners.
The renderer does not get Node integration. The preload script exposes a controlled bridge:
window.ipcRenderer.send(channel, data)window.ipcRenderer.on(channel, handler)window.ipcRenderer.invoke(channel, data)window.ipcRenderer.removeAllListeners(...)window.logger.*
Entrypoints
Electron:
electron/main.jsdecides whether to run the source main file or bundleddist-electron/main.cjs.electron/main-src.jsis the main source file.electron/preload.jsdecides whether to run the source preload or bundleddist-electron/preload.cjs.electron/preload-src.jsexposes IPC/logger bridges.scripts/build-electron.mjsbundles main/preload outputs.
Renderer:
src/index.jsxinitializes Sentry renderer, Redux Provider,MemoryRouter,PersistGate, and<App />.src/App/App.jsxinitializes Apollo, AntD context/theme, auth session check, IPC side effects, and authorized/unauthorized routing.src/components/pages/routes/routes.page.jsxrenders the main app shell and routes.
Routing
Routes are memory-router routes because this is an Electron app:
/Jobs/settingsSettings/reportingReporting/auditAudit/scanScan/adminAdmin
The app shell includes the side menu, notifications modal, release notes, and update manager.
Redux Shape
Store setup:
src/redux/store.js- Redux core
legacy_createStore - Saga middleware
- Redux logger in development
- Redux DevTools compose if present
- redux-persist wrapper with all active reducers currently blacklisted
Reducers:
application: watcher status, watched paths, selected job id, selected target percent, settings, update state, release notes, estimate scrubber results.user: current user, bodyshop, targets, fingerprint, auth errors, notifications, dark mode.reporting: report date range, report rows, scorecard, audit data/errors/loading, excluded ids, cached jobs.scan: scan loading state, last scanned, estimate list.
Sagas:
applicationSagasuserSagasreportingSagasscanSagas
Data Flow for Estimate Import
- User configures
filePathsin settings. - Electron store persists those paths.
electron/file-watcher/file-watcher.jswatches paths with chokidar.- New/changed estimate files are decoded by
electron/decoder/decoder.js. - Main process sends decoded payloads over IPC.
- Renderer
src/ipc/ipc-renderer-handler.jsreceives decoded estimates. - Renderer GraphQL helper
UpsertEstimatewrites jobs/joblines to Hasura. - Jobs UI queries data back through Apollo.
Data Flow for Job Details
- A list item dispatches selected job id to Redux
application. jobs-detail.organism.jsxdebounces selected id briefly to avoid rendering a stale/partial left panel.- Apollo queries
QUERY_JOB_BY_PK. - Detail subcomponents render job metadata, joblines, targets, group controls, claims clerk, estimate scrubber, and other actions.
IPC Contract
IPC channel names live in src/ipc.types.json, imported by:
src/ipc.types.jsfor ESM renderer code.src/ipc.types.commonjs.jsfor CommonJS Electron code.
When adding IPC:
- Add channel names to
src/ipc.types.json. - Register main handlers in the relevant Electron module.
- Register renderer listeners in
src/ipc/ipc-renderer-handler.jsor a local component effect. - Keep handlers idempotent when possible; repeated imports/listeners can create duplicate events.