fablabbcn / smartcitizen-api

The Smart Citizen Engine
https://developer.smartcitizen.me
GNU Affero General Public License v3.0
10 stars 4 forks source link

Improvements to forwarding #329

Open timcowlishaw opened 2 weeks ago

timcowlishaw commented 2 weeks ago

TODO: flesh this ticket out more

timcowlishaw commented 4 days ago

Ok, I think as part of this i'd like to make a few small changes to the way we represent things, which should make the responses clearer and more consistent (and make the code for generating responses much simpler and more robust, and therefore more easily reused and adapted to things like forwarding):

The idea is we'd have fixed representations of all of our data types which we use everywhere (so a device on a user looks the same as a device on the index page, as a device on the show page, ditto for sensors, measurements and users) - with one specific exception which i'll get to in a bit.

The device json would look like the following (which also implicitly provides examples of a user, a sensor, a measurement and a reading on the nested objects):

{
  "id": 16080,
  "uuid": "0974aad9-07b1-4c8f-b095-eb3f2373066c",
  "name": "MINKE_demo #",
  "description": "",
  "state": "has_published",
  "system_tags": [
    "indoor",
    "offline",
    "test_device"
  ],
  "user_tags": [
    "Research",
    "Experimental",
    "Lab"
  ],
  "last_reading_at": "2023-05-11T09:01:17Z",
  "created_at": "2023-02-21T17:27:58Z",
  "updated_at": "2024-06-27T17:03:24Z",
  "notify": {
    "stopped_publishing": false,
    "low_battery": false
  },
  "device_token": null,
  "mac_address": null,
  "postprocessing": null,
  "location": {
    "exposure": "indoor",
    "elevation": null,
    "latitude": 41.39685,
    "longitude": 2.19435,
    "geohash": "sp3e9bjfhh",
    "city": "Barcelona",
    "country_code": "ES",
    "country": "Spain"
  },
  "data_policy": null,
  "hardware": {
    "name": "SCK 2.1 Sea Water",
    "type": "SCK",
    "version": "2.1",
    "slug": "sck:2,1:seawater",
    "last_status_message": null
  },
  "owner": {
    "id": 6556,
    "uuid": "76affe1f-a1b8-4a47-bc0b-07bb8f9c700f",
    "role": "admin",
    "username": "team",
    "url": "http://pral2a.com",
    "profile_picture": "https://api.smartcitizen.me/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBalFDIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--9d0516494e820f91076abc46728daab4d7c2ede3/1djs79t.earth.jpg",
    "location": {
      "city": "Barcelona",
      "country": "Spain",
      "country_code": "ES"
    },
    "email": null,
    "legacy_api_key": null,
    "created_at":"2023-02-21T17:27:58Z",
    "updated_at":,"2023-02-21T17:27:58Z"
  },
  "components": [
      {
        "key": "atlas_do",
        "latest_value": 7.3,
        "prev_value": 7.3,
        "last_reading_at": "2023-05-11T09:01:17Z",
        "sensor": {
          "id": 48,
          "parent_id": 47,
          "name": "AS  EZO Dissolved Oxygen",
          "description": "Atlas Scientific EZO™ Dissolved Oxygen",
          "unit": "mg/L",
          "created_at": "2017-08-04T12:05:30Z",
          "updated_at": "2017-08-04T12:05:30Z",
          "uuid": "dd7baf73-705f-4ac0-a119-c75fedd3ddcf",
          "default_key": "atlas_do",
          "datasheet": null,
          "unit_definition": null,
          "measurement": {
            "id": 21,
            "name": "Dissolved Oxygen",
            "description": "Absolute measure of the concentration of oxygen that is dissolved in Water",
            "unit": null,
            "uuid": "86e4fe06-64fd-49af-9534-5d5cf8763ec6",
            "definition": null
          },
          "tags": []
        },
        "readings": [
          {
            "timestamp": "2023-05-11T09:01:17Z",
            "value": 7.3
          }
        ]
      },
  ],
  "unauthorized_fields": [
    "device_token",
    "mac_address",
    "data_policy",
    "hardware.last_status_message",
    "owner.email",
    "owner.legacy_api_key"
  ]
}

The key changes are as follows:

We use these representations everywhere we represent a thing as JSON, apart from on the world map, where, due to the volume of devices, it's important to be as concise as possible. The `world_map' representation therefore becomes something like this, which contains only the info needed to render the map:

{
  "id": 16080,
  "name": "MINKE_demo #",
  "description": "",
  "state": "has_published",
  "system_tags": [
    "indoor",
    "offline",
    "test_device"
  ],
  "user_tags": [
    "Research",
    "Experimental",
    "Lab"
  ],
  "last_reading_at": "2023-05-11T09:01:17Z",
  "location": {
    "exposure": "indoor",
    "elevation": null,
    "latitude": 41.39685,
    "longitude": 2.19435,
    "geohash": "sp3e9bjfhh",
    "city": "Barcelona",
    "country_code": "ES",
    "country": "Spain"
  },
  "hardware": {
    "name": "SCK 2.1 Sea Water",
    "type": "SCK",
    "version": "2.1",
    "slug": "sck:2,1:seawater",
  },
  "owner": {
    "id": 6556,
    "username": "team",
    "url": "http://pral2a.com",
  },
}

This will be the same for authorized and unauthorized users, as there's no privileged information in there.

timcowlishaw commented 4 days ago

@oscgonfer what do you think? there's a couple of small user-facing changes there but i think overall the responses would be much clearer.