PWA Pool maintenance app using Akka-Http, Quill, uPickle, ScalaJs, Laminar, JoddMail and Postgresql.
- brew install postgresql
- brew install node
- npm install jsdom
Provide valid configuration for:
- Postgresql
- SMTP
in these conf files:
- jvm/src/it/resources/test.server.conf
- jvm/src/main/resoures/server.conf
None of the following Scalajs bundling options yield satisfactory results:
- ScalaJS Bundler: https://scalacenter.github.io/scalajs-bundler/index.html
- Sbt Web: https://github.com/sbt/sbt-web
- Sbt Web ScalaJS: https://github.com/vmunier/sbt-web-scalajs
There is no Scalajs bundling standard.
Using ( libraryDependencies += "org.scala-js" %% "scalajs-env-jsdom-nodejs" % "1.1.0" ) in plugins.sbt provides access to a NodeJs environment ( github.com/scala-js/scala-js-env-jsdom-nodejs ) for testing. Yet the following jsEnv shortcomings exist:
- NodeJs - Window object not supported.
- NodeJs and Jsdom - Window object supported. IndexedDB not supported. Other Windows libraries likely not supported.
- PhantomJS - Throws exception. Advanced configuration not available.
- Selenium - Doesn't support headless.
Use utest ( www.lihaoyi.com/post/uTesttheEssentialTestFrameworkforScala.html ) for testing.
[ shared ]
- sbt [ interactive session ]
- project shared/clean | compile | test
[ jvm ]
- sbt [ interactive session ]
- project jvm/clean | compile | test | it:test | run
[ js ]
- sbt [ interactive session ]
- project js/clean | fastLinkJS | fullLinkJS
- open target/scala-2.13/classes/public/index.html and:
- via Intellij, click target browser in right top corner OR
- via VSCode, right click open with Live Server ( VSCode ) ( must install Live Server extension )
- open developer tools in index.html browser tab
- sbt sharedJVM/clean test
- sbt jvm/clean it:test
jvm
- sbt jvm/run [ curl -v http://localhost:7979/now ]
js
- open target/scala-2.13/classes/public/index.html and:
- via Intellij, click target browser in right top corner OR
- via VSCode, right click open with Live Server ( VSCode ) ( must install Live Server extension )
- open developer tools in index.html browser tab
See sbt-native-packager ( www.scala-sbt.org/sbt-native-packager/formats/universal.html ) for details on universal:packageZipTarball.
jvm
- sbt jvm/universal:packageZipTarball
js
- sbt js/clean fullLinkJS
- sbt js/universal:packageZipTarball
The Router only emits: 200, 400, 401, 500
- Command => Fault | Event
- Entity => Fault | State
- CommandProxy => EventHandler
- EntityProxy => StateHandler
- Register( email ) => Registering( inProgress )
- Login( email, pin ) => LoggedIn( account )
- Deactivate( license ) => Deactivated( account )
- Reactivate( license ) => Reactivated( account )
- Register ( email )
- Login ( email, pin )
- Account ( license, email, pin, activated, deactivated )
- Pool ( pool )
- Pool
- Pools -> Pool
- Surfaces -> Surface
- Pumps -> Pump
- Timers -> Timer -> TimerSettings
- Heaters -> Heater -> HeaterSettings -> HeaterSetting
- Maintenance
- Measurments -> Measurement **
- Cleanings -> Cleaning **
- Chemicals -> Chemical **
- Expenses
- Supplies -> Supply **
- Repairs -> Repair **
** Charts -> measurements, cleanings, chemicals, supplies and repairs.
Public url: /
- /now
- /register
- /login
- /deactivate
- /reactivate
API url: /api/v1/pool
- /pools /add /update
- /surfaces /add /update
- /pumps /add /update
- /timers /add /update
- /timersettings /add /update
- /heaters /add /update
- /heatersettings /add /update
- /measurements /add /update
- /cleanings /add /update
- /chemicals /add /update
- /supplies /add /update
- /repairs /add /update
- License(key)
- Account(license, email, pin, activated, deactivated)
- Pool(id, license, name, built, volume)
- Surface(id, poolId, installed, kind)
- Pump(id, poolId, installed, model)
- Timer(id, poolId, installed, model)
- TimerSetting(id, timerId, created, timeOn, timeOff)
- Heater(id, poolId, installed, model)
- HeaterSetting(id, heaterId, temp, dateOn, dateOff)
- Measurement(id, poolId, measured, temp, totalHardness, totalChlorine, totalBromine, freeChlorine, ph, totalAlkalinity, cyanuricAcid)
- Cleaning(id, poolId, cleaned, brush, net, vacuum, skimmerBasket, pumpBasket, pumpFilter, deck)
- Chemical(id, poolId, added, chemical, amount, unit)
- Supply(id, poolId, purchased, cost, supply, amount, unit)
- Repair(id, poolId, repaired, cost, repair)
- Email(id, license, address, processed, valid)
- Fault(id, dateOf, timeOf, code, cause)
- License
- Account 1 ---> * Pool
- Pool 1 ---> * Surface | Pump | Timer | Heater | Measurement | Cleaning | Chemical | Supply | Repair
- Timer 1 ---> * TimerSetting
- Heater 1 ---> * HeaterSetting
- Fault
Measured in ppm ( parts per million ).
Measurement | Range | Good | Ideal |
---|---|---|---|
total chlorine (tc = fc + cc) | 0 - 10 | 1 - 5 | 3 |
free chlorine (fc) | 0 - 10 | 1 - 5 | 3 |
combinded chlorine (cc = tc - fc) | 0.0 - 0.5 | 0.0 - 0.2 | 0.0 |
ph | 6.2 - 8.4 | 7.2 - 7.6 | 7.4 |
calcium hardness | 0 - 1000 | 250 - 500 | 375 |
total alkalinity | 0 - 240 | 80 - 120 | 100 |
cyanuric acid | 0 - 300 | 30 - 100 | 50 |
total bromine | 0 - 20 | 2 - 10 | 5 |
salt | 0 - 3600 | 2700 - 3400 | 3200 |
temperature | 50 - 100 | 75 - 85 | 82 |
** Units of Measure - oz, gl, lb
- Liquids measured in: gallons ( gl ) and liters ( l ).
- Granules measured in: pounds ( lbs ) and kilograms ( kg ).
- LiquidChlorine ( gl/l )
- Trichlor ( tablet )
- Dichlor ( lbs/kg )
- CalciumHypochlorite ( lbs/kg )
- Stabilizer ( lbs/kg )
- Algaecide ( gl/l )
- MuriaticAcid ( gl/l )
- Salt ( lbs/kg )
- Chlorine for pool.
- Chlorine tablets for pool filtration system.
- Pool Shock
Suggested solutions to chemical imbalances.
- high ph - Sodium Bisulfate
- low ph - Sodium Carbonate, Soda Ash
- high alkalinity - Muriatic Acid, Sodium Bisulfate
- low alkalinity - Sodium Bicarbonate, Baking Soda
- calcium hardness - Calcium Chloride
- low chlorine - Chlorine Tablets, Granules, Liquid
- algae - Algaecide, Shock
- stains - Stain Identification Kit, Stain Remover
- descriptions - cleanings, measurements
- images - add, edit, chart
- measurements - line chart ( x = date, y = chemical )
- cleanings - line chart ( x = date, y = month )
- chemicals - bar chart ( x = date, y = amount, c = chemical )
- supplies - bar chart ( x = date, y = cost, c = item )
- repairs - line chart ( x = date, y = cost )
- Format: yyyy-MM-dd
- String: 1999-01-01, 1999-12-16
- Int: 19990101, 19991216
- Format: HH:mm
- String: 01:01, 19:14
- Int: 101, 1914
- conf:
- on osx intel: /usr/local/var/postgres/postgresql.conf : listen_addresses = ‘localhost’, port = 5432
- on osx m1: /opt/homebrew/var/postgres/postgresql.conf : listen_addresses = ‘localhost’, port = 5432
- build.sbt:
- IntegrationTest / javaOptions += "-Dquill.binds.log=true"
- run:
- brew services start postgresql
- logs:
- on osx intel: /usr/local/var/log/postgres.log
- on m1: /opt/homebrew/var/log/postgres.log
Example database url: postgresql://localhost:5432/pool?user=mycomputername&password='"
- psql postgres
- CREATE DATABASE pool OWNER [your computer name];
- GRANT ALL PRIVILEGES ON DATABASE pool TO [your computer name];
- \l
- \q
- psql pool
- \i ddl.sql
- \q
Alternatively run: psql -d pool -f ddl.sql ( see RouterTest )
- psql pool
- \i ddl.sql
- \q
- psql postgres
- drop database pool;
- \q
See these files:
- jvm/src/it/resources/test.server.conf
- jvm/src/main/resoures/server.conf
To eliminate unused ExecutionContext variable errors, this scalac option must be set in the build.sbt:
scalacOptions ++= Seq(
"-Ywarn-macros:after"
)
Quill macros use the implicit ExecutionContext. The Quill ctx.transaction code does not.
Copyright (c) [2022 - 2025] [Objektwerks]
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.