Skip to content

hbourg/Inventory_app

Repository files navigation

Inventory Management App

A full-stack, multi-device inventory management system built with React Native (Expo) and Node.js/Express, featuring real-time data synchronization across devices with role-based access control.

Overview

This application enables teams to manage device inventory collaboratively in real-time. Users can upload devices to lots, track inventory across multiple storage locations, and view shared data across all connected devices and platforms. Data is persisted on a centralized server, ensuring consistency and accessibility for all team members.

Live Status: Running on Ubuntu Server (i5 8th gen, 8GB RAM, 512GB SSD) with Docker containerization.

Recent Updates: See CHANGELOG.md for latest features and improvements.

Developer documentation: See docs/DEVELOPER_GUIDE.md for a full architecture walkthrough, how-to guides, and API reference. See docs/TROUBLESHOOTING.md for common issues and fixes.


Features

Core Functionality

  • Multi-Device Synchronization: Real-time inventory updates across all connected devices (Android, iOS)
  • Role-Based Access Control: Four user roles (Driver, Warehouse, Tech, Manager) with permission-based features
  • Lot Management: Upload devices to specific lots with location tracking
  • Inventory Search & Filtering: Global search across all inventory items with multiple filter options
  • CSV Import/Export: Bulk lot location imports and per-list CSV exports with native sharing
  • Device Tracking: Track devices by asset tag, serial number, device type, cosmetic/functional grades, and CPU/RAM specs
  • Authentication: JWT-based login with secure password hashing (bcryptjs)
  • Dark/Light Theme: Persistent theme preferences with system-level integration and dynamic header styling
  • Offline Resilience: Local caching with sync-on-connect capability
  • Purchase Tracking:
    • Fuel purchase logging with native date picker and required receipt photos
    • Management purchase tracking with credit card selection and required receipt images
    • Purchase history viewer with CSV export capability
    • Role-filtered purchase history (drivers see fuel, managers see management purchases)
  • Receipt Image Management: Camera capture and photo library integration with optimized compression
  • Version & Attribution: Built-in app version tracking and creator attribution with read-only display
  • Improved Navigation: Hamburger side menu with Home, Settings, and Sign Out options; Close button on Settings for quick navigation back
  • Smart Server Fallback: Automatic failover between configured server URLs (on-site/remote) during app startup authentication

User Roles

Role Permissions
Driver View home dashboard, submit fuel purchases with receipts, view own fuel purchase history
Warehouse Upload devices to lots, view inventory, access lot tracking
Tech Scan and add inventory items, view and delete scan_add inventory
Manager Full access, upload devices, submit management purchases, view all purchase history, manage users, export data

Tech Stack

Frontend

  • React Native (Expo 54.0): Cross-platform mobile framework
  • TypeScript: Type-safe JavaScript for reliability
  • @react-navigation: Stack and bottom-tab navigation
  • Async Storage: Device-level persistence for offline support
  • Expo modules:
    • expo-file-system - File handling
    • expo-document-picker - CSV import
    • expo-sharing - Native share sheet
    • expo-vector-icons - UI icons
    • expo-constants - App metadata/version display
    • expo-image-picker - Camera and photo library access
    • @react-native-community/datetimepicker - Native date picker

Backend

  • Node.js 20 LTS: Runtime
  • Express.js 5.2: REST API framework
  • JWT (jsonwebtoken): Stateless authentication
  • bcryptjs: Secure password hashing
  • CORS: Cross-origin resource sharing
  • dotenv: Environment configuration management
  • Expo Server SDK: Push notification delivery

Infrastructure & DevOps

  • Docker & Docker Compose: Containerization and orchestration
  • Ubuntu Server 24.04 LTS: Production OS
  • Nginx: Reverse proxy and HTTPS termination
  • UFW (Uncomplicated Firewall): Network security
  • PM2: Alternative process manager (configured, not primary)

Data & Storage

  • JSON file storage: Persistence layer (migrate to PostgreSQL for scale)
  • AsyncStorage: Mobile device-level caching

Project Architecture

