AquaGen Labs
Water-quality lab reports: upload a report (PDF, image, CSV, or Excel) for a facility, and the page shows a 12-month trend per parameter plus a month-by-month repository of the uploaded files.
- Route:
/labs→AquagenLabsPage(libs/aquagenLabs/src/AquagenLabsPage.jsx) — registered in the production and demo apps - Permission:
NLABS(gates the embedded Quality tab; the/labsroute itself is unguarded — see Access & visibility) - Library:
libs/aquagenLabs/— standarddataSource → controller → store → componentslayering
The same components + store appear as a "Lab Reports" tab inside
Water Quality, gated by NLABS with ignoreSuperUser
(super users don't auto-pass).
It's a lab-report viewer/uploader — not a full LIMS. No test scheduling, chain-of-custody, approvals, or certificate generation exist in the code.
Two views + upload
Toggle between Overview and Past Reports; upload from the header.
| View / action | Component | Shows | On click |
|---|---|---|---|
| Overview | LabsReportOverview | Per-unit tabs; each parameter row has a 12-month trend (Recharts) with threshold reference lines + an Acceptable Range | Switch unit tabs; the year picker refetches |
| Past Reports | LabsReportViewer | The uploaded report files for a selected month (filename + upload time) | Download icon → opens the file in a new tab |
| New Report | LabsReportUpload | Upload dialog: report date, a digital/manual toggle, a click-or-drag file drop-zone | Upload → POST, refresh overview, auto-close after 2s |
The Overview year picker (store
selectedDate) and the Past-Reports month picker (local page state) are independent.
APIs
Three endpoints (dataSource/aquagenLabsDataSource.js):
| Action | Method | Path | Params |
|---|---|---|---|
| Overview trends | GET | /deviceDataV2 | date1 (year), category: QUALITY_DATA_EXTRACTION, divisionFactor: 1, type: YEAR |
| List a month's reports | GET | /dataExtraction/reports | year, month |
| Upload a report | POST (multipart) | dataExtraction/ | file field file; query manualEntry, date, time |
The Overview trends come from /deviceDataV2 (device readings), not the
dataExtraction report files — only the list and upload use dataExtraction/.
There is no delete endpoint.
Overview response shape
{
subCategories: [{ // only subCategories[0] is read
units: [{
unitId, displayName, key,
meta: { params: ['pH','TDS'], siUnit, min, max, lowThreshold, highThreshold },
graph: [{ x2: 'Jan', y: { pH: 7.1, TDS: 440 } }, /* …up to 12 months */ ],
value: { pH: 7.2, TDS: 450 },
}],
}],
}
The report list returns { files: [{ filePath, downloadUrl, lastModified }] }.
State (AquagenLabsStore)
A React Context (AquagenLabsStoreContextProvider) exposing aquaLabsData,
error, selectedDate / setSelectedDate, and fetchAquaLabsData (also called
after an upload). Mounted by the page and, separately, by the Quality tab. See
State Management and
API Call Flow.
Access & visibility
| Layer | Rule |
|---|---|
/labs route | Unguarded — mounts AquagenLabsPage directly (no PermissionWrapper) |
| Sidebar entry | isDemoOption: true → the standalone entry appears only in the demo build; access: open skips the permission check |
| Quality "Lab Reports" tab | NLABS required with ignoreSuperUser — super users don't auto-pass |
| Feature-locked catalog | Listed as a marketing/locked feature for users without the product |
Edge cases & guards
| Area | Handling |
|---|---|
| Overview loading / empty | "Loading water quality data…" → "No parameter data available" |
| Malformed units / null points | Units without meta.params are dropped; null graph points filtered before charting |
| Missing thresholds | Range derived defensively (low–high, < high, 1–14 for pH, else -) |
| Upload validation | MIME allow-list (PDF / JPG / PNG / CSV / Excel); no file-size check |
| Upload result | Spinner while uploading; success Alert + auto-close; errors surfaced inline |
| Past Reports states | Loading spinner · error alert · "No reports found for this month" |
| Object URLs | Preview object URLs revoked on unmount |
Harmless copy quirks: the submit error says "select a PDF" though CSV/Excel/ images are valid;
manualEntryis inverted ('false'= digital); every report row shows a PDF icon regardless of the real file type.
Underlying libraries
| Purpose | Library |
|---|---|
| Trend charts | recharts |
| Dates / pickers | moment, CustomSingleDatePicker |
| Icons | @mui/icons-material, @iconify/react |
| Upload / preview | native browser APIs (FormData, <input type="file">, <iframe> / <img>) — no upload or PDF library |
Code reference
| File | Role |
|---|---|
AquagenLabsPage.jsx | Page shell + Overview/Past-Reports toggle |
components/LabsReportOverview.jsx | Per-unit parameter table + 12-month trend |
components/LabsReportUpload.jsx | Upload dialog (file picker + drag/drop) |
components/LabsReportViewer.jsx | Monthly uploaded-file list (download) |
store/AquagenLabsStore.js | Context store; overview fetch |
controller/aquagenLabsController.js · dataSource/aquagenLabsDataSource.js | Controller + API calls |
Related
- Water Quality Monitoring — hosts the embedded "Lab Reports" tab
- Permissions —
NLABS,PermissionWrapper,ignoreSuperUser - Application Routes · API Call Flow