Skip to content

feat(units): weight math audit — new @packrat/units package with NIST constants and 174 tests#2388

Merged
andrew-bierman merged 6 commits into
mainfrom
feat/weight-audit
May 7, 2026
Merged

feat(units): weight math audit — new @packrat/units package with NIST constants and 174 tests#2388
andrew-bierman merged 6 commits into
mainfrom
feat/weight-audit

Conversation

@andrew-bierman
Copy link
Copy Markdown
Collaborator

@andrew-bierman andrew-bierman commented May 7, 2026

Summary

  • New `@packrat/units` package — single source of truth for all weight math, using exact NIST avoirdupois constants (`1 oz = 28.349523125 g`, `1 lb = 453.59237 g`, `1 kg = 1000 g`)
  • Migrated all call sites — `apps/expo` and `packages/api` now import from `@packrat/units` instead of divergent inline math
  • 174 unit tests cross-validated against `convert-units` v3
  • Fixed `computeCategories` percentage bug — was dividing gram-based numerator by display-unit denominator for non-gram users
  • Pre-push fixes: added `prefers-reduced-motion` CSS to `apps/landing` (WCAG 2.3.3), bumped 8 stale expo SDK-54 patch versions

Key changes

Area Before After
oz to g 28 (rounded) 28.349523125 (NIST exact)
lb to g 453.59 453.59237 (NIST exact)
Unknown unit fallback NaN graceful fallback to g
Round-trip fidelity divergent factors same constant both directions
Test count ~30 174

Testing

  • `bun test` in `packages/units` — 174 pass, 0 fail
  • All existing API and expo weight tests updated and passing

Post-Deploy Monitoring & Validation

No additional operational monitoring required: pure refactor of math utilities with no behavior change for users, no DB writes, no API surface changes.


Compound Engineered Generated with Claude Code

andrew-bierman and others added 3 commits May 7, 2026 12:10
- Create packages/units with NIST-exact avoirdupois constants
  (1 oz = 28.349523125 g, 1 lb = 453.59237 g — single source of truth)
- Expose normalize, fromGrams, convert, displayWeight, isWeightUnit,
  parseWeightUnit; 174 tests including cross-validation vs convert-units v3
- Migrate all call sites: apps/expo weight utils, computePackWeights,
  computePackTemplateWeights, computeCategories, lib/utils/compute-pack,
  packages/api weight utils and compute-pack
- Fix convertToGrams/convertFromGrams which were NOT inverses of each other
  (used 28.3495 vs 28.35 — silent drift of ~0.016 oz per 100 oz)
- Fix computeCategories percentage bug: was mixing pack.totalWeight (in
  preferred unit) with convertToGrams, giving wrong % for non-gram users
- Update all test suites to NIST values; 730 tests passing (0 failures)
- Add convert-units 3.0.0-beta.8 as devDependency for cross-validation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add @media (prefers-reduced-motion: reduce) to landing app globals.css
  to satisfy WCAG 2.3.3 accessibility requirement (fixes react-doctor check)
- Bump 8 expo packages to SDK-54 required patch versions:
  expo ^54.0.33→~54.0.34, expo-dev-client/file-system/glass-effect/
  image-picker/linking/updates/web-browser each +0.0.1

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Satisfies the no-raw-typeof custom lint rule enforced by the pre-push hook.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Warning

Rate limit exceeded

@andrew-bierman has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 43 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2bdbcd76-b985-4adc-88df-b6c89d277aa5

📥 Commits

Reviewing files that changed from the base of the PR and between c1f2b9a and cfbb19f.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (22)
  • apps/expo/features/pack-templates/utils/computePacktemplateWeight.ts
  • apps/expo/features/packs/utils/__tests__/convertFromGrams.test.ts
  • apps/expo/features/packs/utils/__tests__/convertToGrams.test.ts
  • apps/expo/features/packs/utils/computeCategories.ts
  • apps/expo/features/packs/utils/computePackWeights.ts
  • apps/expo/features/packs/utils/convertFromGrams.ts
  • apps/expo/features/packs/utils/convertToGrams.ts
  • apps/expo/lib/utils/compute-pack.ts
  • apps/expo/package.json
  • apps/expo/utils/__tests__/weight.test.ts
  • apps/expo/utils/weight.ts
  • apps/expo/vitest.config.ts
  • apps/landing/app/globals.css
  • biome.json
  • packages/api/package.json
  • packages/api/src/utils/__tests__/weight.test.ts
  • packages/api/src/utils/compute-pack.ts
  • packages/api/src/utils/weight.ts
  • packages/units/package.json
  • packages/units/src/index.test.ts
  • packages/units/src/index.ts
  • packages/units/vitest.config.ts

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: String must contain at most 250 character(s) at "tone_instructions"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/weight-audit

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added dependencies Pull requests that update a dependency file api mobile web labels May 7, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

Coverage Report for Expo Unit Tests Coverage (./apps/expo)