Inventory_app/
├── App.tsx                      # App entry point
├── index.ts                     # Expo entry
├── server.js                    # Express backend API
├── src/
│   ├── screens/                 # UI screens
│   │   ├── LoginScreen.tsx      # Login with company logo and metadata
│   │   ├── HomeScreen.tsx
│   │   ├── UploadItemsScreen.tsx
│   │   ├── InventoryListScreen.tsx
│   │   ├── ItemDetailScreen.tsx
│   │   ├── SettingsScreen.tsx
│   │   ├── DriverPortalScreen.tsx       # Fuel purchase form with required receipt image
│   │   ├── ManagementPortalScreen.tsx   # Management purchase form with required receipt image
│   │   ├── PurchaseHistoryScreen.tsx    # Purchase viewer with CSV export
│   │   └── UserManagementScreen.tsx
│   ├── context/                 # State management
│   │   ├── AuthContext.tsx
│   │   └── ThemeContext.tsx     # Dark/light mode with dynamic theme switching
│   ├── services/                # API & business logic
│   │   ├── serverApi.ts         # Includes purchase submission & history fetching
│   │   └── syncService.ts
│   ├── storage/                 # Local persistence
│   │   ├── inventoryStorage.ts
│   │   └── lotUploadStorage.ts
│   ├── navigation/              # Route configuration
│   ├── components/              # Reusable UI components
│   ├── theme/                   # Design system (colors, spacing, typography)
│   ├── types/                   # TypeScript definitions
│   └── utils/                   # Helpers (CSV parsing)
├── docker-compose.yml           # Container orchestration
├── Dockerfile                   # Image definition
├── .env.example                 # Environment template
├── ecosystem.config.cjs         # PM2 configuration
└── docs/
    ├── PRODUCTION_DEPLOYMENT.md # Deployment guide
    ├── DEVELOPER_GUIDE.md       # Architecture, how-to, API reference
    └── TROUBLESHOOTING.md       # Common issues and fixes

API Endpoints

Authentication

  • POST /auth/login - User login
  • GET /auth/me - Get current user (requires token)

Inventory (Server-backed)

  • GET /items - Fetch all inventory items (paginated)
  • POST /items - Add new inventory item
  • GET /lot-items - Fetch lot uploads
  • POST /lot-items - Submit device to lot

Lots

  • GET /lots/public - Get lot info (no auth required)
  • GET /lots - Get lot info with locations (requires auth)
  • POST /lots/import - Bulk import lot locations from CSV

Purchases

  • POST /fuel-purchases - Log fuel purchase (receipt image required)
  • GET /purchases/fuel - Fetch fuel purchase history (authenticated)
  • POST /management-purchases - Log management purchase (receipt image required)
  • GET /purchases/management - Fetch management purchase history (manager only)

Push Notifications

  • POST /push/register - Register device for push notifications

Getting Started

Prerequisites

  • Node.js 20+ and npm
  • Android 9+ or iOS 12+
  • For testing: Expo Go app or built APK/IPA
  • For production: Ubuntu Server, Docker 27+

Local Development

# Clone and install
git clone <repo>
cd Inventory_app
npm install

# Set up environment
cp .env.example .env
# Edit .env with your API URL (examples: http://localhost:3000 or private VPN URL)

# Start development server (Terminal 1)
npm run server

# Start Expo development (Terminal 2)
npm run android    # or npm run ios

Production Deployment

See docs/PRODUCTION_DEPLOYMENT.md for the comprehensive setup guide including:

  • Docker image building
  • Environment configuration
  • Nginx reverse proxy setup
  • HTTPS with Let's Encrypt
  • Firewall configuration
  • PostgreSQL migration path

Quick start:

# On Ubuntu server
cd ~/Inventory_app
cp .env.example .env
# Edit .env with strong JWT_SECRET
docker compose up -d --build inventory-server

How It Works

Data Flow

  1. Mobile App captures device information (asset tag, device type, lot number)
  2. App sends to Express Server via authenticated REST API
  3. Server persists to shared JSON files (or PostgreSQL)
  4. Other devices fetch latest data via GET /items, GET /lot-items
  5. Conflict resolution: Latest timestamp wins; no offline-first merging yet

