Skip to content

Notes Module Application Guide

This guide explains how to use the Notes module of the Coldwave Cloud Backend from an application developer perspective. It focuses on typical UX patterns, API usage and WebSocket integration.

The Notes module is intentionally simple: it lets your users attach free-form text notes (service logs, comments, to‑dos) to devices. Notes are always associated with a device (not a specific service or property).


When and why to use notes

Common use cases:

  • Service & maintenance logs
    • Technicians record what they did on a device (e.g. “Fan replaced, firmware updated to 1.2.3”).
    • Follow‑up teams can see the full history in the device detail view.
  • Operational communication
    • Operators add comments like “intermittent noise since last week” or “customer reported error at 14:30”.
    • Notes can supplement alarms and telemetry with human context.
  • Ad‑hoc documentation
    • Internal remarks such as “Do not change setpoint X; part of special contract”.
    • Quick bookmarks for later investigations.

Notes are not intended for:

  • Large attachments or binary data (use a separate storage system and link from the note).
  • Structured configuration (use metadata / schema / device config instead).

Data model in practice

The Notes API revolves around a very small data model:

  • deviceIdentifier – the device this note belongs to.
  • id / noteIdentifier – unique identifier of the note (integer).
  • author – free‑form string that represents the user who created the note.
  • note – the text content of the note.
  • createdAt – creation timestamp (integer, typically UNIX epoch seconds).
  • updatedAt – last update timestamp (integer, optional).

In your frontend state model you can standardize the identifier naming:

ts
type DeviceId = string;
type NoteId = number;

interface Note {
  noteIdentifier: NoteId;        // maps to id / noteIdentifier in the API
  deviceIdentifier: DeviceId;
  author: string;
  text: string;
  createdAt: number;
  updatedAt?: number;
}

Store notes normalized and indexed by deviceIdentifier:

ts
interface AppState {
  // ...
  notesByDevice: Record<DeviceId, Note[]>;
}

UX patterns for device notes

Typical UI patterns for notes in applications:

  • Timeline on the device detail page
    • Show a reverse‑chronological list (“most recent first”) of notes for the current device.
    • Include author, timestamp and content.
  • Compact “Notes” teaser on overview pages
    • Show the latest 1–2 notes per device (or an indicator “3 notes in last 7 days”).
    • Clicking opens the full device detail with the notes timeline.
  • “Add note” form
    • Simple textarea + submit button.
    • Optionally a dropdown or implicit value for author (current user or IAM username).
  • Search / filter (optional)
    • Filter by text content (“contains ‘compressor’”).
    • Filter by time range (“last 30 days”) or by author.

Permissions are controlled by the backend (notes resource). In the UI, you can:

  • Hide the “Add note” / “Edit” / “Delete” controls if the user has read‑only access.
  • Gracefully handle 403 responses (show a warning/snackbar and refresh visible notes).

API usage: essential endpoints

The Notes module provides five main operations:

  • Create a note for a device.
  • Update an existing note.
  • Delete an existing note.
  • List all notes (across devices).
  • List all notes for a specific device.

All endpoints live under /api/v1/notes and require the appropriate permission on the notes resource.

1. List notes for a device

Use this endpoint to show a note timeline on a device detail page.

http
GET /api/v1/notes/:deviceIdentifier
  • Access: requires read permission for resource notes.
  • URL parameter:
    • deviceIdentifier – unique device identifier (case‑insensitive in the backend).

Example (curl):

bash
curl --location '<<URL>>/api/v1/notes/DEVICE-1234'       --header "Authorization: Bearer ${TOKEN}"

Example response (simplified):

json
[
  {
    "createdAt": 1700000000,
    "updatedAt": 1700003600,
    "id": 1,
    "author": "alice@example.com",
    "note": "Replaced fan, set speed to 70%."
  },
  {
    "createdAt": 1699900000,
    "id": 2,
    "author": "bob@example.com",
    "note": "Customer reported intermittent noise."
  }
]

In your frontend, map id to noteIdentifier and sort by createdAt / updatedAt as needed.

2. List notes across devices (admin / overview)

Use this endpoint to implement admin or fleet‑wide views of notes.

http
GET /api/v1/notes
  • Access: requires read permission for resource notes.
  • Query parameters:
    • depth (optional) – generic parameter used across modules to include nested information; for notes, depth=1 returns notes grouped by device.

Example (simplified response structure):

json
[
  {
    "deviceIdentifier": "DEVICE-1234",
    "notes": [
      {
        "createdAt": 1700000000,
        "updatedAt": 1700003600,
        "id": 1,
        "author": "alice@example.com",
        "note": "Replaced fan, set speed to 70%."
      }
    ]
  },
  {
    "deviceIdentifier": "DEVICE-5678",
    "notes": [
      {
        "createdAt": 1699900000,
        "id": 2,
        "author": "bob@example.com",
        "note": "Check vibration sensor at next visit."
      }
    ]
  }
]

This is particularly useful for “fleet activity” or “service logs” overview pages.

3. Create a note

Use this to add a new note for a device.

http
POST /api/v1/notes/:deviceIdentifier
  • Access: requires create permission for resource notes.
  • URL parameter:
    • deviceIdentifier – unique device identifier.
  • Request body:
    • note (string, required) – the note content.

