Specification — Visits and Water Measurements in Poolia
1. Objective
Capture operational pool inspections in Poolia through a combination of:
- visit records;
- water measurement records;
- a combined pool-specific creation flow that stores both together.
This design separates raw measured values from the operational visit record while still supporting a convenient frontend workflow for technicians.
2. Functional Approach
The domain is split into two related collections:
poolValuesvisits
Core idea
A PoolValues document stores measured water data such as:
- pH
- chlorine
- temperature
- boolean water status
A Visit document stores the inspection event itself, including:
- technician
- pool
- reference to the water values
- operational status
- actions
- problem description
- observations
The backend also exposes a higher-level endpoint that creates both records together for a specific pool.
3. Data Design
3.1. PoolValues
Represents raw water measurements.
Main fields
poolIdphchlorinetemperatureisOkcreatedAt
Purpose
This entity is useful both for visit-linked measurements and for historical metric analysis.
3.2. Visit
Represents the operational visit itself.
Main fields
datetechnicianIdpoolIdpoolValueIdisPoolOkisOkactionsproblemstatusobservations
Visit status
Allowed values are:
pendingin_progressresolved
4. Combined Visit Creation Logic
The most important workflow in this domain is:
POST /pools/{poolId}/visits
This endpoint creates a pool-specific visit together with its water values.
Validation rules
- the pool must exist;
- the technician must exist;
- the technician must have role
technician; - the technician must already be assigned to the pool.
Additional payload rule
If isOk is false, then problem is required.
This validation is implemented at the schema level for CreatePoolVisitRequest.
5. REST Endpoints
5.1. Generic PoolValues CRUD
Create values
POST /pool-values
Creates a PoolValues document directly.
List values
GET /pool-values
Returns all measurement documents.
Get values by id
GET /pool-values/{pool_values_id}
Returns one PoolValues document.
Update values
PATCH /pool-values/{pool_values_id}
Applies partial updates.
Delete values
DELETE /pool-values/{pool_values_id}
Deletes the document.
5.2. Generic Visit CRUD
Create visit
POST /visits
Creates a visit directly from a VisitCreate payload.
List visits
GET /visits
Returns all visits.
Get visit by id
GET /visits/{visit_id}
Returns one visit or 404.
Update visit
PATCH /visits/{visit_id}
Applies partial updates.
Delete visit
DELETE /visits/{visit_id}
Deletes the visit.
5.3. Pool-specific combined visit flow
Create pool visit with values
POST /pools/{poolId}/visits
Request body
{
"technicianId": "technician-id",
"ph": 7.2,
"chlorine": 1.5,
"temperature": 26.4,
"isOk": true,
"actions": "Adjusted chlorine dosage",
"problem": null,
"status": "pending",
"observations": "Water clear and stable"
}
Behavior
- validates pool existence;
- validates technician existence and role;
- validates technician assignment to the pool;
- creates a
PoolValuesrecord; - creates a
Visitrecord linked to the measurement; - returns both objects together.
Response shape
{
"poolValue": { "...": "..." },
"visit": { "...": "..." }
}
List pool visits
GET /pools/{poolId}/visits
Returns all visits for a pool after validating that the pool exists.
6. Business Logic Summary
Direct values CRUD
The pool-values router exposes generic CRUD operations with minimal orchestration.
Direct visits CRUD
The visits router exposes generic CRUD operations over Visit.
Combined pool visit flow
The pool-specific combined endpoint is the operational path that best reflects the business flow:
- the technician records measured values;
- the backend stores
PoolValues; - the backend stores
Visitlinked to those values; - the client receives both records in one response.
7. Frontend Integration Notes
Recommended operational flow
For technician workflows, frontend should prefer:
POST /pools/{poolId}/visits
instead of creating PoolValues and Visit separately.
That keeps the operation atomic at the business level and reduces client complexity.
Pool history screens
Frontend can use:
GET /pools/{poolId}/visits
to render visit history for a pool.
Advanced or administrative screens
If needed, frontend can still use generic CRUD endpoints:
/visits/pool-values
for raw data access or internal tooling.
8. UX Considerations
Validation for problematic visits
When the pool is marked as not OK, frontend should require a problem description before submitting, matching the backend validation rule.
Status handling
Because status is explicit, frontend can visualize visits as:
- pending
- in progress
- resolved
without deriving that state from other fields.
9. Current Scope
The current implementation covers:
- raw water measurements;
- visit records;
- combined pool-specific visit creation;
- technician assignment validation;
- list and detail retrieval.
It does not currently cover:
- transactional rollback between visit and values if future persistence rules become more complex;
- pagination of visit history;
- automatic alert triggering from measured values;
- visit approval workflows.
10. Future Recommendations
A future version could add:
- pagination and sorting for pool visit history;
- computed trend endpoints for pH/chlorine/temperature;
- automatic threshold evaluation against alert configuration;
- richer visit state transitions.
11. Final Summary
Visits and water measurements in Poolia are modeled as two complementary resources: one for raw measurement data and one for operational inspection records. The combined /pools/{poolId}/visits flow is the most important business endpoint because it aligns naturally with technician workflows while preserving clean data separation in the backend.