Authentication

  • User logs in with username/password
  • Server validates credentials (bcryptjs hash comparison)
  • On success, JWT token returned and stored in AsyncStorage
  • Token included in all subsequent API requests
  • Role verified on backend for permission checks
  • Automatic server fallback: On app boot, attempts authentication across configured server URLs (saved, onsite, remote, default) until successful connection is established and persists the working URL

Navigation & User Experience

  • Side Menu: Hamburger button (top-left) opens animated slide-in panel showing user name, role, and quick navigation
    • Home: Navigate back to home screen
    • Settings: Access app configuration and dual-server URL profiles
    • Sign Out: Exit and return to login
  • Settings Screen: Close button (top-right X icon) for quick navigation back
  • Animations: Smooth 220ms menu slide-in and 180ms slide-out for professional feel

Synchronization

  • On app launch, fetch all inventory and lot items from server
  • On device upload, immediate sync to server
  • Pending uploads queued if offline (stored locally)
  • CSV imports bulk-insert via /lots/import endpoint

Purchase Tracking System

  • Fuel Purchases (Drivers):

    • Form with native date picker for purchase date
    • Amount field and "Purchased At" location tracking
    • Receipt photo is mandatory before submit (camera or photo library)
    • Optional notes field
    • Image quality automatically compressed (camera: 50%, library: 30%) to fit 2MB server limit
    • Submit with user attribution
  • Management Purchases (Managers):

    • Similar form with credit card selection (Chase Business or Charity Charge)
    • Receipt image is mandatory before submit
    • Uses same compression optimization
    • Track spending by card type
  • Purchase History Viewer:

    • Accessible from Driver and Management portals
    • Dual-tab interface (Fuel purchases visible to all, Management purchases managers-only)
    • Swipe-to-refresh for latest data
    • Tap receipt to view full-size image in modal
    • CSV export with timestamp, amount, submitted by, card type (if applicable)
    • Exported CSVs shareable via native share sheet

Default Users (Local Server)

The server creates users.json with four default accounts on first run (only if the file does not exist):

Username Password Role
manager1 password123 manager
driver1 password123 driver
warehouse1 password123 warehouse
tech1 password123 tech

Set a strong JWT_SECRET, rotate all default credentials, and create named user accounts before going to production.


Skills & Learning Outcomes

Mobile Development

  • React Native fundamentals: Components, hooks, navigation, bottom tabs
  • Expo ecosystem: Build streamlined mobile apps without native code complexity
  • Expo EAS: Cloud-based app building for Android/iOS
  • Cross-platform UI: Responsive design adapting to different screen sizes and orientations
  • AsyncStorage: Client-side persistence and state hydration
  • Native modules: File I/O, document picker, sharing via Expo APIs
  • Deployment: Building APK/IPA files for distribution

Backend Development

  • Express.js API design: RESTful endpoints, middleware, error handling
  • Authentication & Authorization: JWT tokens, role-based access control (RBAC), middleware-based permission checks
  • Data persistence: File-based JSON storage with atomic writes, migration path to SQL databases
  • API security: CORS, input validation, password hashing
  • Push notifications: Server-side push notification delivery via Expo

Full-Stack Development

  • Client-server communication: JSON APIs, fetch requests, error handling
  • State management: Context API for global auth/theme state
  • Type safety: TypeScript for both frontend and backend
  • Environment management: dotenv for configuration across environments
  • Error handling: Graceful failures, retry logic, user feedback

DevOps & Infrastructure

  • Docker: Containerization, Dockerfile optimization, multi-stage builds
  • Docker Compose: Service orchestration, volume management, networking
  • Linux/Ubuntu: Server administration, user management, file permissions
  • Firewalls: UFW rules for port management and security
  • Reverse proxying: Nginx configuration, port forwarding, HTTPS termination (ready for setup)
  • Process management: PM2 for long-running processes (alternative to Docker)
  • Network configuration: Static IPs, firewall rules, port management

System Design

  • Scalability thinking: Identified JSON→PostgreSQL migration path; understood sharding/replication concepts
  • Real-time sync: Designed multi-device synchronization without conflict resolution framework
  • Role-based permissions: Implemented permission system; understood privilege escalation risks
  • API versioning: Structured endpoints for future backward compatibility
  • CSV handling: Parsing, validation, and bulk import logic

