The Problem

A home‑/business‑focused RFID asset‑management app has grown to 753 files (582 in App/, 107 in packages/, 47 in Data/). The codebase mixes React Native, Express and Rails, uses Yarn, and runs GitHub Actions CI. While functional, the architecture contains several structural weaknesses that raise the cost of any change and introduce security risk.

What This Does

App/ is the React Native mobile entry point; it renders screens, components and UI groups (e.g., App/app/App.tsx, App/app/components/InsetGroup/InsetGroup.tsx). Data/ holds the schema, types and data‑access logic (Data/lib/types.ts, Data/lib/schema.ts). packages/ contains shared modules, the most notable being packages/data-storage-couchdb/ which implements CouchDB adapters (packages/data-storage-couchdb/lib/functions/types.ts, packages/data-storage-couchdb/lib/functions/getGetData.ts). The app communicates with RFID readers through native Java modules (App/android/app/src/main/java/vg/zeta/app/inventory/RFIDWithUHFBLEModule.java, RFIDWithUHFUARTModule.java) and Objective‑C bridges.

External touches – The repo has no Dockerfile; CI runs yarn install and bundle exec fastlane‑style builds. Secrets are stored in a committed debug.keystore (critical issue). No license file is present beyond the repo‑level notice.

How It Is Wired

  • Entry pointApp/app/App.tsx mounts the root navigator.
  • NavigationApp/app/navigation/Navigation.tsx (916 LOC) and App/app/navigation/RootNavigationContext.tsx feed into each other, forming a circular import with Data/lib/types.ts and App/app/navigation/Navigation.tsx. The cycle involves four modules and must be broken before any navigator refactor.
  • Data hubpackages/data-storage-couchdb/lib/functions/types.ts is imported by 22 other modules (instability 0), making it a high‑blast‑radius hub; changes ripple widely.
  • Import cycleData/lib/types.ts, App/app/navigation/Navigation.tsx, App/app/navigation/RootNavigationContext.tsx are mutually reachable; breaking the cycle requires extracting shared types or inverting a dependency.
  • Oversized filesApp/app/navigation/Navigation.tsx (916 LOC), packages/integration-airtable/lib/syncWithAirtable.ts and App/app/components/InsetGroup/InsetGroup.tsx exceed 500 LOC, hindering comprehension.
  • Duplicated logic – 1748 repeated 6‑line blocks across 162 files (found in App/.eslintrc.js, Data/.eslintrc.js, and the two RFID Java modules) indicate copy‑paste that should be extracted to shared helpers.
  • Empty catch blocks – 12 files under packages/data-storage-couchdb/lib/functions/ swallow errors (getGetData.ts, getGetDatumHistories.ts, getGetHistoriesInBatch.ts).

How To Use It

Setup

# Clone the repository (exact URL as provided)
git clone https://github.com/moses-y/Inventory.git
cd Inventory

# Install JavaScript dependencies
cd App && yarn install

# Install Ruby backend dependencies (Rails Gemfile present)
cd ../App && bundle install

No explicit start script is documented; a typical React Native dev flow after the above is npx react-native start or npx react-native run-ios/run-android.

Configuration The repo expects a compatible RFID UHF reader; supported devices are listed in the docs at https://docs.inventory.ztg.app/rfid-hardware/supported-rfid-devices. No environment‑variable file is committed; any required keys (e.g., CouchDB credentials) should be placed in a .env at the project root and referenced via process.env in the relevant modules.

Running it

# From the App directory (after deps are installed)
yarn react-native start
# or, to launch a device emulator
yarn react-native run-ios   # or run-android

The README also provides TestFlight and APK download links for quick testing without a local build.

Real‑World Use

A warehouse manager scans an RFID tag on a pallet; the iOS app reads the tag via the native BLE module, sends the EPC to the CouchDB sync function (packages/data-storage-couchdb/lib/functions/getGetData.ts), and updates the item’s location in the UI (App/app/features/inventory/components/ItemListItem.tsx). The hub module packages/data-storage-couchdb/lib/functions/types.ts validates the payload before persisting, and the navigation stack (App/app/navigation/Navigation.tsx) transitions the user to the item‑detail screen.

Code Health & Issues

  • HIGH/soundness – Import cycle member (4 files: Data/lib/types.ts, App/app/navigation/Navigation.tsx, App/app/navigation/RootNavigationContext.tsx) – circular dependency that blocks navigator changes.
  • HIGH/cognitive_load – Deep nesting (25 files, e.g., App/app/features/inventory/components/ItemListItem.tsx, packages/data-storage-couchdb/lib/functions/getGetData.ts) – control flow hard to follow; guard‑clause refactor recommended.
  • MEDIUM/resilience – Empty catch block (12 files, packages/data-storage-couchdb/lib/functions/getGetData.ts) – errors silently discarded; add logging or re‑throw.
  • MEDIUM/clarity – Hub module (packages/data-storage-couchdb/lib/functions/types.ts) – 22 importers, high blast radius; keep stable and small, move volatile logic out.
  • HIGH/clarity – Duplicated code blocks (1748 repeated 6‑line blocks across 162 files) – extract shared helpers; DRY the repeated logic.
  • HIGH/cognitive_load – Oversized file (App/app/navigation/Navigation.tsx 916 LOC) – split into cohesive units by responsibility.
  • MEDIUM/cognitive_load – High branching density (2 files, packages/data-storage-couchdb/lib/functions/getGetAttachmentInfoFromDatum.ts, App/app/features/label-printers/print-utils.ts) – 15 branch points over 53 lines; decompose decision logic.

SDLC observations (from file‑structure audit)

  • Critical: committed private key App/android/app/debug.keystore – must be re‑issued and purged from history.
  • HIGH: pin third‑party GitHub Actions to commit SHAs (e.g., zetavg/couchdb-action@master).
  • HIGH: remove continue-on-error from correctness‑gating steps in .github/workflows/build_app.yml.
  • MEDIUM: declare least‑privilege permissions: contents: read in workflows that currently have no declaration.
  • MEDIUM: enable Dependabot/Renovate – 10 manifests, no update bot configured.
  • MEDIUM: install from lockfile in CI – yarn install without --immutable; switch to yarn install --immutable.
  • MEDIUM: gate pull requests on dependency vulnerability scan – no scan currently in CI.
  • MEDIUM: add pre‑commit secret gate – no repo‑level gate visible.
  • MEDIUM: set persist-credentials: false on checkout in build_app.yml.
  • MEDIUM: review postinstall script in package.json and disable scripts in CI, or set ignore-scripts.

The Bottom Line

The repository provides a functional RFID asset‑management mobile app with a clear React Native + Rails split, but its architecture bears several high‑impact technical debts: a circular import that blocks navigation changes, a hub module that amplifies ripple effects, duplicated copy‑paste logic, and an exposed signing key. The code health audit flags a critical security item and multiple CI‑configuration gaps. Teams comfortable with incremental refactors and who can allocate time to break the import cycle and purge the keystore will find the app extensible; others may need to invest in a larger restructuring effort before safe ongoing development.