104 lines
3.8 KiB
Markdown
104 lines
3.8 KiB
Markdown
# 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.js` decides whether to run the source main file or bundled `dist-electron/main.cjs`.
|
|
- `electron/main-src.js` is the main source file.
|
|
- `electron/preload.js` decides whether to run the source preload or bundled `dist-electron/preload.cjs`.
|
|
- `electron/preload-src.js` exposes IPC/logger bridges.
|
|
- `scripts/build-electron.mjs` bundles main/preload outputs.
|
|
|
|
Renderer:
|
|
|
|
- `src/index.jsx` initializes Sentry renderer, Redux Provider, `MemoryRouter`, `PersistGate`, and `<App />`.
|
|
- `src/App/App.jsx` initializes Apollo, AntD context/theme, auth session check, IPC side effects, and authorized/unauthorized routing.
|
|
- `src/components/pages/routes/routes.page.jsx` renders the main app shell and routes.
|
|
|
|
## Routing
|
|
|
|
Routes are memory-router routes because this is an Electron app:
|
|
|
|
- `/` Jobs
|
|
- `/settings` Settings
|
|
- `/reporting` Reporting
|
|
- `/audit` Audit
|
|
- `/scan` Scan
|
|
- `/admin` Admin
|
|
|
|
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:
|
|
|
|
- `applicationSagas`
|
|
- `userSagas`
|
|
- `reportingSagas`
|
|
- `scanSagas`
|
|
|
|
## Data Flow for Estimate Import
|
|
|
|
1. User configures `filePaths` in settings.
|
|
2. Electron store persists those paths.
|
|
3. `electron/file-watcher/file-watcher.js` watches paths with chokidar.
|
|
4. New/changed estimate files are decoded by `electron/decoder/decoder.js`.
|
|
5. Main process sends decoded payloads over IPC.
|
|
6. Renderer `src/ipc/ipc-renderer-handler.js` receives decoded estimates.
|
|
7. Renderer GraphQL helper `UpsertEstimate` writes jobs/joblines to Hasura.
|
|
8. Jobs UI queries data back through Apollo.
|
|
|
|
## Data Flow for Job Details
|
|
|
|
1. A list item dispatches selected job id to Redux `application`.
|
|
2. `jobs-detail.organism.jsx` debounces selected id briefly to avoid rendering a stale/partial left panel.
|
|
3. Apollo queries `QUERY_JOB_BY_PK`.
|
|
4. 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.js` for ESM renderer code.
|
|
- `src/ipc.types.commonjs.js` for 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.js` or a local component effect.
|
|
- Keep handlers idempotent when possible; repeated imports/listeners can create duplicate events.
|
|
|