Continue adding JSON information and also begin working on the aggregation SQL.

me committed 2026-08-20 13:25:07 -07:00
1 parent bde8a74880
commit 6b883fc6cb
1 file changed
+99 -11
+99 -11
@@ -8,7 +8,7 @@ To allow users to enter up to 8 locations and have the highs and lows display on
| SE | | | CQ |
| | CQ | WS | |
## Explanation
## Definitions
The wheel is based on the movement of the sun and determines the seasons of the year.
@@ -168,7 +168,7 @@ than half of their latitudes as negatives.
## 2. Database
### Description
#: TBD
### Requirements
@@ -255,7 +255,13 @@ access the tables, or a setting / parameter can be set to default to them.
Today's high and low are accessible when joining to the `LOC_WEATHER` table, which
is necessary anyways to get to the `WEATHER_DATE` and `ZIP_CODE`.
Extended high and low are for `WEATHER_DATE + 7`, so a week from the date.
Extended high and low are for the furthest accessible day up to a week out.
```sql
SELECT loc_weather_id, max(weather_date)
FROM loc_weather
WHERE weather_date <= sysdate+7
GROUP BY loc_weather_id;
```
### Roles
@@ -338,6 +344,47 @@ For each `ZIP_CODE`, calculate the following:
- Weekly Mean
- Weekly Median
- Weekly Mode
- Tomorrow
```sql
-- Can be done the same as Extended, just change the sysdate+7 to sysdate+1.
```
- Extended
- Example:
```sql
-- Need to get the max(weather_date) per loc_id, identify its loc_weather_id, then use that to join against the agg table.
-- Temp view of the latest date that each location has.
SELECT lw.loc_id, max(lw.weather_date)
FROM loc_weather lw
WHERE lw.weather_date <= sysdate + 7
GROUP BY lw.loc_id;
-- Joining the temp view to the table to get the individual records.
SELECT lw.loc_weather_id, lw.high, lw.low
FROM loc_weather lw
, (SELECT lw.loc_id, max(lw.weather_date) as weather_date
FROM loc_weather lw
WHERE lw.weather_date <= sysdate + 7
GROUP BY lw.loc_id) t
WHERE lw.loc_id = t.loc_id
AND lw.weather_date = t.weather_date;
-- Merging the data into the agg table.
MERGE INTO loc_weather_agg o
USING (SELECT lw.loc_weather_id, lw.high, lw.low
FROM loc_weather lw
, (SELECT lw.loc_id, max(lw.weather_date) as max_weather_date
FROM loc_weather lw
WHERE lw.weather_date <= sysdate + 7
GROUP BY lw.loc_id) t
WHERE lw.loc_id = t.loc_id
AND lw.weather_date = t.max_weather_date) i
ON (o.loc_weather_id = i.loc_weather_id)
WHEN MATCHED THEN UPDATE
SET o.extended_high = i.high
, o.extended_low = i.low;
commit;
```
## 4. Response API
@@ -359,8 +406,33 @@ Listener API which receives requests from the front end and queries the database
- Program shall post any new zip codes in the `loc` table.
- program shall update `loc.last_accessed_date` for the zip codes it retrieved data for.
### Flow
1. Initialize.
1. Parse request. (Appendix #1)
1. Merge zip codes to `loc`.
1. Notify `weatherman` if new zip codes exist.
- Wait until a continue or error is replied.
- If continue, proceed to next steps.
- If error, provide error to user (Appendix #8)
1. Pull weather data from `loc_weather` and `loc_weather_agg`.
1. Form and deliver response. (Appendix #2)
# Appendix - JSON Requests and Responses
Between the programs being developed there are 3 themes being used regarding message intent.
**data**
: These messages pass information back and forth.
**command**
: These are used to notify programs that actions need taken.
**error**
: These notify that something went wrong and may provide a message with which to return to the front end.
Theintent is passed at the JSON object's root level `"message_type"` attribute. The rest of the payload lies within an attribute named the same as the message type.
## 1. Request: Front End to Response API
- Data shall be de-duplicated so that any one zip only appears once.
@@ -371,6 +443,7 @@ response to provide, in case the format changes in the future.
```json
{
"version": "1.0",
"message_type": "data",
"data": [
"zip_code": "85901",
"zip_code": "86004",
@@ -389,6 +462,7 @@ response to provide, in case the format changes in the future.
```json
{
"version": "1.0",
"message_type": "data",
"data": [
{
"zip_code": "85901",
@@ -449,25 +523,28 @@ response to provide, in case the format changes in the future.
Notification from the `reporter` for the `weatherman` to kick off an ad hoc run.
This data never leaves the server and cannot come from outside sources, the endpoint will not available to the public, it is accessed via localhost.
Zip codes do not need provided since the `reporter` has already inserted and committed them to `loc`.
- This data never leaves the server and cannot come from outside sources, the endpoint will not available to the public, it is accessed via localhost.
- Zip codes do not need provided since the `reporter` has already inserted and committed them to `loc`.
- `reporter` runs this in a synchronous fashion, waiting for the response before continuing to reply to the user.
```json
{
"data": "run",
"message_type": "command",
"command": "run",
}
```
## 6. Response: ZIP_CODE Data Now Available
Response from `weatherman` program to `reporter`.
Response from `weatherman` program to `reporter` that the new zip codes inserted into the DB have data.
- If the `reporter` sees this, then it continues with building a response for the front end user.
If the `reporter` sees this, then it continues with building a response for the front end.
```json
{
"data": "ready",
"message_type": "command",
"command": "continue",
}
```
@@ -479,7 +556,18 @@ If the `reporter` happens to see this, it provides
```json
{
"data": "error",
"message_type": "error",
"error": "Message about what went wrong, which may get forwarded to the user.",
}
```
## 8. Response: Error to Front End
Sometimes the `reporter` may need to let the user know things did not go as planned.
```json
{
"message_type": "error",
"error": "Failed to pull weather information. REASON.",
}
```