Skip to content

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:

  • poolValues
  • visits

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

  • poolId
  • ph
  • chlorine
  • temperature
  • isOk
  • createdAt

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

  • date
  • technicianId
  • poolId
  • poolValueId
  • isPoolOk
  • isOk
  • actions
  • problem
  • status
  • observations

Visit status

Allowed values are:

  • pending
  • in_progress
  • resolved

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 PoolValues record;
  • creates a Visit record 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:

  1. the technician records measured values;
  2. the backend stores PoolValues;
  3. the backend stores Visit linked to those values;
  4. the client receives both records in one response.

7. Frontend Integration Notes

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.