This document describes the architecture of the GenPres application, a clinical decision support system (CDSS) for order management. The system is written entirely in F# and built with the SAFE Stack (Saturn, Azure, Fable, Elmish).
GenPres is a client-server web application:
- Server: Runs in .NET (F#), can be hosted in a Docker container. Exposes a web API.
- Client: F# (Fable) compiled to JavaScript, runs in the browser.
- Configuration: All configuration and medication rules are (currently) maintained in Google Spreadsheets.
- Local Drug Repository: Drug data is cached locally in text files for performance and offline access.
- F# (.NET 10.0)
- Giraffe for web server
- Saturn for application composition
- Fable.Remoting for type-safe API communication with the client
For the canonical and up-to-date development toolchain requirements
(.NET SDK, Node.js, npm), see the Toolchain Requirements section in
DEVELOPMENT.md.
- Entry Point:
src/Informedica.GenPRES.Server/Server.fs - API Implementation:
src/Informedica.GenPRES.Server/ServerApi.fs- Implements protocol in
Informedica.GenPRES.Shared.Api.IServerApi - Processes commands from the client, performs calculations/validations, and returns results
- Implements protocol in
- Domain Logic: e.g.,
src/Informedica.GenORDER.Lib- Uses F# MailboxProcessor (actor model) for concurrent/isolated processing (e.g., medication order calculations). NOT IMPLEMETENTED YET.
- Dockerfile builds the server, bundles the client, and sets up the environment.
- Environment variables (e.g.,
GENPRES_URL_ID,GENPRES_PROD) configure which Google Spreadsheet is used for configuration. - Entry point: runs
dotnet Informedica.GenPRES.Server.dlland exposes port 8085.
Example Docker Usage:
docker build --build-arg GENPRES_URL_ARG="your_secret_url_id" -t halcwb/genpres .
docker run -it -p 8080:8085 halcwb/genpres- F# (Fable): Compiles to JavaScript
- Elmish: Model-View-Update architecture
- React: UI rendering
- Vite: Dev/bundle tooling (see
src/Informedica.GenPRES.Client/vite.config.js)
- Entry Point:
src/Informedica.GenPRES.Client/App.fsandsrc/Informedica.GenPRES.Client/index.html - Communicates with the server using Fable.Remoting proxies (
Informedica.GenPRES.Shared.Api.IServerApi) - Handles application state, dispatches commands, and updates UI reactively
- All rules, constraints, and medication data (except local drug cache) are stored in Google Spreadsheets.
- URLs are constructed dynamically and downloaded as CSV.
- Example:
https://docs.google.com/spreadsheets/d/{id}/gviz/tq?tqx=out:csv&sheet={sheet}
- F# Modules (e.g.,
Informedica.Utils.Lib.Web.GoogleSheets) handle fetching and parsing of spreadsheet data. - Which spreadsheet to use is controlled by the
GENPRES_URL_IDenvironment variable.
-
Data Cache: Proprietary cache files (not distributed publicly) containing medication product information.
- Used for fast lookup/calculation and offline use.
- Demo cache files are included for development.
- Path:
src/Informedica.GenPRES.Server/data/cache/README.mdexplains the folder usage.
-
Medication Data Types and Logic:
- Main types are defined in
src/Informedica.NKF.Lib/Drug.fsandsrc/Informedica.GenORDER.Lib/Types.fs - Includes types for Medication, Dose, Route, Schedule, and Medication order.
- Medication data can be loaded from local cache or generated from Google Sheets.
- Main types are defined in
GenPres implements a comprehensive domain architecture described in detail in the docs/domain folder. For complete architectural specifications, see:
- Core Domain Model: Defines the transformation pipeline from expert knowledge to executable orders
- GenFORM: Transforms free text to Operational Knowledge Rules (OKRs)
- GenORDER: Transforms OKRs to Order Scenarios and defines the Order Model (Orderable, Component, Item)
- GenSOLVER: Quantitative constraint solving engine
The system implements a transformation pipeline:
Free Text → [GenFORM] → OKRs → [GenORDER] → Order Scenarios → [GenSOLVER] → Quantitative Solutions
Operational Knowledge Rules (OKRs) define:
- Selection Constraints (Generic, Indication, Route, Patient Category, Dose Type, etc.)
- Calculation Constraints (Dose Limits, Schedule, Duration, Volumes, Concentrations)
Order Model (hierarchical structure):
- Order → Prescription → Orderable → Component → Item → Dose
For details on:
- Rule types (Dose Rule, Solution Rule, Reconstitution Rule, Renal Rule), see GenFORM Section 3
- Order model structure, see GenORDER Section 6
- Dose semantics (Quantity, Per Time, Rate, Total, Adjusted), see GenORDER Section 7
- Equation system (65 equations), see GenORDER Appendix D.1
- Constraint solving algorithm, see GenSOLVER Section 3
- Order-Independent Calculations: The constraint-based equation system allows calculations regardless of data entry order
- Automatic Unit Handling: All calculations use base units with automatic conversion
- Absolute Precision: Uses BigRationals to avoid rounding errors
- Range and Restriction Modeling: Supports dose ranges, frequency sets, and value constraints
- Safety by Construction: Invalid options are mathematically impossible to construct
- Completeness Guarantee: All valid options are preserved by the constraint solver
- Development:
dotnet runfor full stack, ordotnet run listfor targets. - Client: Open browser at
http://localhost:5173. - Production: Deploy via Docker.
- Environmental Variables:
GENPRES_URL_ID: Google Spreadsheet ID for config/dataGENPRES_LOG,GENPRES_PROD,GENPRES_DEBUG: Control logging, production/demo mode, etc.
- Startup:
- Server loads configuration from Google Spreadsheets (as CSV).
- Loads or generates local drug cache.
- Runtime:
- Client sends commands (e.g., calculate dose) via API.
- Server processes, applies rules, validates, and returns results.
- Drug lookup/calculation uses both spreadsheet config and local cache as needed.
- Updates:
- To update rules or configuration, edit the Google Spreadsheets referenced by the server.
- Core Domain Model
- GenFORM: Free Text to Operational Rules
- GenORDER: Operational Rules to Orders
- GenSOLVER: Order Scenarios to Quantitative Solutions
- Some medication data is proprietary and not included in the public repo.
- Only demo cache files are distributed for development and testing.
- The drug repository logic and calculation code is modular and can be extended for new data sources.
src/Informedica.GenPRES.Server/Server.fs: Application entry pointsrc/Informedica.GenPRES.Server/ServerApi.fs: API implementationsrc/Informedica.GenPRES.Client/App.fs: Client application entryDockerfile: Container configuration for deployment
For the complete library list with dependency order, see the Core Libraries section in DEVELOPMENT.md. For detailed library specifications including capabilities, see GenFORM Appendix B.3.