Status Category Percentage Covered / Total
🔵 Lines 82.55% 478 / 579
🔵 Statements 82.55% (🎯 75%) 478 / 579
🔵 Functions 92.59% 50 / 54
🔵 Branches 91.39% 170 / 186
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
apps/expo/features/pack-templates/utils/computePacktemplateWeight.ts 100% 100% 100% 100%
apps/expo/features/packs/utils/computeCategories.ts 0% 0% 0% 0% 1-42
apps/expo/features/packs/utils/computePackWeights.ts 100% 100% 100% 100%
apps/expo/features/packs/utils/convertFromGrams.ts 100% 100% 100% 100%
apps/expo/features/packs/utils/convertToGrams.ts 100% 100% 100% 100%
apps/expo/lib/utils/compute-pack.ts 100% 100% 100% 100%
apps/expo/utils/weight.ts 100% 100% 100% 100%
Generated in workflow #1101 for commit cfbb19f by the Vitest Coverage Report Action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

Coverage Report for API Unit Tests Coverage (./packages/api)

Status Category Percentage Covered / Total
🔵 Lines 75.03% 565 / 753
🔵 Statements 75.03% (🎯 65%) 565 / 753
🔵 Functions 95.65% 44 / 46
🔵 Branches 89.05% 244 / 274
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/api/src/utils/compute-pack.ts 100% 100% 100% 100%
packages/api/src/utils/weight.ts 100% 100% 100% 100%
Generated in workflow #1101 for commit cfbb19f by the Vitest Coverage Report Action

@andrew-bierman andrew-bierman marked this pull request as ready for review May 7, 2026 18:44
Copilot AI review requested due to automatic review settings May 7, 2026 18:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a shared @packrat/units package to centralize weight-unit conversion/normalization using exact NIST avoirdupois constants, then refactors existing API + Expo weight utilities to consume that shared implementation (reducing duplicated conversion math). It also includes small dependency updates (Expo) and a landing-page accessibility improvement for reduced-motion users.

Changes:

  • Added new @packrat/units package with weight conversion helpers (normalize, fromGrams, convert, displayWeight, parsing/guards) and comprehensive tests.
  • Refactored API and Expo weight computations (base/total/category summaries, grams helpers) to use @packrat/units instead of bespoke conversion logic.
  • Updated Expo-related dependencies and added prefers-reduced-motion CSS handling on the landing site.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/units/vitest.config.ts Adds Vitest config for the new @packrat/units package with strict coverage thresholds.
packages/units/src/index.ts Implements canonical unit conversion/parsing/formatting helpers and exported types/constants.
packages/units/src/index.test.ts Adds extensive unit tests and cross-validation against convert-units.
packages/units/package.json Declares the new workspace package and its test/dev dependencies.
packages/api/src/utils/weight.ts Replaces ad-hoc conversions with @packrat/units and keeps legacy helpers via re-exports/wrappers.
packages/api/src/utils/compute-pack.ts Refactors pack base/total weight computation to normalize to grams via @packrat/units and use displayWeight.
packages/api/src/utils/tests/weight.test.ts Updates assertions to reflect exact NIST constants and new conversion behavior.
packages/api/package.json Adds @packrat/units workspace dependency.
bun.lock Records new workspace package and dependency updates (including Expo version bumps).
biome.json Adds packages/units/src/index.ts to the existing override list (rule exceptions).
apps/landing/app/globals.css Adds prefers-reduced-motion styles to reduce animation/transition effects.
apps/expo/vitest.config.ts Adds Vitest aliases for @packrat/units (and @packrat/guards) to point at source during unit tests.
apps/expo/utils/weight.ts Refactors Expo app weight utilities to use @packrat/units.
apps/expo/utils/tests/weight.test.ts Updates Expo-side weight util tests to align with exact constants/behavior.
apps/expo/package.json Adds @packrat/units dependency and bumps Expo-related versions.
apps/expo/lib/utils/compute-pack.ts Refactors Expo pack weight computation to normalize via @packrat/units and format via displayWeight.
apps/expo/features/packs/utils/convertToGrams.ts Replaces local conversion switch with normalize(..., parseWeightUnit(...)).
apps/expo/features/packs/utils/convertFromGrams.ts Replaces local conversion switch with fromGrams(...).
apps/expo/features/packs/utils/computePackWeights.ts Refactors feature-level pack weight computation to use @packrat/units.
apps/expo/features/packs/utils/computeCategories.ts Refactors category aggregation to compute percentages from grams and display using @packrat/units.
apps/expo/features/packs/utils/tests/convertToGrams.test.ts Updates tests for NIST exact values and new behavior.
apps/expo/features/packs/utils/tests/convertFromGrams.test.ts Updates tests for NIST exact values and new behavior.
apps/expo/features/pack-templates/utils/computePacktemplateWeight.ts Refactors template weight computation to normalize via @packrat/units and format via displayWeight.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +8 to +15
oz: 28.349523125,
lb: 453.59237,
} as const;

export const WEIGHT_UNITS = Object.freeze(['g', 'kg', 'oz', 'lb'] as const);

export type WeightUnit = keyof typeof TO_GRAMS;

@andrew-bierman andrew-bierman changed the title Feat/weight audit feat(units): weight math audit — new @packrat/units package with NIST constants and 174 tests May 7, 2026
@andrew-bierman andrew-bierman merged commit 8eda5a0 into main May 7, 2026
10 of 12 checks passed
@andrew-bierman andrew-bierman deleted the feat/weight-audit branch May 7, 2026 23:24
andrew-bierman added a commit that referenced this pull request May 14, 2026
feat(units): weight math audit — new @packrat/units package with NIST constants and 174 tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api dependencies Pull requests that update a dependency file mobile web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants