This page provides a summary of how a third party process can use the PainChek "Update Stamp" attribute to enable efficient data synchronisation.
The first time a process connects to the PainChek API, it will need to fetch and synchronise all data. However, when the API is subsequently used to re-synchronise the two systems, the third party process will only need to process "deltas" (changes in records), leading to a small, fast and efficient synchronisation processes.
In order for a process know what "delta" records it should fetch, PainChek uses the concept of an "update stamp".
The update stamp is an integer field found in every table.
Every time a record is created or updated, the records "update stamp" is set to the current highest value + 1.
For instance, if records A, then B then C third created, the data looks like this:
Record |
Update Stamp |
---|---|
A |
1 |
B |
2 |
C |
3 |
If record B is then edited, the data appears like this:
Record |
Update Stamp |
---|---|
A |
1 |
B |
4 |
C |
3 |
If record D is then added, the data becomes:
Record |
Update Stamp |
---|---|
A |
1 |
B |
4 |
C |
3 |
D |
5 |
Note
Note that the "update stamp" sequence will end up with gaps (e.g. "2" is no longer in the sequence) and that each table (object type) maintains its own "update stamp" sequence.
A third party synchronisation process can use the "update stamp" to efficiently detect and process the updates (adds/edits/deletes) that have been made on the PainChek system since the previous synchronisation.
The third Party process would need to:
-
Record maximum update stamp it currently knows about
-
When the process performs a synchronisation, it passes the last known "update stamp" to the PainChek API
-
The API returns all new and updated records (i.e. records with an "update stamp" larger than the value supplied)
-
The process uses those updates to synchronise its data store with PainChek
-
The process updates the maximum "update stamp" returned from the API to use a reference point for the next synchronisation run.
NB: The above process operates independently for each table/object type (users, patients, comments, etc) in PainChek.
For instance, consider that when a table is first synchronised, this is the data available:
Record |
Update Stamp |
---|---|
A |
1 |
B |
2 |
C |
3 |
...the third Party process would record a maximum update stamp of "3".
At the time of the next synchronisation. this is data available:
Record |
Update Stamp |
---|---|
A |
1 |
B |
4 |
C |
3 |
D |
5 |
The third-party process will supply an "update stamp" of "3" and so the PainChek API will respond with 2 records (the update to "B" and the new "D"). The third-party process the records (one update and one insert) and then records a maximum update stamp of "5".
If the third party process synchronises again (assuming the PainChek data is unchanged), it will be asking for records greater than "5" and, as there are none, no data is returned and no processing is required.
API calls that fetch lists of data (e.g. patients, assessments, comments, etc.) can pass the "sync" parameter - e.g.:
curl https://ap.ua.painchek.com/api/patients/?sync=755
The API will return all records where the "update stamp" is higher than 755 - e.g.:
{ "count": 2, "next": null, "previous": null, "results": [{ "uuid": "7f58e25c-ba8a-47d5-b7d6-1377428b14fa", "license": "a89e0cc1-fd90-4721-b09b-7f527f5ff626", "license_name": "A89E0CC1-FD90/PainChek Ltd/2018-08-25", "first_name": "Enola", "last_name": "Gay", "nickname": "Rose", "gender": "f", "birth_date": "1951-11-14", "death_date": null, "created_at": "2017-09-26T02:16:28.850000Z", "modified_at": "2017-11-13T02:17:35.662737Z", "deleted_at": null, "deleted_reason": null, "update_stamp": 760, "image": "https://ap.ua.painchek.com/media/patients/7f58e25c-ba8a-47d5-b7d6-1377428b14fa.jpg", "external_id": null }, { "uuid": "9b829fe4-a72a-4323-ae65-5fa4622b6986", "license": "a89e0cc1-fd90-4721-b09b-7f527f5ff626", "license_name": "A89E0CC1-FD90/PainChek Ltd/2018-08-25", "first_name": "Norma", "last_name": "May", "nickname": "Maisie", "gender": "f", "birth_date": "1940-06-23", "death_date": null, "created_at": "2017-09-26T02:16:28.806000Z", "modified_at": "2017-11-13T02:14:26.372040Z", "deleted_at": null, "deleted_reason": null, "update_stamp": 759, "image": "https://ap.ua.painchek.com/media/patients/9b829fe4-a72a-4323-ae65-5fa4622b6986.jpg", "external_id": null }] }
You can see the 2 records `were returned - one with an update stamp of 759 and one with an update stamp of 760. At that point, a synchronisation process can record the last update value is 760 and hence, the next time it synchronises, it would call:
curl -u <username>:<password> https://ap.ua.painchek.com/api/patients/?sync=760
Assuming no data has been updated since the previous call, the return would be:
curl https://ap.ua.painchek.com/api/patients/?sync=755
Note
Using the "sync" parameter is the preferred and correct way of detecting new, updated and deleted records.
Using timestamps is not considered reliable as it's possible that data is cached on local devices for long periods of time before being uploaded by the PainChek database. Using timestamps could result in these records being "missed".