Software Engineering Practices

  • Version control: Git workflow, .gitignore, code commits
  • Testing: TypeScript compilation, runtime validation
  • Documentation: Code comments, deployment guides, README
  • Clean code: Refactoring data flow, removing unused files, consistent naming
  • Debugging: Docker logs, browser DevTools, server-side error traces

Challenges & Solutions

Challenge Solution
Mobile apps losing connection to local dev server Switched to server-backed API with private VPN or secure remote endpoint
Data inconsistency across devices Centralized data on server; server as source of truth
CSV parsing complexity Built custom parser handling both tab and comma delimiters
Expo Go's QR code dependency Built standalone APK via EAS for persistent installation
Docker image not picking up code changes Added --build flag to rebuild on deploy
Lot names not displaying Fixed readLotInfo() to return locations array
File transfer time (scp including node_modules) Used tar with .exclude flags for fast transfer
Port listening on localhost only Ensured Docker containers expose ports to 0.0.0.0

Future Enhancements

Near-term

  • PostgreSQL migration for production scalability
  • Conflict-free replicated data types (CRDTs) for offline-first sync
  • Photo capture for device conditions
  • QR code generation for devices
  • Email notifications to managers

Medium-term

  • Dashboard analytics (trends, device lifespan)
  • Multi-warehouse support
  • Advanced search (date ranges, condition filters)
  • Audit logs for compliance
  • Mobile app auto-updates

Long-term

  • Machine learning for device recommendations
  • Integration with asset tracking hardware (RFID/Bluetooth tags)
  • White-label version for other organizations
  • Mobile app for managers with full admin interface

Deployment Workflow

Quick Deploy to Production Server

Once initial setup is complete, deploy new code with a single command:

From your local machine:

git add -A
git commit -m "your update message"
git push origin main

On the Ubuntu server:

ssh <your-user>@<YOUR_SERVER_IP>
deploy

The deploy command automatically:

  • Pulls latest code from GitHub main branch
  • Preserves .env configuration
  • Rebuilds Docker image
  • Restarts the inventory-server container
  • Performs health check

Server URLs Configuration

  • On-Site (local network): your LAN IP, e.g. http://192.168.1.x:3000
  • Remote (VPN): your VPN/remote IP, e.g. http://YOUR_VPN_IP:3000

Configure both URLs in app.json under expo.extra before building.

The app includes automatic server fallback at boot — if one URL fails during authentication, it tries configured alternatives automatically.

Deployment Checklist

  • TypeScript compiles without errors
  • Server runs locally on port 3000
  • Docker image builds successfully
  • Docker Compose orchestrates container
  • Firewall allows HTTP/HTTPS traffic
  • Mobile app connects to server IP
  • CSV import works end-to-end
  • Multi-device sync confirmed
  • Users can login and see role-based UI
  • Side menu navigation with Home, Settings, Sign Out
  • Close button on Settings screen
  • GitHub SSH deploy key configured
  • One-command deploy shortcut set up
  • Server URL fallback for authentication
  • TLS/HTTPS configured with Nginx
  • Monitoring set up (healthcheck + auto-restart)
  • Backup strategy implemented (nightly cron + retention)

Detailed deployment commands and operations runbook are in docs/PRODUCTION_DEPLOYMENT.md.


Key Learnings

  1. Full-stack ownership: Building both frontend and backend gives end-to-end visibility into data flow and performance
  2. DevOps is crucial: Docker, networking, and firewall knowledge bridges dev environment and production
  3. API design matters: Clear, consistent endpoints make frontend development smooth and future-proof changes
  4. Type safety saves debugging time: TypeScript caught errors that would be runtime bugs in JavaScript
  5. User role modeling: Early permission system design prevents security rework later
  6. Documentation pays off: Deployment guide made recreation on new hardware straightforward
  7. Mobile app distribution: Building standalone APKs via EAS beats QR scanning for real users
  8. Server as source of truth: Centralizing data eliminates sync conflicts and simplifies logic

License

MIT


Questions?

Refer to docs/PRODUCTION_DEPLOYMENT.md for deployment support or explore the source code in src/ for implementation details.

About

Internal operations app for warehouse teams — scan and track device inventory, manage lot uploads, log fuel and business purchases, and sync data across all devices in real time.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors