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 point –
App/app/App.tsxmounts the root navigator. - Navigation –
App/app/navigation/Navigation.tsx(916 LOC) andApp/app/navigation/RootNavigationContext.tsxfeed into each other, forming a circular import withData/lib/types.tsandApp/app/navigation/Navigation.tsx. The cycle involves four modules and must be broken before any navigator refactor. - Data hub –
packages/data-storage-couchdb/lib/functions/types.tsis imported by 22 other modules (instability 0), making it a high‑blast‑radius hub; changes ripple widely. - Import cycle –
Data/lib/types.ts,App/app/navigation/Navigation.tsx,App/app/navigation/RootNavigationContext.tsxare mutually reachable; breaking the cycle requires extracting shared types or inverting a dependency. - Oversized files –
App/app/navigation/Navigation.tsx(916 LOC),packages/integration-airtable/lib/syncWithAirtable.tsandApp/app/components/InsetGroup/InsetGroup.tsxexceed 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.tsx916 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-errorfrom correctness‑gating steps in.github/workflows/build_app.yml. - MEDIUM: declare least‑privilege
permissions: contents: readin workflows that currently have no declaration. - MEDIUM: enable Dependabot/Renovate – 10 manifests, no update bot configured.
- MEDIUM: install from lockfile in CI –
yarn installwithout--immutable; switch toyarn 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: falseon checkout inbuild_app.yml. - MEDIUM: review
postinstallscript inpackage.jsonand disable scripts in CI, or setignore-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.