From fdb6b8838e45177b18e086384abd2f491d03bf4c Mon Sep 17 00:00:00 2001 From: Hyperling Date: Tue, 18 Aug 2026 16:51:15 -0700 Subject: [PATCH 1/7] frontend, add the outline for a possible settings page. --- Design.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Design.md b/Design.md index 842ad1b..dbfd326 100644 --- a/Design.md +++ b/Design.md @@ -34,6 +34,39 @@ Developer: Hyperling Language/Framework: Flutter +#### Settings + +**Not required in initial versions of the app, focus on pulling data first!** + +1. Server + - Toggle: 'Use Cache Server' + - TRUE: + - Radio Group: 'Aggregation Mode' + - 'Mean / Average' + - 'Mode / Most Common' + - 'Median / Center-Most' + - 'Today Only' + - 'Tomorrow Only' + - FALSE: + - TextEdit: 'API Key' (REQUIRED) + - 'If not using the cache server, you'll need to provide your own API key for TBD weather service.' + - TBD: What data is provided, and how easy is it to manipulate? +1. 'Temperature' + - Radio Group: 'Unit' + - Fahrenheit (^F) + - Celcius (^C) + - TextEdit: 'Preferred High' + - Radio Group: 'Relativity? (TBD)' + - Less Than + - Greather Than + - Checkbox: 'Equal To' + - TextEdit: 'referred Low' + - Radio Group: 'Relativity? (TBD)' + - Less Than + - Greather Than + - Checkbox: 'Equal To' + + ### Description ### Requirements From 6cf39d2672ca796f15236fbc6f7148c1d750a0ca Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 19 Aug 2026 12:18:30 -0700 Subject: [PATCH 2/7] Lots of DB content as well as some love to the frontend and fetcher sections. --- Design.md | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 220 insertions(+), 9 deletions(-) diff --git a/Design.md b/Design.md index dbfd326..8121e75 100644 --- a/Design.md +++ b/Design.md @@ -34,19 +34,71 @@ Developer: Hyperling Language/Framework: Flutter +### Planned Versions + +**0.1** +: Basic listview app, hardcode limited production API key. + +**0.2** +: Change main page to a Celtic Wheel type layout with season signifier. + +**1.0** +: Integrate with a backend cache server which provides aggregated data. + +**1.1** +: Add settings page and other nice to haves. + +### Requirements + +- App shall start with a Main page only, then have a Settings page added later. +- App shall come with a limited use API key. This key shall not be used by any +other module of this project. Developers should use their seperate API key when +using Postman, testing the Weather Fetcher, etc. + +### Pages + +#### Main + +*Initial Versions - Simple Data Entry* + +--- + +8 sections which contain (three?) data input fieldss: + +- Zip Code +- Lat & Long (or should the lat/long just be used to lookup the zip code?) +- Nickname + +*Formal Versions - Wheel Layout* + +--- + +Circular layout representing the Celtic season wheel with 'LAST_UPDATE_DATE' +in the center so the user knows when the highs and lows were last refreshed. + +"Hand" which points to the current season. Accurate to the day preferably, so +if we're at September 1 it's pointing in between Summer CQ and Fall Equinox. + +- Initially can just highlight the current half quarter and start making the next +one glow as it gets approached. So for June 21, Spring2 and Summer1 would both +glow at 50% since that's the day they transition. Then by mid July it would only +be Summer1 which glows, and at the end of July Summer1 would be dim and Summer2 +would be glowing more. + #### Settings **Not required in initial versions of the app, focus on pulling data first!** -1. Server +1. 'Server' - Toggle: 'Use Cache Server' - TRUE: - Radio Group: 'Aggregation Mode' - - 'Mean / Average' - - 'Mode / Most Common' - - 'Median / Center-Most' - - 'Today Only' - - 'Tomorrow Only' + - 'Week : Mean / Average' + - 'Week : Median / Center-Most' + - 'Week : Mode / Most Common' + - 'Only : Today' + - ?'Only : Tomorrow' + - ?'Only : Today + 7' - FALSE: - TextEdit: 'API Key' (REQUIRED) - 'If not using the cache server, you'll need to provide your own API key for TBD weather service.' @@ -66,27 +118,186 @@ Language/Framework: Flutter - Greather Than - Checkbox: 'Equal To' - ### Description ### Requirements ## 2. Database - - ### Description ### Requirements +- All temperature data shall be stored in Fahrenheit. Decimals are okay. +- All date data shall be displayed as 'YYYY-MM-DDTHH24:MI:SS' GMT +(or 'YYYY-MM-DDTHH24:MI:SS+0000') in any reporting or data transfers. Time zones +will be handled at the frontend. The 'T' in the center is a dead character. Example: + ```shell + $ echo "Actual Time: `date`" && echo "Report Time: `date -u +'%Y-%m-%dT%H:%M:%S%z'`" + Actual Time: Wed Aug 19 10:49:52 AM MST 2026 + Report Time: 2026-08-19T17:49:52+0000 + ``` +- Database shall be set to case insensitive, so that `SELECT column FROM loc` +and `select COLUMN from LOC` are the same command. +- Database shall have a daily purge script followed by statistics rebuilding. +The records to be removed will look like (TBD: `IS_PURGED = true`). The purge +will cascade through any child tables. Bonus points if they exist, are scheduled, +and gets executed from inside the DB rather than needing to run outside files. +- Database object script(s) for the primary initialization as well as patches +shall be reproducible and rerunnable, meaning they drop then create all database +objects, constraints, schedules, etc being added in the revision. Example: + ```sql + -- Undo Section -- + -- Allowed to have failures if the objects don't exist yet. + SET ERRORS OFF / ON ERROR CONTINUE / ETC; + DROP TABLE example_child; + DROP TABLE example; + + -- Apply Section -- + -- All commands must succeed successfully in order to continue. + SET ERRORS ON / ON ERROR EXIT / ETC; + CREATE TABLE example + ( example_id INT PRIMARY KEY + , example_data VARCHAR + ); + CREATE TABLE example_child + ( example_child_id INT PRIMARY KEY + , example_id INT FOREIGN KEY (example.example_id) + , more_example_data VARCHAR + ); + ``` +- Scripts shall have a consistent style and formatting. Developer may use the +style of their choice. + +### Tables + +- Database and schema names shall be short and easy to remember, otherwise they +are the developer's choice. Bonus points if the DB does not require them to +access the tables, or a setting / parameter can be set to default to them. + ```sql + -- yucky + select * from db_name.schema_name.table_name; + -- preferred + select * from table_name; + ``` + +#### Table 1: `loc` + +| Column Name | Type | Constraints | Calculated? | +| --- | :-: | :---: | :-----: | +| loc_id | INT | PK | - | +| zip_code | STRING | UNIQUE | - | +| last_accessed_date | DATE | - | - | +| needs_purged | - | - | CASE WHEN sysdate < last_accessed_date + 90 THEN true ELSE false ESAC | + +#### Table 3: `loc_weather_agg` + +| Column Name | Type | Constraints | Calculated? | +| --- | :-: | :---: | :-----: | +| loc_weather_agg_id | INT | PK | - | +| loc_weather_id | INT | FK (loc_weather.loc_weather_id) | - | +| weekly_mean_high | DECIMAL | - | - | +| weekly_mean_low | DECIMAL | - | - | +| weekly_median_high | DECIMAL | - | - | +| weekly_median_low | DECIMAL | - | - | +| weekly_mode_high | DECIMAL | - | - | +| weekly_mode_low | DECIMAL | - | - | +| tomorrow_high | DECIMAL | - | - | +| tomorrow_low | DECIMAL | - | - | +| extended_high | DECIMAL | - | - | +| extended_low | DECIMAL | - | - | + +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. + +### Roles + +Object grants shall be given to roles, and the roles then assigned to users. Example: +```sql +CREATE ROLE myrole; +GRANT SELECT, INSERT, UPDATE ON example TO myrole; +CREATE USER me; +GRANT myrole TO me; +``` + +#### Role 0 : `librarian` + +- Grant `SELECT` on all `loc*` tables. + +#### Role 1: `weatherman` + +- Grant `INSERT` and `UPDATE` on all `loc_weather*` tables. + +#### Role 2: `reporter` + +- Grant `INSERT`, `UPDATE` on `loc`. + +#### Role 3: `garbageman` + +- Grant `DELETE` on all `loc*` tables. +- Grant ability to build statistics on all `loc*` tables. +- Depending on the DB used, may also need grants on keys and constraints in order to rebuild the stats on their indexes or other stat-holding objects. + +#### Role 4: `developer` + +- Grant `ALL` on the applicable schema. +- CANNOT access or alter `SYSTEM` type schemas, views, etc. + +### Users + +#### User 1: `dbuser` + +- Granted the `librarian` and `developer` role. +- Used by the main contributors of the project to test in stage environments. +- Used by the project owner(s) in production to apply patch scripts. + +#### User 2: `climate` + +- Granted the `librarian` and `weatherman` role. +- Used by a local process to add and aggregate weather data. + +#### User 3: `geo` + +- Granted the `librarian` and `reporter` role. +- Used by a local process to pull weather data and post new locations. + +#### User 4: `purge` + +- Granted the `librarian` and `garbageman` role. +- User / schema who owns the purge routines if they are intalled in the DB. +- Otherwise, this is the user who logs in and runs external purge scripts. + +#### As Needed: leetbro, hackersis, othercoolalias + +Contributors to this project may have their accounts created in test and stage +environments as necessary. Otherwise the contributors known as DB admins shall +handle all applicable DB support and modifications. + ## 3. Weather Fetcher ### Description ### Requirements +- Assume the database is local, just as would be during local devlopment. Will +not need to access via domain name or a special port, only localhost:defaut_port. +- Program shall use its own API key(s) to access the weather data. May use a +pool of keys if necessary to alleviate bandwidth or throttling. + +#### Aggregations + +For each `ZIP_CODE`, calculate the following: + +- Weekly Mean +- Weekly Median +- Weekly Mode + ## 4. Response API ### Description ### Requirements + +- From 0508ef3ecefc9d8d858a7e5cd9217437f5a68628 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 19 Aug 2026 12:42:23 -0700 Subject: [PATCH 3/7] Spelling checks and a few more thoughts for the front end. --- Design.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/Design.md b/Design.md index 8121e75..29f5a6f 100644 --- a/Design.md +++ b/Design.md @@ -52,7 +52,7 @@ Language/Framework: Flutter - App shall start with a Main page only, then have a Settings page added later. - App shall come with a limited use API key. This key shall not be used by any -other module of this project. Developers should use their seperate API key when +other module of this project. Developers should use their separate API key when using Postman, testing the Weather Fetcher, etc. ### Pages @@ -63,10 +63,10 @@ using Postman, testing the Weather Fetcher, etc. --- -8 sections which contain (three?) data input fieldss: +8 sections which contain (three?) data input fields: - Zip Code -- Lat & Long (or should the lat/long just be used to lookup the zip code?) +- Lat & Long (used to look up the zip, not sent to cache DB or weather service) - Nickname *Formal Versions - Wheel Layout* @@ -83,7 +83,12 @@ if we're at September 1 it's pointing in between Summer CQ and Fall Equinox. one glow as it gets approached. So for June 21, Spring2 and Summer1 would both glow at 50% since that's the day they transition. Then by mid July it would only be Summer1 which glows, and at the end of July Summer1 would be dim and Summer2 -would be glowing more. +would be glowing more. Maybe keep this in play after the hand works too. +- (TBD: If someone is in the southern hemisphere, how to know that and do the hand in a 180 degree from what it'd be up north? Maybe the location API can be used to know that based on the latitude being positive or negative if only a zip code is provided.) + +##### Actions + +- IF zip == "" && lat != "" && long != "" THEN zip = LOOKUP(lat, long); #### Settings @@ -106,16 +111,16 @@ would be glowing more. 1. 'Temperature' - Radio Group: 'Unit' - Fahrenheit (^F) - - Celcius (^C) + - Celsius (^C) - TextEdit: 'Preferred High' - Radio Group: 'Relativity? (TBD)' - Less Than - - Greather Than + - Greater Than - Checkbox: 'Equal To' - TextEdit: 'referred Low' - Radio Group: 'Relativity? (TBD)' - Less Than - - Greather Than + - Greater Than - Checkbox: 'Equal To' ### Description @@ -266,7 +271,7 @@ GRANT myrole TO me; #### User 4: `purge` - Granted the `librarian` and `garbageman` role. -- User / schema who owns the purge routines if they are intalled in the DB. +- User / schema who owns the purge routines if they are installed in the DB. - Otherwise, this is the user who logs in and runs external purge scripts. #### As Needed: leetbro, hackersis, othercoolalias @@ -281,7 +286,7 @@ handle all applicable DB support and modifications. ### Requirements -- Assume the database is local, just as would be during local devlopment. Will +- Assume the database is local, just as would be during local development. Will not need to access via domain name or a special port, only localhost:defaut_port. - Program shall use its own API key(s) to access the weather data. May use a pool of keys if necessary to alleviate bandwidth or throttling. From bd031d10b489f9ab2b02e725207cb7d58e3df642 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 19 Aug 2026 13:27:45 -0700 Subject: [PATCH 4/7] Contnue additions to front end as well as to the overview section. --- Design.md | 73 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/Design.md b/Design.md index 29f5a6f..ec97cb5 100644 --- a/Design.md +++ b/Design.md @@ -1,6 +1,6 @@ # Purpose -To allow users to enter up to 8 locations based on zip codes or lat/long and have the highs and lows display on a Celtic Wheel type layout based on the movement of the sun and seasons of the year. +To allow users to enter up to 8 locations and have the highs and lows display on a Celtic Wheel type layout in order to provide an easy at-a-glance evaluation of where to move during a weather focused nomadic cycle. | | SS | CQ | | | --- | --- | --- | --- | @@ -10,6 +10,8 @@ To allow users to enter up to 8 locations based on zip codes or lat/long and hav ## Explanation +The wheel is based on the movement of the sun and determines the seasons of the year. + SS = Summer Solstice, CQ = Cross Quarter, FE = Fall Equinox, @@ -26,6 +28,19 @@ The day is an estimate which typically actually spans between the 21st and 24th. Cross quarters are calculated to be `month = (3*X)-1`, `day = 1`. An example is Samhein which is typically November 1. +This document will refer to the 8 season segments as follows: + +| Season | Events | Dates | +| - | :---: | :--: | +| Spring1 | Spring Equinox to Spring Cross Quarter | March 21 - May 01 | +| Spring2 | Spring Cross Quarter to Summer Solstice | May 01 - June 21 | +| Summer1 | Summer Solstice to Summer Cross Quarter | June 21 - August 01 | +| Summer2 | Summer Cross Quarter to Summer Equinox | August 01 - September 21 | +| Fall1 | Fall Equinox to Fall Cross Quarter | September 21 - November 01 | +| Fall2 | Fall Cross Quarter to Winter Solstice | November 01 - December 21 | +| Winter1 | Winter Solstice to Winter Cross Quarter | December 21 - February 01 | +| Winter2 | Winter Cross Quarter to Spring Equinox | February 01 - March 21 | + # Components ## 1. Front End @@ -57,22 +72,32 @@ using Postman, testing the Weather Fetcher, etc. ### Pages +- App shall have a simple layout with all pages linked and visible from Main. +- Data entry may be done in a pop-up, modal, or subpage if necessary. + #### Main *Initial Versions - Simple Data Entry* --- -8 sections which contain (three?) data input fields: +8 sections which contain data input fields for: - Zip Code - Lat & Long (used to look up the zip, not sent to cache DB or weather service) - Nickname +Zip is a required field to successfully submit the data. Nickname is optional. +Lat and Long can be ignored and will be autopopulated on submit based on the Zip, +or if they are both populated and Zip is blank, then the submit function shall +calculate Zip based off of them. + *Formal Versions - Wheel Layout* --- +Includes and expands upon the previous section. + Circular layout representing the Celtic season wheel with 'LAST_UPDATE_DATE' in the center so the user knows when the highs and lows were last refreshed. @@ -84,11 +109,27 @@ one glow as it gets approached. So for June 21, Spring2 and Summer1 would both glow at 50% since that's the day they transition. Then by mid July it would only be Summer1 which glows, and at the end of July Summer1 would be dim and Summer2 would be glowing more. Maybe keep this in play after the hand works too. -- (TBD: If someone is in the southern hemisphere, how to know that and do the hand in a 180 degree from what it'd be up north? Maybe the location API can be used to know that based on the latitude being positive or negative if only a zip code is provided.) +- Hand and glowing need to be in the opposite direction if the user has more +than half of their latitudes as negatives. ##### Actions -- IF zip == "" && lat != "" && long != "" THEN zip = LOOKUP(lat, long); +- Location Submission {submitLocation(), onLocationSave()} + - `IF zip.isEmpty() && lat.isEmpty() && long.isEmpty() + THEN ERROR('Zip code must be provided! You may use lat/long to find it if needed.'); + FI` + - `IF zip.isEmpty() && (lat.isEmpty() || long.isEmpty()) + THEN ERROR('Coordinate data not filled out completely.'); + FI` + - `IF zip.isEmpty() && !lat.isEmpty() && !long.isEmpty() + THEN zip = LOOKUP(lat, long); + FI` + - If the user opts to provide a lat and long, find the zip code. + - `IF !zip.isEmpty() + THEN (lat, long) = LOOKUP(zip); + FI` + - This overwrites the user's lat and long for what is actually going to + checked by the weather API. #### Settings @@ -102,8 +143,8 @@ would be glowing more. Maybe keep this in play after the hand works too. - 'Week : Median / Center-Most' - 'Week : Mode / Most Common' - 'Only : Today' - - ?'Only : Tomorrow' - - ?'Only : Today + 7' + - 'Only : Tomorrow' + - 'Only : Extended (Today + 7)' - FALSE: - TextEdit: 'API Key' (REQUIRED) - 'If not using the cache server, you'll need to provide your own API key for TBD weather service.' @@ -113,20 +154,18 @@ would be glowing more. Maybe keep this in play after the hand works too. - Fahrenheit (^F) - Celsius (^C) - TextEdit: 'Preferred High' - - Radio Group: 'Relativity? (TBD)' - - Less Than - - Greater Than + - Whole Numbers / Integers Only + - Radio Group: '(TBD: Relativity?)' + - Option: 'Less Than' + - Option: 'Greater Than' - Checkbox: 'Equal To' - - TextEdit: 'referred Low' - - Radio Group: 'Relativity? (TBD)' - - Less Than - - Greater Than + - TextEdit: 'Preferred Low' + - Whole Numbers / Integers Only + - Radio Group: '(TBD: Relativity?)' + - Option: 'Less Than' + - Option: 'Greater Than' - Checkbox: 'Equal To' -### Description - -### Requirements - ## 2. Database ### Description From 2a95801d5794a476cad9653afdb66db254f7322b Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 19 Aug 2026 14:02:28 -0700 Subject: [PATCH 5/7] Add abbreviations for the seasons, using Spanish `verano` as inspiration for summer's. --- Design.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Design.md b/Design.md index ec97cb5..10bdde2 100644 --- a/Design.md +++ b/Design.md @@ -30,16 +30,16 @@ An example is Samhein which is typically November 1. This document will refer to the 8 season segments as follows: -| Season | Events | Dates | -| - | :---: | :--: | -| Spring1 | Spring Equinox to Spring Cross Quarter | March 21 - May 01 | -| Spring2 | Spring Cross Quarter to Summer Solstice | May 01 - June 21 | -| Summer1 | Summer Solstice to Summer Cross Quarter | June 21 - August 01 | -| Summer2 | Summer Cross Quarter to Summer Equinox | August 01 - September 21 | -| Fall1 | Fall Equinox to Fall Cross Quarter | September 21 - November 01 | -| Fall2 | Fall Cross Quarter to Winter Solstice | November 01 - December 21 | -| Winter1 | Winter Solstice to Winter Cross Quarter | December 21 - February 01 | -| Winter2 | Winter Cross Quarter to Spring Equinox | February 01 - March 21 | +| Season | Abbr. | Events | Dates | +| -- | :-: | :----: | :---: | +| Spring1 | S1 | Spring Equinox to Spring Cross Quarter | March 21 - May 01 | +| Spring2 | S2 | Spring Cross Quarter to Summer Solstice | May 01 - June 21 | +| Summer1 | V1 | Summer Solstice to Summer Cross Quarter | June 21 - August 01 | +| Summer2 | V2 | Summer Cross Quarter to Summer Equinox | August 01 - September 21 | +| Fall1 | F1 | Fall Equinox to Fall Cross Quarter | September 21 - November 01 | +| Fall2 | F2 | Fall Cross Quarter to Winter Solstice | November 01 - December 21 | +| Winter1 | W1 | Winter Solstice to Winter Cross Quarter | December 21 - February 01 | +| Winter2 | W2 | Winter Cross Quarter to Spring Equinox | February 01 - March 21 | # Components From bde8a74880740180a03f8bb8e400c238083e59a5 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Thu, 20 Aug 2026 10:24:03 -0700 Subject: [PATCH 6/7] Lots of API related information for the applications. No internet access so cannot review weather services yet. --- Design.md | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 1 deletion(-) diff --git a/Design.md b/Design.md index 10bdde2..343af40 100644 --- a/Design.md +++ b/Design.md @@ -212,6 +212,7 @@ objects, constraints, schedules, etc being added in the revision. Example: ``` - Scripts shall have a consistent style and formatting. Developer may use the style of their choice. +- Scripts shall assume a Docker environment using image `debian:trixie-slim`. ### Tables @@ -340,8 +341,145 @@ For each `ZIP_CODE`, calculate the following: ## 4. Response API +Developer: TBD + +Language: Developer's choice. +Node.js using Express recommended unless a better use case can be made. + ### Description +Listener API which receives requests from the front end and queries the database on their behalf. This program is responsible for adding new `ZIP_CODE`'s to the database and requesting that the weatherman load the data for these when that is done. + ### Requirements -- +- Program shall listen JSON #1 in the appendix as its initiating request. +- Program shall provide JSON #2 as a response to the request. +- Program shall access the database in section #2 as user `geo`. +- Program shall acquire the weather data from the `loc_weather_agg` table.. +- 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. + +# Appendix - JSON Requests and Responses + +## 1. Request: Front End to Response API + +- Data shall be de-duplicated so that any one zip only appears once. +- All payloads shall contain the version number so that the server knows which +response to provide, in case the format changes in the future. +- Commas are acceptable after every data element, even ending ones. + +```json +{ + "version": "1.0", + "data": [ + "zip_code": "85901", + "zip_code": "86004", + "zip_code": "86001", + ], +} +``` + +## 2. Response: Response API to Front End + +- Version shall be included so that the front end knows how to parse the response. +- Commas are acceptable after every element, including the ends of lists. +- Zip codes and dates shall be treated as strings. +- Temperature data shall be treated like numbers. + +```json +{ + "version": "1.0", + "data": [ + { + "zip_code": "85901", + "last_update_date": "1900-01-01T15:00:00+0000", + "mean_high": 64.237, + "mean_low": 38.758, + "median_high": 65, + "median_low": 43, + "mode_high": 68, + "mode_low": 47, + "today_high": 58, + "today_low": 33, + "tomorrow_high": 61, + "tomorrow_low": 37, + }, + { + "zip_code": "86004", + "last_update_date": "1900-01-01T15:00:00+0000", + "mean_high": 45.46, + "mean_low": 22.235, + "median_high": 45, + "median_low": 19, + "mode_high": 42, + "mode_low": 22, + "today_high": 46, + "today_low": 25, + "tomorrow_high": 52, + "tomorrow_low": 12, + }, + { + "zip_code": "86001", + "last_update_date": "1900-01-01T15:00:00+0000", + "mean_high": 45.64, + "mean_low": 22.532, + "median_high": 44, + "median_low": 18, + "mode_high": 41, + "mode_low": 21, + "today_high": 45, + "today_low": 24, + "tomorrow_high": 51, + "tomorrow_low": 11, + }, + ], +} + +``` + +## 3. Request: Applications to Weather Provider (TBD) + +(TBD: How to parse a request to the weather service.) + +## 4. Response: Weather Provider (TBD) to Applications + +(TBD: How to read a response from the weather service.) + +## 5. Request: New ZIP_CODE Needs Processed + +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`. + +```json +{ + "data": "run", +} +``` + +## 6. Response: ZIP_CODE Data Now Available + +Response from `weatherman` program to `reporter`. + +If the `reporter` sees this, then it continues with building a response for the front end. + +```json +{ + "data": "ready", +} +``` + +## 7. Response: Issue Loading New ZIP_CODE's + +Response from `weatherman` program to `reporter`. + +If the `reporter` happens to see this, it provides + +```json +{ + "data": "error", + "error": "Message about what went wrong, which may get forwarded to the user.", +} +``` From 6b883fc6cbe7ee62d9679ffbec96cd6421158a10 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Thu, 20 Aug 2026 13:25:07 -0700 Subject: [PATCH 7/7] Continue adding JSON information and also begin working on the aggregation SQL. --- Design.md | 110 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 99 insertions(+), 11 deletions(-) diff --git a/Design.md b/Design.md index 343af40..b054e4f 100644 --- a/Design.md +++ b/Design.md @@ -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.", +} +```