Functional Weave
Code in Rust

health.dose-weight-based@1.0.0

README.md

3,186 bytes · view raw

# health.dose-weight-based

Status: needs review and sign-off by a qualified clinician before it is published. Not a medical device; for decision support only; always follow local clinical guidelines.

Works out a weight-based dose (so much per kilogram), caps it at a maximum
single dose, and turns it into a volume the measuring device can actually
show: a whole number of 0.1 mL, 0.01 mL or 1 mL steps. It holds no drug data.
The prescriber's dose per kg, the maximum single dose and the product strength
all come from the caller, from the prescription and the product in hand.

## Units

Everything is a whole number in small units, so no step drifts. In floating
point, three 0.1 mL steps are 0.30000000000000004 mL. Here they are 300 µL.

| you have | pass                      |
|----------|---------------------------|
| 1 kg     | 1000 g                    |
| 1 mg     | 1000 µg                   |
| 1 mL     | 1000 µL                   |
| 120 mg/5 mL | strength 120000 µg in 5000 µL |
| 1 g in 3 mL | strength 1000000 µg in 3000 µL (no 333.33… mg/mL rounding) |

A weight of 12.4 is refused, not read as grams, because a slip between
kilograms and grams is a thousand-fold error.

## Worked example

15 mg/kg for a 12.4 kg child is 186 mg. At 120 mg in 5 mL that is 7.75 mL.
The syringe is marked in 0.1 mL, and 7.75 lies exactly between 7.7 and 7.8.
The tie goes down, so the answer is 7.7 mL, which holds 184.8 mg.
`differenceBasisPoints` is -65, meaning the given dose is 0.65% below the
calculated dose.

## Rounding rules

- **Cap first.** When weight × dose per kg is more than the maximum single
  dose, the maximum becomes the target and `cappedAtMaximum` is true. A dose
  exactly at the maximum is not capped.
- **Nearest measurable volume, a tie goes down.** When the dose is exactly
  halfway between two steps, the smaller one is chosen, because that is the
  more cautious choice.
- **Never over the maximum.** If rounding to the nearest step would deliver
  more than the maximum single dose, the volume drops one step.
- **Never zero.** If the dose rounds to no increments at all, the function
  raises an error. The fix is a more dilute product or a finer measure, not
  silently giving nothing.

Local policy may round differently. For example, some policies always round
down, and some allow up to ±10%. `differenceBasisPoints` compares the delivered
dose with the target (signed, 100 = 1%), so a caller can enforce its own
tolerance. The integer outputs (`calculatedMicrograms`, `targetMicrograms`,
`deliveredMicrograms`) are rounded half-up to a whole microgram for display.
The comparisons and the difference use the exact fractions.

## Limits (refused, not clamped)

weightGrams 200 to 500000; dosePerKgMicrograms 1 to 1000000;
maxSingleDoseMicrograms 1 to 100000000 or null for none; strengthMicrograms
1 to 100000000; strengthVolumeMicrolitres 1 to 1000000;
measuringIncrementMicrolitres 1 to 100000.

It does not check that the dose per kg, the maximum or the product are right
for the drug, the patient's age or renal function, or the route. It does not
convert to dosing by body surface area, and it does not cap by a daily
maximum.