Example (curl):

bash
curl --location '<<URL>>/api/v1/notes/DEVICE-1234'       --header "Authorization: Bearer ${TOKEN}"       --header 'Content-Type: application/json'       --data '{
    "note": "Replaced fan, new firmware 1.2.3."
  }'

Response (simplified):

json
{
  "noteIdentifier": 42
}

Implementation notes:

  • Use the returned noteIdentifier as the canonical ID and add the note to your notesByDevice[deviceIdentifier] list.
  • In most UIs, you do not need to refetch all notes after creation if you already have the list in state; just append the new note and rely on the WebSocket event as confirmation.

4. Update a note

Use this to edit the content of an existing note.

http
PUT /api/v1/notes/:deviceIdentifier/:noteIdentifier
  • Access: requires update permission for resource notes.
  • URL parameters:
    • deviceIdentifier – unique device identifier.
    • noteIdentifier – unique identifier of the note (integer).
  • Request body:
    • note (string, required) – the updated note content.

Example (curl):

bash
curl --location '<<URL>>/api/v1/notes/DEVICE-1234/42'       --header "Authorization: Bearer ${TOKEN}"       --header 'Content-Type: application/json'       --data '{
    "note": "Replaced fan, new firmware 1.2.4 (was 1.2.3)."
  }'

Response:

  • Returns HTTP status 204 No Content on success.

In the UI, you can optimistically update the note text and timestamp; if the request fails, revert the changes and show an error.

5. Delete a note

Use this to remove a note (e.g. if it was added by mistake).

http
DELETE /api/v1/notes/:deviceIdentifier/:noteIdentifier
  • Access: requires delete permission for resource notes.
  • URL parameters:
    • deviceIdentifier – unique device identifier.
    • noteIdentifier – unique identifier of the note (integer).

Response:

  • Returns HTTP status 204 No Content on success.

In the UI, confirm deletion with the user before sending the request, then remove the note from notesByDevice[deviceIdentifier].


WebSocket integration

The Notes module emits events over the WebSocket connection so that UIs can update without polling. Events share a common pattern used throughout the backend: a type field and additional data.

Notes events include (names simplified):

  • NOTE_MESSAGE_ADD – a new note was created for a device.
  • NOTE_MESSAGE_UPDATE – an existing note was updated.
  • NOTE_MESSAGE_DELETE – a note was deleted.

All note events:

  • Require read permission for the notes resource.
  • Respect device access permissions (e.g. tenant / customer scoping).

A typical event payload contains:

  • type – one of the event names above.
  • deviceIdentifier – the affected device.
  • createdAt / updatedAt – timestamps.
  • id – numeric note identifier.
  • author – author string.
  • note – note content (for add/update).

Example WebSocket handler (TypeScript‑style pseudocode):

ts
function applyNoteEvent(state: AppState, event: any) {
  const deviceId: DeviceId = event.deviceIdentifier;
  if (!state.notesByDevice[deviceId]) {
    state.notesByDevice[deviceId] = [];
  }

  switch (event.type) {
    case "NOTE_MESSAGE_ADD": {
      const note: Note = {
        noteIdentifier: event.id,
        deviceIdentifier: deviceId,
        author: event.author,
        text: event.note,
        createdAt: event.createdAt,
        updatedAt: event.updatedAt,
      };
      state.notesByDevice[deviceId].push(note);
      // keep newest first
      state.notesByDevice[deviceId].sort(
        (a, b) => (b.updatedAt ?? b.createdAt) - (a.updatedAt ?? a.createdAt)
      );
      break;
    }

    case "NOTE_MESSAGE_UPDATE": {
      const list = state.notesByDevice[deviceId];
      const idx = list.findIndex((n) => n.noteIdentifier === event.id);
      if (idx >= 0) {
        list[idx] = {
          ...list[idx],
          text: event.note,
          updatedAt: event.updatedAt ?? Date.now(),
        };
      }
      break;
    }

    case "NOTE_MESSAGE_DELETE": {
      const list = state.notesByDevice[deviceId];
      state.notesByDevice[deviceId] = list.filter(
        (n) => n.noteIdentifier !== event.id
      );
      break;
    }
  }
}

Integrate this into your global WebSocket dispatcher alongside other module events (alarms, OTA, etc.).


Permission patterns and multi‑tenant UIs

A few practical patterns for using notes in multi‑tenant environments:

  • Per‑tenant isolation
    • Rely on the backend’s IAM and device access control to ensure tenants only see notes for their own devices.
  • Role‑based UI features
    • Show “Add / Edit / Delete note” actions only if the current user has create / update / delete permissions for notes.
  • Audit‑friendly design
    • Display author and timestamps prominently.
    • Consider making deletion rare (e.g. only admins) and encourage corrections via new notes.

For most applications, a simple role distinction (viewer vs operator vs admin) and checking capabilities on the notes resource is sufficient.


Summary

  • The Notes module lets you attach free‑form text notes to devices.
  • API usage is straightforward: list notes (per device or fleet‑wide), create, update and delete notes.
  • WebSocket events keep the UI synchronized in real time.
  • A normalized notesByDevice state and a small set of reducer functions are enough to integrate notes into dashboards, detail pages and maintenance tools.