# WeBuilt - Cherre API integration
Author(s): Rafael Esteves
Team: Fetchly
Links:
[Pivotal Tracker story](https://www.pivotaltracker.com/n/projects/2570651/stories/182821701)
[Site features required by the client](https://drive.google.com/file/d/1E2V25rThqKz-IwZJVvZeOFoGeQ1uTcDc/view?usp=sharing)
[Cherre's data dictionary](https://docs.google.com/spreadsheets/d/1mOHG0OIIFPOOeF-h4ZM4ywkTYJv_v2QIMkavmQQomKs/edit?usp=sharing)
[Diagram](https://app.tryeraser.com/workspace/g0hmFdTfLKJJp7VLQhEp)
# Introduction
We need to integrate WeBuilt to Cherre API in order to get the geospatial and geometrical data about the buildings (aka properties) and display it on the map.
# To be clarified
Do we need any more data from Cherre other than parcel boundaries?
# Solution
Assuming that the initial request from WeBuilt is done in the search properties route, we can expect to receive, among many others, geospatial parameters.
That means the backend will be queried for properties within a give area.
We can then use those parameters to query either our own already cached data or Cherre's API (more on that in the next paragraphs) for the properties within that area.
Assuming Cherre's data will be used in conjunction with already existing data from WeBuilt's database, we will need to map each property WeBuilt's database to it's corresponding counterpart in Cherre's API.
We can use the existing address related fields to compose an address string that we use to match a given property from our database to one in Cherre's API.
First, however, we'll need to standardise the address we previously composed, so it can effectively be compared against records from Cherre's database.
To do this, we'll send the address string to Cherre's GraphQL api, like this:
```
{
address(address: "8161 Seaton Pl, MONTGOMERY Al") {
one_line_address
}
}
```
Which should return a standardised address. The response should look like this:
```
{
"address": {
"one_line_address": "8161 SEATON PLACE, MONTGOMERY, AL 36116"
}
}
```
> The reference for this resource can be found at https://app.cherre.com/core-api#cherre-standardization-services--6
Now that we have the standardised address we can use it to query Cherre's data and grab the geospatial and geometrical data, like this:
```
{
cherre_address(
where: { display_address: { _eq: "8161 SEATON PLACE, MONTGOMERY, AL 36116" } }
) {
display_address
parcel_boundary__address_point {
assessor_parcel_number
cherre_parcel_boundary_pk
fips_code
geojson
geom
latitude
longitude
parcel_centroid
parcel_centroid_geometry
tax_assessor_id
}
}
}
```
The response would then give us the information needed to draw the object on the map in the correct location and with the correct shape and size, as well as boundaries.
```
{
"cherre_address": [
{
"display_address": "8161 SEATON PLACE, MONTGOMERY, AL 36116",
"parcel_boundary__address_point": [
{
"assessor_parcel_number": "09-09-29-4-000-001.008",
"cherre_parcel_boundary_pk": 3765071503848069600,
"fips_code": "01101",
"geojson": "{\"type\":\"Polygon\",\"coordinates\":[[[-86.17176797919449,32.33797100921091],[-86.17183948239498,32.33797510549812],[-86.17189781809176,32.33798025450885],[-86.17190344513863,32.33860272703323],[-86.17125593229482,32.33860716786986],[-86.17125067265882,32.33802664416512],[-86.17127628362821,32.33802449545892],[-86.17129615436347,32.33802034073174],[-86.17131525254575,32.33801409118362],[-86.17133326915688,32.33800584623966],[-86.17134991493843,32.33799573872984],[-86.17137365471606,32.33797772326697],[-86.17138380478024,32.33797335070754],[-86.17139485316103,32.33797103122264],[-86.17165482740169,32.33796901002545],[-86.17169634483748,32.33796910717462],[-86.17176797919449,32.33797100921091]]]}",
"geom": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::4326"
}
},
"coordinates": [
[
[
-86.1716963448375,
32.3379691071746
],
[
-86.1716548274017,
32.3379690100255
],
]
]
},
"latitude": 32.33829,
"longitude": -86.17158,
"parcel_centroid": {
"type": "Point",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::4326"
}
},
"coordinates": [
-86.1715794753293,
32.3382916707255
]
},
"parcel_centroid_geometry": {
"type": "Point",
"coordinates": [
-86.1715794753293,
32.3382916707255
]
},
"tax_assessor_id": 734334016
}
]
}
]
}
```
# Formulating the response
First, we will need a table to store Cherre's responses. We will store as JSON in a table called`cherre_data`.
| id | property_id | geojson | geom | ... |
| --- | ---------------- | ------- | ---- | --- |
| int | Ref from WeBuilt | json | json | ... |
> he dots (...) represent the rest of Cherre's response data. We'll store all of it.
[](https://i.imgur.com/4YTDFuj.jpg)
As noted in the diagram above, we first need to check if the DB query is cached, and if so, return the cached response.
> Reference [here](https://www.honeybadger.io/blog/rails-activerecord-caching/)
Then we check if the area bein queried is known, meaning it is stored in our database from a previous request or job run, and if so, we pull from there, avoiding an API call.
If the area is unknown, we have to hit Cherre.
We query Cherre's database for that area and populate both the response and the `cherre_data`database table.
# Relationship between tables
There should be a 1 to 1 relationship between `properties` and `cherre_data`.
In the diagram, it shows a `cherre_id` field in the `properties` table, I think it could be the other way around, so we avoid to change the already existing `properties` table.
In that case, we'd have a `property_id`field in the `cherre_data` table.
# The job runs
There will be a job that every x amount of time to refresh WeBuilt's database with Cherre's up to date information.
The interval x should be decided with the client taking in consideration how long