Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
#+TITLE: Behave Polylith * Prerequisites + OpenJDK 17 + [[https://github.com/babashka/babashka#installation][Babashka]] + [[https://clojure.org/guides/install_clojure][Clojure]] + Postgres (>=12) * Getting Started ** Emacs/CIDER 1. Pull down the repository (~git clone git@gitlab.com:sig-gis/behave-polylith~) 1. Pull down the submodules (~git submodule update --init --remote~) 1. Follow the Datomic Setup (see below) 1. Start the Datomic Transactor (see below) 1. Open ~development/user.cljs~ in Emacs 1. Start the CIDER nREPL ~cider-jack-in-clj&cljs~ 1. Choose ~figwheel-main~ and ~dev~ for the front-end build. 1. Open ~http://localhost:8080~ in your browser. * Architecture ** Polylith This project adopts a Polylith design, which allows both a mono-repo experience across mulitple projects. *** What is a Polylith? The [[https://polylith.gitbook.io/polylith/][Polylith]] project organization method attempts to marry the best parts of operating within a single Monorepo (single source of truth, DRY code, less repos to manage), with the benefits of having single repos for each project (customization). The Polylith design is made up of three parts: Components, Bases, and Projects. *** Components This is the most basic unit for Polylith. Ideally, Components require few, if any, dependencies. Each component always has an ~<component>.interface~ namespace, which includes the public functions that are meant to be exported from the component. Components (ideally) are written in the Clojure Common (~*.cljc~) format so as to be used in both CLJ and CLJS environments. *** Bases Bases are groups of components and other dependencies that constitute a middle-tier of the Polylith. Bases can be project-specific, but ideally are general enough to be used across multiple projects. Bases typically only have a ~main.clj[sc]~ file. *** Projects Projects are made up of multiple bases and components. Many projects can exist within a Polylith, which enables a great deal of customization while also sharing components and bases across projects. ** Components Library The projects take advantage of the [[https://gitlab.com/sig-gis/behave-components][Behave Components]] shared UI components library. Check out the docs on the Behave Components page to learn more. ** Reagent & Re-Frame The projects use both [[https://reagent-project.github.io/][Reagent]] and [[https://day8.github.io/re-frame][Re-Frame]] to manage application state and application logic. Re-Frame was adopted to reduce tight coupling between views/components and the data/actions that are used within them. ** Datalog & Datoms The projects store data in Datoms and performs queries using the Datalog syntax. The back-end access Datoms using [[https://github.com/replikativ/datahike][DataHike]], and the front-end accesses Datoms through [[https://github.com/tonsky/datascript][DataScript]]. [[https://github.com/denistakeda/re-posh][Re-Posh]] is also used to enable subscriptions on DataScript entities, reducing view logic. * Projects ** App (=projects/behave=) *** Schema #+begin_src dot :results value :file projects/behave/docs/schema.png digraph GitHub { graph [rankdir = "LR"] node [shape = record] Tool [label="Tools |{ :bp/uuid | string } |{ :tool/name | string } |{ :tool/order | number } |{ :tool/translation-key | string } |{ :tool/help-key | string }"] SubTool [label="Subtool |{ :bp/uuid | string } |{ :subtool/name | string } |{ :subtool/order | number } |{ :subtool/autocompute? | boolean } |{ :subtool/translation-key | string } |{ :subtool/help-key | string }"] SubToolVariable [label="Subtool-Variable |{ :bp/uuid | string } |{ :subtool-variable/io | keyword } |{ :subtool-variable/order | number } |{ :subtool-variable/cpp-namespace-uuid | string } |{ :subtool-variable/cpp-mclass | string } |{ :subtool-variable/cpp-function-uuid | string } |{ :subtool-variable/translation-key | string } |{ :subtool-variable/help-key | string }"] Variable [label="Variable |{ :bp/uuid | string } |{ :variable/name | string } |{ :variable/bp6-label | string } |{ :variable/bp6-code | string } |{ :variable/kind | keyword} |{ :variable/translation-key | string } |{ :variable/native-decimals | double } |{ :variable/english-decimals | double } |{ :variable/metric-decimals | double } |{ :variable/maximum | double } |{ :variable/minimum | double } |{ :variable/default-value | double } |{ :variable/map-units-convertible? | double } "] List [label="List |{ :bp/uuid | string } |{ :list/name | string } |{ :list/translation-key | string } "] ListOptions [label="List-Options |{ :bp/uuid | string } |{ :list-option/name | string } |{ :list-option/default | string } |{ :list-option/value | string } |{ :list-option/order | string } |{ :list-option/translation-key | string } "] Dimension [label="Dimension |{ :bp/uuid | string } |{ :dimension/name | string } |{ :dimension/cpp-enum-uuid | string } "] Unit [label="Unit |{ :bp/uuid | string } |{ :unit/name | string } |{ :unit/short-code | string } |{ :unit/system | string } |{ :unit/cpp-enum-member-uuid | string } "] DomainSet [label="Domain-Set |{ :bp/uuid | string } |{ :domain-set/name | string } "] Domain [label="Domain |{ :bp/uuid | string } |{ :domain/name | string } |{ :domain/decimals | string } "] Tool -> SubTool [label=":tool/subtools" taillabel=1 headlabel=N] SubTool -> SubToolVariable [label=":subtool/variables" taillabel=1 headlabel=N] Variable -> SubToolVariable [label=":variable/subtool-variables" taillabel=1 headlabel=N] Variable -> List [label=":variable/list" taillabel=1 headlabel=1] Variable -> Domain [label=":variable/domain-uuid" taillabel=1 headlabel=1] Variable -> Unit [label=":variable/native-unit-uuid" taillabel=1 headlabel=1] Variable -> Unit [label=":variable/english-unit-uuid" taillabel=1 headlabel=1] Variable -> Unit [label=":variable/metric-unit-uuid" taillabel=1 headlabel=1] List -> ListOptions [label=":list/options" taillabel=1 headlabel=N] Dimension -> Unit [label=":dimension/units" taillabel=1 headlabel=N] DomainSet -> Domain [label=":domain-set/domains" taillabel=1 headlabel=N] Domain -> Dimension [label=":domain/dimension-uuid" taillabel=1 headlabel=1] Domain -> Unit [label=":domain/native-unit-uuid" taillabel=1 headlabel=1] Domain -> Unit [label=":domain/english-unit-uuid" taillabel=1 headlabel=1] Domain -> Unit [label=":domain/metric-unit-uuid" taillabel=1 headlabel=1] } #+end_src #+RESULTS: [[file:projects/behave/docs/schema.png]] *** Building the Behave UberJAR 1. Navigate to ~projects/behave~. All paths described here will use this directory as root. 2. Add/edit the ~resources/config.edn~ for your deployment. Below is an example file: #+BEGIN_SRC clojure ;; resources/config.edn {:database {:config {:store {:backend :file :path "~/.behave/db"}}} :site {:title "BehavePlus 7" :description "Wildfire Analysis toolkit."} :server {:http-port 8007 :mode "prod"} :vms {:secret-token "<vms-secret-token>"}} #+END_SRC 3. Compile ClojureScript #+BEGIN_SRC bash bb build-js #+END_SRC 4. Build the UberJAR NOTE: The uberjar build process requires triangulum to be available in the deps.edn located at the user level (i.e. /home/<user>//.clojure/deps.edn). #+begin_src clojure {sig-gis/triangulum {:git/url "https://github.com/sig-gis/triangulum" :sha "<latest-sha>"}} #+end_src #+BEGIN_SRC bash bb uber #+END_SRC 4. Congratulations! You're now the owner of an UberJAR. (i.e. ~target/behave7-2023.10.19-97f1ef9-standalone.jar~) ** Behave CMS (=projects/behave_cms=) *** Schema TODO *** Datomic Setup **** Download & Setup Datomic Pro #+BEGIN_SRC bash mkdir -p ~/.datomic cd ~/.datomic curl -O https://datomic-pro-downloads.s3.amazonaws.com/1.0.7075/datomic-pro-1.0.7075.zip unzip *.zip ln -s $PWD/datomic-pro-1.0.7075 $PWD/current echo 'export PATH="$HOME/.datomic/current/bin:$PATH"' >> ~/.bashrc # Or ~/.zshrc #+END_SRC **** Setting up PostgreSQL for Datomic Be sure that PostgreSQL is running on port 5432. #+BEGIN_SRC bash cd /bases/datomic_store/sql/ psql -U postgres -f 01_setup.sql # Creates the Datomic DB, User psql -U datomic datomic -f 02_tables.sql # Sets up the KV table #+END_SRC **** Running the Transactor #+BEGIN_SRC bash bb transactor #+END_SRC **** Running the Datomic Console #+BEGIN_SRC bash bb console --port <port> #+END_SRC Then visit [[http://localhost:8000/browse][localhost:8000/browse]] **** Restoring CMS using a backup file #+begin_src sh bb restore --file <datomic-2024-##-##.dump> #+end_src * Behave-Lib The "behave-lib" directory includes the build process for generating a WASM file using c++ code from "behave-mirror" and "include" directories. Here's Checklist for when new c++ code needs to be transcribed into wasm and be available via the Behave CMS. *** Create new WASM file **** Updating Hatchet's idl output and copying to behave.idl - [ ] Run the pair of header files (i.e. surface.h and SIGSurface.h) through Hatchet (see Hatchet README). - [ ] Replace/Edit text - [ ] "std_string" with "[Const] DOMString" - [ ] "string" with [Const] DOMString - [ ] Any type ref to other classes with "[Ref] SIG<module>" - [ ] Add [Const] to beginning of function in behave.idl for any functions in header file ending in const. - [ ] Copy missing functions to the SIG<module> interface in "behave-lib/include/idl/behave.idl" - [ ] Add new enums in "behave-lib/include/idl/behave.idl" - [ ] For each enum in behave.idl there should be an enum entry in "src/cljs/behave/lib/enums.cljs" **** Updating CLJS file in Behave with Hatchet's output. - [ ] Add missing functions from hatchet's output cljs file to "behave/src/cljs/behave/lib/<model>.cljs" - [ ] Add this to the end of the file #+begin_src clojure (def ^:export ns-public-fns (update-keys (ns-publics 'behave.lib.ignite) name)) #+end_src **** Updating enums.cpp - [ ] Add mapping for new enums in "behave-lib/include/cpp/emscripten/enums.cpp" **** Updating behave_extern.js - [ ] Update behave_extern.js with functions from cljs file **** Create new WASM file - [ ] In "behave-lib" run #+begin_src sh make install #+end_src *** Import EDN files from hatchet into CMS - [ ] Both edn files have been created through hatchet (i.e. surface.edn and SIGSurface.edn) - [ ] Run a modified version of the code block below for the module that needs updating #+begin_src clojure (ns cms-import) ;; Combine edn files from hatchet (cms-import {:behave-file "path/to/hatchet/output/surface.edn" :sig-adapter-file "path/to/hatchet/output/SIGSurface.edn" :out-file-name "SIGSurface.edn" :from-key :Surface :to-key :SIGSurface}) (add-export-file-to-conn "./cms-exports/SIGSurface.edn" conn) #+end_src * Schema ERDs ** VMS This schema is used for the Behave VMS. It largely impacts the rendering UI of the Behave VMS and the Application. #+begin_src dot :results value :file projects/behave/docs/vms-schema.png // Relations (NOTE when a relation attribute of type :db/type/string instead of type :db.type/ref, this means the value is a UUID that matches the :bp/uuid of the related entity.) digraph GitHub { graph [rankdir = "LR"] node [shape = record] //---------------------------------------------------------------------------------------------- // VMS Schema Starts Here //---------------------------------------------------------------------------------------------- User [label="User |{ :bp/uuid | string } |{ :user/name | string } |{ :user/email | string } |{ :user/password | string } |{ :user/reset-key | string } |{ :user/verified? | boolean } |{ :user/super-admin? | boolean } |{ :user/help-key | string } "] //---------------------------------------------------------------------------------------------- Application [label="Application |{ :bp/uuid | string } |{ :application/name | string } |{ :application/version-major | number } |{ :application/version-minor | number } |{ :application/version-patch | number } |{ :application/version | tuple } |{ :application/help-key | string } "] Application -> Module [label=":application/modules" taillabel=1 headlabel=N] Application -> Tool [label=":application/tools" taillabel=1 headlabel=N] Application -> HelpPage [label=":application/help-key" taillabel=1 headlabel=1] Application -> Translation [label=":application/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Module [label="Module |{ :bp/uuid | string } |{ :module/name | string } |{ :module/order | number } "] Module -> Submodule [label=":module/submodules" taillabel=1 headlabel=N] Module -> Diagram [label=":module/diagram" taillabel=1 headlabel=N] Module -> HelpPage [label=":module/help-key" taillabel=1 headlabel=1] Module -> Translation [label=":module/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Submodule [label="Submodule |{ :bp/uuid | string } |{ :submodule/name | string } |{ :submodule/order | number } |{ :submodule/io | keyword } |{ :submodule/research? | boolean } |{ :submodule/conditionals-operator | keyword } "] Submodule -> Group [label=":submodule/groups" taillabel=1 headlabel=N] Submodule -> Conditional [label=":submodule/conditionals" taillabel=1 headlabel=N] Submodule -> HelpPage [label=":submodule/help-key" taillabel=1 headlabel=1] Submodule -> Translation [label=":submodule/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Group [label="Group |{ :bp/uuid | string } |{ :group/name | string } |{ :group/order | long } |{ :group/io | keyword } |{ :group/research? | boolean } |{ :group/repeat? | boolean } |{ :group/max-repeat | long } |{ :group/conditionals-operator | keyword } "] Group -> Group [label=":group/children" taillabel=1 headlabel=1] Group -> Conditional [label=":group/conditionals" taillabel=1 headlabel=N] Group -> GroupVariable [label=":group/group-variables" taillabel=1 headlabel=N] Group -> HelpPage [label=":group/help-key" taillabel=1 headlabel=1] Group -> Translation [label=":group/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- GroupVariable [label="Group-Variable |{ :bp/uuid | string } |{ :group-variable/cpp-class | string } |{ :group-variable/cpp-function | string } |{ :group-variable/cpp-namespace | string } |{ :group-variable/cpp-parameter | string } |{ :group-variable/order | long} |{ :group-variable/research? | boolean } "] GroupVariable -> CppClass [label=":group-variable/cpp-class (uuid)" taillabel=1 headlabel=1] GroupVariable -> CppFunction [label=":group-variable/cpp-function (uuid)" taillabel=1 headlabel=1] GroupVariable -> CppNamespace [label=":group-variable/cpp-namespace (uuid)" taillabel=1 headlabel=1] GroupVariable -> CppParameter [label=":group-variable/cpp-parameter (uuid)" taillabel=1 headlabel=1] GroupVariable -> HelpPage [label=":group-variable/help-key" taillabel=1 headlabel=1] GroupVariable -> Translation [label=":group-variable/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- CppClass [label="Cpp.Class |{ :bp/uuid | string } |{ :cpp.class/name | string } "] CppClass -> CppFunction [label=":cpp.class/function" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- CppFunction [label="Cpp.Function |{ :bp/uuid | string } |{ :cpp.function/name | string } |{ :cpp.function/return-type | stringema} "] CppFunction -> CppParameter [label=":cpp.function/parameter" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- CppParameter [label="Cpp.Parameter |{ :bp/uuid | string } |{ :cpp.parameter/name | string } |{ :cpp.parameter/order | number } |{ :cpp.parameter/type | string } "] //---------------------------------------------------------------------------------------------- CppNamespace [label="Cpp.Namespace |{ :bp/uuid | string } |{ :cpp.namespace/name | string } "] CppNamespace -> CppClass [label=":cpp.namespace/class" taillabel=1 headlabel=N] CppNamespace -> CppEnum [label=":cpp.namespace/enum" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- CppEnum [label="Cpp.Enum |{ :bp/uuid | string } |{ :cpp.enum/name | string } "] CppEnum -> CppEnumMember [label=":cpp.enum/enum-member" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- CppEnumMember [label="Cpp.Enum-member |{ :bp/uuid | string } |{ :cpp.enum-member/name | string } |{ :cpp.enum-member/value | number } "] //---------------------------------------------------------------------------------------------- Tool [label="Tools |{ :bp/uuid | string } |{ :tool/name | string } |{ :tool/order | number } "] Tool -> SubTool [label=":tool/subtools" taillabel=1 headlabel=N] Tool -> HelpPage [label=":tool/help-key" taillabel=1 headlabel=1] Tool -> Translation [label=":tool/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- SubTool [label="Subtool |{ :bp/uuid | string } |{ :subtool/name | string } |{ :subtool/order | number } |{ :subtool/autocompute? | boolean } "] SubTool -> SubToolVariable [label=":subtool/variables" taillabel=1 headlabel=N] SubTool -> HelpPage [label=":subtool/help-key" taillabel=1 headlabel=1] SubTool -> Translation [label=":subtool/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- SubToolVariable [label="Subtool-Variable |{ :bp/uuid | string } |{ :subtool-variable/io | keyword } |{ :subtool-variable/order | long } |{ :subtool-variable/cpp-namespace-uuid | string } |{ :subtool-variable/cpp-mclass | string } |{ :subtool-variable/cpp-function-uuid | string } "] SubToolVariable -> HelpPage [label=":subtool-variable/help-key" taillabel=1 headlabel=1] SubToolVariable -> Translation [label=":subtool-variable/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Variable [label="Variable |{ :bp/uuid | string } |{ :variable/name | string } |{ :variable/bp6-label | string } |{ :variable/bp6-code | string } |{ :variable/kind | keyword} |{ :variable/native-decimals | double } |{ :variable/english-decimals | double } |{ :variable/metric-decimals | double } |{ :variable/maximum | double } |{ :variable/minimum | double } |{ :variable/default-value | double } |{ :variable/map-units-convertible? | boolean } "] Variable -> GroupVariable [label=":variable/group-variables" taillabel=1 headlabel=N] Variable -> SubToolVariable [label=":variable/subtool-variables" taillabel=1 headlabel=N] Variable -> List [label=":variable/list" taillabel=1 headlabel=1] Variable -> Domain [label=":variable/domain-uuid" taillabel=1 headlabel=1] Variable -> Unit [label=":variable/native-unit-uuid" taillabel=1 headlabel=1] Variable -> Unit [label=":variable/english-unit-uuid" taillabel=1 headlabel=1] Variable -> Unit [label=":variable/metric-unit-uuid" taillabel=1 headlabel=1] Variable -> Translation [label=":variable/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- List [label="List |{ :bp/uuid | string } |{ :list/name | string } "] List -> ListOption [label=":list/options" taillabel=1 headlabel=N] List -> Translation [label=":list/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- ListOption [label="List-Option |{ :bp/uuid | string } |{ :list-option/name | string } |{ :list-option/default | string } |{ :list-option/value | string } |{ :list-option/order | long } |{ :list-option/hide? | boolean } "] ListOption -> Translation [label=":list-option/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Dimension [label="Dimension |{ :bp/uuid | string } |{ :dimension/name | string } |{ :dimension/cpp-enum-uuid | string } "] Dimension -> Unit [label=":dimension/units" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- Unit [label="Unit |{ :bp/uuid | string } |{ :unit/name | string } |{ :unit/short-code | string } |{ :unit/system | string } |{ :unit/cpp-enum-member-uuid | string } "] //---------------------------------------------------------------------------------------------- DomainSet [label="Domain-Set |{ :bp/uuid | string } |{ :domain-set/name | string } "] DomainSet -> Domain [label=":domain-set/domains" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- Domain [label="Domain |{ :bp/uuid | string } |{ :domain/name | string } |{ :domain/decimals | string } "] Domain -> Dimension [label=":domain/dimension-uuid" taillabel=1 headlabel=1] Domain -> Unit [label=":domain/native-unit-uuid" taillabel=1 headlabel=1] Domain -> Unit [label=":domain/english-unit-uuid" taillabel=1 headlabel=1] Domain -> Unit [label=":domain/metric-unit-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Conditional [label="Conditional |{ :bp/uuid | string } |{ :conditional/type | keyword } |{ :conditional/operator | keyword } |{ :conditional/values | string } "] Conditional -> GroupVariable [label=":conditional/group-variable-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Diagram [label="Diagram |{ :bp/uuid | keyword } |{ :diagram/type | string } "] Diagram -> GroupVariable [label=":diagram/group-variable" taillabel=1 headlabel=1] Diagram -> GroupVariable [label=":diagram/input-group-variables" taillabel=1 headlabel=N] Diagram -> GroupVariable [label=":diagram/output-group-variables" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- Language [label="Language |{ :bp/uuid | keyword } |{ :language/name | string } |{ :language/short-code | string } "] Language -> Translation [label=":language/translation" taillabel=1 headlabel=1] Language -> HelpPage [label=":language/help-page" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Translation [label="Translation |{ :bp/uuid | keyword } |{ :translation/name | string } |{ :translation/key | string } |{ :translation/translation | string } "] //---------------------------------------------------------------------------------------------- HelpPage [label="Help-page |{ :bp/uuid | keyword } |{ :help-page/key | string } |{ :help-page/content | string } "] //---------------------------------------------------------------------------------------------- Link [label="Link |{ :bp/uuid | keyword } "] Link -> GroupVariable [label="link/source" taillabel=1 headlabel=1] Link -> GroupVariable [label="link/destination" taillabel=1 headlabel=1] } #+end_src #+RESULTS: [[file:projects/behave/docs/vms-schema.png]] ** Worksheet This schema is used to store instances of worksheet information in the Behave application. #+begin_src dot :results value :file projects/behave/docs/worksheet-schema.png // Relations (NOTE when a relation attribute of type :db/type/string instead of type :db.type/ref, this means the value is a UUID that matches the :bp/uuid of the related entity.) digraph GitHub { graph [rankdir = "LR"] node [shape = record] //---------------------------------------------------------------------------------------------- // Worksheet Schema Starts Here //---------------------------------------------------------------------------------------------- Worksheet [label="Worksheet |{ :bp/uuid | string } |{ :worksheet/run-description | string } |{ :worksheet/name | string } |{ :worksheet/created | long } |{ :worksheet/furthest-visited-step | keyword } |{ :worksheet/modules | keywords } "] Worksheet -> Note [label=":worksheet/notes" taillabel=1 headlabel=N] Worksheet -> InputGroup [label=":worksheet/input-groups" taillabel=1 headlabel=N] Worksheet -> RepeatGroup [label=":worksheet/repeat-groups" taillabel=1 headlabel=N] Worksheet -> Output [label=":worksheet/outputs" taillabel=1 headlabel=N] Worksheet -> ResultTable [label=":worksheet/result-table" taillabel=1 headlabel=1] Worksheet -> GraphSettings [label=":worksheet/graph-settings" taillabel=1 headlabel=1] Worksheet -> TableSettings [label=":worksheet/table-settings" taillabel=1 headlabel=1] Worksheet -> WorksheetDiagram [label=":worksheet/diagrams" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Note [label="Note |{ :bp/uuid | string } |{ :note/name | string } |{ :note/content | string } |{ :note/submodule | string } "] //---------------------------------------------------------------------------------------------- InputGroup [label="Input-Group |{ :bp/uuid | string } |{ :input-group/repeat-id | long } |{ :input-group/inputs | long } "] InputGroup -> Group [label=":input-group/group-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- RepeatGroup [label="Repeat-Group |{ :bp/uuid | string } |{ :repeat-group/group-uuid | string } |{ :repeat-group/repeats | long } |{ :repeat-group/inputs | long } "] RepeatGroup -> Group [label=":repeat-group/group-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Output [label="Output |{ :bp/uuid | string } |{ :output/enabled? | boolean } "] Output -> GroupVariable [label=":output/group-variable-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- ResultTable [label="Result-Table |{ :bp/uuid | string } "] ResultTable -> ResultHeader [label=":result-table/headers" taillabel=1 headlabel=N] ResultTable -> ResultRow [label=":result-table/rows" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- ResultHeader [label="Result-Header |{ :bp/uuid | string } |{ :result-header/repeat-id | long } |{ :result-header/order | long } |{ :result-header/units | string } "] ResultHeader -> GroupVariable [label=":result-header/group-variable-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- ResultRow [label="Result-Row |{ :bp/uuid | string } |{ :result-row/id | long } "] ResultRow -> ResultCell [label=":result-row/cells" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- ResultCell [label="Result-Cell |{ :bp/uuid | string } |{ :result-cell/value | string } "] ResultCell -> ResultHeader [label=":result-cell/header" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- TableSettings [label="Table-Settings |{ :bp/uuid | string } |{ :table-settings/enabled? | boolean } "] TableSettings -> TableFilter [label=":table-settings/filters" taillabel=1 headlabel=N] TableSettings -> MapUnitsSettings [label=":table-settings/map-units-settings" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- TableFilter [label="Table-Filter |{ :bp/uuid | string } |{ :table-filter/min | long } |{ :table-filter/max | long } |{ :table-filter/enabled? | boolean } "] TableFilter -> GroupVariable [label=":table-filter/group-variable-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- MapUnitsSettings [label="Map-Units-settings |{ :bp/uuid | string } |{ :map-units-settings/enabled? | boolean } |{ :map-units-settings/units | string } |{ :map-units-settings/map-rep-fraction | long } "] //---------------------------------------------------------------------------------------------- GraphSettings [label="Graph-Settings |{ :bp/uuid | string } |{ :graph-settings/enabled? | boolean } "] GraphSettings -> YAxisLimit [label=":graph-settings/y-axis-limits" taillabel=1 headlabel=N] GraphSettings -> GroupVariable [label=":graph-settings/x-axis-group-variable-uuid" taillabel=1 headlabel=1] GraphSettings -> GroupVariable [label=":graph-settings/z-axis-group-variable-uuid" taillabel=1 headlabel=1] GraphSettings -> GroupVariable [label=":graph-settings/z2-axis-group-variable-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- YAxisLimit [label="Y-Axis-Limit |{ :bp/uuid | string } |{ :y-axis-limit/min | long } |{ :y-axis-limit/max | long } "] YAxisLimit -> GroupVariable [label=":y-axis-limit/group-variable-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- WorksheetDiagram [label="Worksheet-diagram |{ :bp/uuid | string } |{ :worksheet.diagram/title | string } |{ :worksheet.diagram/row-id | long } "] WorksheetDiagram -> GroupVariable [label=":worksheet.diagram/group-variable-uuid" taillabel=1 headlabel=1] WorksheetDiagram -> Ellipse [label=":worksheet.diagram/ellises" taillabel=1 headlabel=N] WorksheetDiagram -> Arrow [label=":worksheet.diagram/arrows" taillabel=1 headlabel=N] WorksheetDiagram -> ScatterPlot [label=":worksheet.diagram/scatter-plots" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- Ellipse [label="Ellipse |{ :bp/uuid | string } |{ :ellipse/legend-id | string } |{ :ellipse/semi-major-axis | double } |{ :ellipse/semi-minor-axis | double } |{ :ellipse/rotation | long } |{ :ellipse/color | string } "] //---------------------------------------------------------------------------------------------- Arrow [label="Arrow |{ :bp/uuid | string } |{ :arrow/legend-id | string } |{ :arrow/length | double } |{ :arrow/rotation | double } |{ :arrow/color | string } |{ :arrow/dashed? | string } "] //---------------------------------------------------------------------------------------------- ScatterPlot [label="Scatter-Plot |{ :bp/uuid | string } |{ :scatter-plot/legend-id | string } |{ :scatter-plot/color | string } |{ :scatter-plot/x-coordinates | string } |{ :scatter-plot/y-coordinates | string } "] } #+end_src #+RESULTS: [[file:projects/behave/docs/worksheet-schema.png]] ** VMS + Worksheet This Documents the schema for both the behave and behave_cms project. #+begin_src dot :results value :file projects/behave/docs/schema.png // Relations (NOTE when a relation attribute of type :db/type/string instead of type :db.type/ref, this means the value is a UUID that matches the :bp/uuid of the related entity.) digraph GitHub { graph [rankdir = "LR"] node [shape = record] //---------------------------------------------------------------------------------------------- // VMS Schema Starts Here //---------------------------------------------------------------------------------------------- User [label="User |{ :bp/uuid | string } |{ :user/name | string } |{ :user/email | string } |{ :user/password | string } |{ :user/reset-key | string } |{ :user/verified? | boolean } |{ :user/super-admin? | boolean } |{ :user/help-key | string } "] //---------------------------------------------------------------------------------------------- Application [label="Application |{ :bp/uuid | string } |{ :application/name | string } |{ :application/version-major | number } |{ :application/version-minor | number } |{ :application/version-patch | number } |{ :application/version | tuple } |{ :application/help-key | string } "] Application -> Module [label=":application/modules" taillabel=1 headlabel=N] Application -> Tool [label=":application/tools" taillabel=1 headlabel=N] Application -> HelpPage [label=":application/help-key" taillabel=1 headlabel=1] Application -> Translation [label=":application/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Module [label="Module |{ :bp/uuid | string } |{ :module/name | string } |{ :module/order | number } "] Module -> Submodule [label=":module/submodules" taillabel=1 headlabel=N] Module -> Diagram [label=":module/diagram" taillabel=1 headlabel=N] Module -> HelpPage [label=":module/help-key" taillabel=1 headlabel=1] Module -> Translation [label=":module/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Submodule [label="Submodule |{ :bp/uuid | string } |{ :submodule/name | string } |{ :submodule/order | number } |{ :submodule/io | keyword } |{ :submodule/research? | boolean } |{ :submodule/conditionals-operator | keyword } "] Submodule -> Group [label=":submodule/groups" taillabel=1 headlabel=N] Submodule -> Conditional [label=":submodule/conditionals" taillabel=1 headlabel=N] Submodule -> HelpPage [label=":submodule/help-key" taillabel=1 headlabel=1] Submodule -> Translation [label=":submodule/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Group [label="Group |{ :bp/uuid | string } |{ :group/name | string } |{ :group/order | long } |{ :group/io | keyword } |{ :group/research? | boolean } |{ :group/repeat? | boolean } |{ :group/max-repeat | long } |{ :group/conditionals-operator | keyword } "] Group -> Group [label=":group/children" taillabel=1 headlabel=1] Group -> Conditional [label=":group/conditionals" taillabel=1 headlabel=N] Group -> GroupVariable [label=":group/group-variables" taillabel=1 headlabel=N] Group -> HelpPage [label=":group/help-key" taillabel=1 headlabel=1] Group -> Translation [label=":group/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- GroupVariable [label="Group-Variable |{ :bp/uuid | string } |{ :group-variable/cpp-class | string } |{ :group-variable/cpp-function | string } |{ :group-variable/cpp-namespace | string } |{ :group-variable/cpp-parameter | string } |{ :group-variable/order | long} |{ :group-variable/research? | boolean } "] GroupVariable -> CppClass [label=":group-variable/cpp-class (uuid)" taillabel=1 headlabel=1] GroupVariable -> CppFunction [label=":group-variable/cpp-function (uuid)" taillabel=1 headlabel=1] GroupVariable -> CppNamespace [label=":group-variable/cpp-namespace (uuid)" taillabel=1 headlabel=1] GroupVariable -> CppParameter [label=":group-variable/cpp-parameter (uuid)" taillabel=1 headlabel=1] GroupVariable -> HelpPage [label=":group-variable/help-key" taillabel=1 headlabel=1] GroupVariable -> Translation [label=":group-variable/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- CppClass [label="Cpp.Class |{ :bp/uuid | string } |{ :cpp.class/name | string } "] CppClass -> CppFunction [label=":cpp.class/function" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- CppFunction [label="Cpp.Function |{ :bp/uuid | string } |{ :cpp.function/name | string } |{ :cpp.function/return-type | stringema} "] CppFunction -> CppParameter [label=":cpp.function/parameter" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- CppParameter [label="Cpp.Parameter |{ :bp/uuid | string } |{ :cpp.parameter/name | string } |{ :cpp.parameter/order | number } |{ :cpp.parameter/type | string } "] //---------------------------------------------------------------------------------------------- CppNamespace [label="Cpp.Namespace |{ :bp/uuid | string } |{ :cpp.namespace/name | string } "] CppNamespace -> CppClass [label=":cpp.namespace/class" taillabel=1 headlabel=N] CppNamespace -> CppEnum [label=":cpp.namespace/enum" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- CppEnum [label="Cpp.Enum |{ :bp/uuid | string } |{ :cpp.enum/name | string } "] CppEnum -> CppEnumMember [label=":cpp.enum/enum-member" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- CppEnumMember [label="Cpp.Enum-member |{ :bp/uuid | string } |{ :cpp.enum-member/name | string } |{ :cpp.enum-member/value | number } "] //---------------------------------------------------------------------------------------------- Tool [label="Tools |{ :bp/uuid | string } |{ :tool/name | string } |{ :tool/order | number } "] Tool -> SubTool [label=":tool/subtools" taillabel=1 headlabel=N] Tool -> HelpPage [label=":tool/help-key" taillabel=1 headlabel=1] Tool -> Translation [label=":tool/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- SubTool [label="Subtool |{ :bp/uuid | string } |{ :subtool/name | string } |{ :subtool/order | number } |{ :subtool/autocompute? | boolean } "] SubTool -> SubToolVariable [label=":subtool/variables" taillabel=1 headlabel=N] SubTool -> HelpPage [label=":subtool/help-key" taillabel=1 headlabel=1] SubTool -> Translation [label=":subtool/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- SubToolVariable [label="Subtool-Variable |{ :bp/uuid | string } |{ :subtool-variable/io | keyword } |{ :subtool-variable/order | long } |{ :subtool-variable/cpp-namespace-uuid | string } |{ :subtool-variable/cpp-mclass | string } |{ :subtool-variable/cpp-function-uuid | string } "] SubToolVariable -> HelpPage [label=":subtool-variable/help-key" taillabel=1 headlabel=1] SubToolVariable -> Translation [label=":subtool-variable/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Variable [label="Variable |{ :bp/uuid | string } |{ :variable/name | string } |{ :variable/bp6-label | string } |{ :variable/bp6-code | string } |{ :variable/kind | keyword} |{ :variable/native-decimals | double } |{ :variable/english-decimals | double } |{ :variable/metric-decimals | double } |{ :variable/maximum | double } |{ :variable/minimum | double } |{ :variable/default-value | double } |{ :variable/map-units-convertible? | boolean } "] Variable -> GroupVariable [label=":variable/group-variables" taillabel=1 headlabel=N] Variable -> SubToolVariable [label=":variable/subtool-variables" taillabel=1 headlabel=N] Variable -> List [label=":variable/list" taillabel=1 headlabel=1] Variable -> Domain [label=":variable/domain-uuid" taillabel=1 headlabel=1] Variable -> Unit [label=":variable/native-unit-uuid" taillabel=1 headlabel=1] Variable -> Unit [label=":variable/english-unit-uuid" taillabel=1 headlabel=1] Variable -> Unit [label=":variable/metric-unit-uuid" taillabel=1 headlabel=1] Variable -> Translation [label=":variable/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- List [label="List |{ :bp/uuid | string } |{ :list/name | string } "] List -> ListOption [label=":list/options" taillabel=1 headlabel=N] List -> Translation [label=":list/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- ListOption [label="List-Option |{ :bp/uuid | string } |{ :list-option/name | string } |{ :list-option/default | string } |{ :list-option/value | string } |{ :list-option/order | long } |{ :list-option/hide? | boolean } "] ListOption -> Translation [label=":list-option/translation-key" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Dimension [label="Dimension |{ :bp/uuid | string } |{ :dimension/name | string } |{ :dimension/cpp-enum-uuid | string } "] Dimension -> Unit [label=":dimension/units" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- Unit [label="Unit |{ :bp/uuid | string } |{ :unit/name | string } |{ :unit/short-code | string } |{ :unit/system | string } |{ :unit/cpp-enum-member-uuid | string } "] //---------------------------------------------------------------------------------------------- DomainSet [label="Domain-Set |{ :bp/uuid | string } |{ :domain-set/name | string } "] DomainSet -> Domain [label=":domain-set/domains" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- Domain [label="Domain |{ :bp/uuid | string } |{ :domain/name | string } |{ :domain/decimals | string } "] Domain -> Dimension [label=":domain/dimension-uuid" taillabel=1 headlabel=1] Domain -> Unit [label=":domain/native-unit-uuid" taillabel=1 headlabel=1] Domain -> Unit [label=":domain/english-unit-uuid" taillabel=1 headlabel=1] Domain -> Unit [label=":domain/metric-unit-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Conditional [label="Conditional |{ :bp/uuid | string } |{ :conditional/type | keyword } |{ :conditional/operator | keyword } |{ :conditional/values | string } "] Conditional -> GroupVariable [label=":conditional/group-variable-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Diagram [label="Diagram |{ :bp/uuid | keyword } |{ :diagram/type | string } "] Diagram -> GroupVariable [label=":diagram/group-variable" taillabel=1 headlabel=1] Diagram -> GroupVariable [label=":diagram/input-group-variables" taillabel=1 headlabel=N] Diagram -> GroupVariable [label=":diagram/output-group-variables" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- Language [label="Language |{ :bp/uuid | keyword } |{ :language/name | string } |{ :language/short-code | string } "] Language -> Translation [label=":language/translation" taillabel=1 headlabel=1] Language -> HelpPage [label=":language/help-page" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Translation [label="Translation |{ :bp/uuid | keyword } |{ :translation/name | string } |{ :translation/key | string } |{ :translation/translation | string } "] //---------------------------------------------------------------------------------------------- HelpPage [label="Help-page |{ :bp/uuid | keyword } |{ :help-page/key | string } |{ :help-page/content | string } "] //---------------------------------------------------------------------------------------------- Link [label="Link |{ :bp/uuid | keyword } "] Link -> GroupVariable [label="link/source" taillabel=1 headlabel=1] Link -> GroupVariable [label="link/destination" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- // Worksheet Schema Starts Here //---------------------------------------------------------------------------------------------- Worksheet [label="Worksheet |{ :bp/uuid | string } |{ :worksheet/run-description | string } |{ :worksheet/name | string } |{ :worksheet/created | long } |{ :worksheet/furthest-visited-step | keyword } |{ :worksheet/modules | keywords } "] Worksheet -> Note [label=":worksheet/notes" taillabel=1 headlabel=N] Worksheet -> InputGroup [label=":worksheet/input-groups" taillabel=1 headlabel=N] Worksheet -> RepeatGroup [label=":worksheet/repeat-groups" taillabel=1 headlabel=N] Worksheet -> Output [label=":worksheet/outputs" taillabel=1 headlabel=N] Worksheet -> ResultTable [label=":worksheet/result-table" taillabel=1 headlabel=1] Worksheet -> GraphSettings [label=":worksheet/graph-settings" taillabel=1 headlabel=1] Worksheet -> TableSettings [label=":worksheet/table-settings" taillabel=1 headlabel=1] Worksheet -> WorksheetDiagram [label=":worksheet/diagrams" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Note [label="Note |{ :bp/uuid | string } |{ :note/name | string } |{ :note/content | string } |{ :note/submodule | string } "] //---------------------------------------------------------------------------------------------- InputGroup [label="Input-Group |{ :bp/uuid | string } |{ :input-group/repeat-id | long } |{ :input-group/inputs | long } "] InputGroup -> Group [label=":input-group/group-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- RepeatGroup [label="Repeat-Group |{ :bp/uuid | string } |{ :repeat-group/group-uuid | string } |{ :repeat-group/repeats | long } |{ :repeat-group/inputs | long } "] RepeatGroup -> Group [label=":repeat-group/group-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- Output [label="Output |{ :bp/uuid | string } |{ :output/enabled? | boolean } "] Output -> GroupVariable [label=":output/group-variable-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- ResultTable [label="Result-Table |{ :bp/uuid | string } "] ResultTable -> ResultHeader [label=":result-table/headers" taillabel=1 headlabel=N] ResultTable -> ResultRow [label=":result-table/rows" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- ResultHeader [label="Result-Header |{ :bp/uuid | string } |{ :result-header/repeat-id | long } |{ :result-header/order | long } |{ :result-header/units | string } "] ResultHeader -> GroupVariable [label=":result-header/group-variable-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- ResultRow [label="Result-Row |{ :bp/uuid | string } |{ :result-row/id | long } "] ResultRow -> ResultCell [label=":result-row/cells" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- ResultCell [label="Result-Cell |{ :bp/uuid | string } |{ :result-cell/value | string } "] ResultCell -> ResultHeader [label=":result-cell/header" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- TableSettings [label="Table-Settings |{ :bp/uuid | string } |{ :table-settings/enabled? | boolean } "] TableSettings -> TableFilter [label=":table-settings/filters" taillabel=1 headlabel=N] TableSettings -> MapUnitsSettings [label=":table-settings/map-units-settings" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- TableFilter [label="Table-Filter |{ :bp/uuid | string } |{ :table-filter/min | long } |{ :table-filter/max | long } |{ :table-filter/enabled? | boolean } "] TableFilter -> GroupVariable [label=":table-filter/group-variable-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- MapUnitsSettings [label="Map-Units-settings |{ :bp/uuid | string } |{ :map-units-settings/enabled? | boolean } |{ :map-units-settings/units | string } |{ :map-units-settings/map-rep-fraction | long } "] //---------------------------------------------------------------------------------------------- GraphSettings [label="Graph-Settings |{ :bp/uuid | string } |{ :graph-settings/enabled? | boolean } "] GraphSettings -> YAxisLimit [label=":graph-settings/y-axis-limits" taillabel=1 headlabel=N] GraphSettings -> GroupVariable [label=":graph-settings/x-axis-group-variable-uuid" taillabel=1 headlabel=1] GraphSettings -> GroupVariable [label=":graph-settings/z-axis-group-variable-uuid" taillabel=1 headlabel=1] GraphSettings -> GroupVariable [label=":graph-settings/z2-axis-group-variable-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- YAxisLimit [label="Y-Axis-Limit |{ :bp/uuid | string } |{ :y-axis-limit/min | long } |{ :y-axis-limit/max | long } "] YAxisLimit -> GroupVariable [label=":y-axis-limit/group-variable-uuid" taillabel=1 headlabel=1] //---------------------------------------------------------------------------------------------- WorksheetDiagram [label="Worksheet-diagram |{ :bp/uuid | string } |{ :worksheet.diagram/title | string } |{ :worksheet.diagram/row-id | long } "] WorksheetDiagram -> GroupVariable [label=":worksheet.diagram/group-variable-uuid" taillabel=1 headlabel=1] WorksheetDiagram -> Ellipse [label=":worksheet.diagram/ellises" taillabel=1 headlabel=N] WorksheetDiagram -> Arrow [label=":worksheet.diagram/arrows" taillabel=1 headlabel=N] WorksheetDiagram -> ScatterPlot [label=":worksheet.diagram/scatter-plots" taillabel=1 headlabel=N] //---------------------------------------------------------------------------------------------- Ellipse [label="Ellipse |{ :bp/uuid | string } |{ :ellipse/legend-id | string } |{ :ellipse/semi-major-axis | double } |{ :ellipse/semi-minor-axis | double } |{ :ellipse/rotation | long } |{ :ellipse/color | string } "] //---------------------------------------------------------------------------------------------- Arrow [label="Arrow |{ :bp/uuid | string } |{ :arrow/legend-id | string } |{ :arrow/length | double } |{ :arrow/rotation | double } |{ :arrow/color | string } |{ :arrow/dashed? | string } "] //---------------------------------------------------------------------------------------------- ScatterPlot [label="Scatter-Plot |{ :bp/uuid | string } |{ :scatter-plot/legend-id | string } |{ :scatter-plot/color | string } |{ :scatter-plot/x-coordinates | string } |{ :scatter-plot/y-coordinates | string } "] } #+end_src #+RESULTS: [[file:projects/behave/docs/schema.png]]