A lightweight, mobile-friendly inventory tracking application. This project consists of a Ruby-based Sinatra backend and a Progressive Web App (PWA) frontend, designed for scanning and managing product stocks via barcodes.
The application uses the openfoodfacts API to fetch product data
Created as a fun / PoC project while moving into a new house with a log of storage space including several freezers.
backend/: A Sinatra-based Ruby API.app/: Contains the core logic and models.config.ru: Rack configuration for running the application.Gemfile: Ruby dependencies (Sinatra, Openfoodfacts, Puma, etc.).
haproxy/: Configuration and static assets.static/: The frontend PWA (HTML, CSS, JS, and Service Workers).haproxy.cfg: Reverse proxy configuration to glue the frontend and backend together.
- Backend: Ruby 3.4.2, Sinatra, Puma.
- Frontend: Vanilla JS (ES Modules), HTML5 (BarcodeDetector API), CSS3.
- Infrastructure: Docker, Docker Compose, HAProxy.
- Docker and Docker Compose
- Ruby 3.4.2 (if developing backend locally)
The easiest way to start the full stack is using Docker Compose:
Use latest container from gcr:
bash run.sh
Build container from sources and start:
DOCKER_COMPOSE_BUILD=true bash run.sh
The application will be accessible through the HAProxy load balancer (check docker-compose.yml for port mappings, usually port 80 or 443).
- Create a
.envfile in the root directory. - Define necessary environment variables (e.g.,
AUTH_TOKENfor API security).
- Barcode Scanning: Uses the browser's native
BarcodeDetectorAPI to scan items via the device camera. - Offline Support: Implemented as a PWA with a Service Worker for caching.
- IndexedDB: Local storage of authentication tokens and cached inventory data.
- Search & Filter: Real-time filtering of inventory items.
The backend is a Sinatra application. To install the dependencies, execute:
cd backend
bundle install
Static files are served from haproxy/static/. You can edit index.html to modify the UI.
This project is licensed under the BSD 3-Clause License.
Commercial use is permitted, provided that the copyright notice and license text are retained in accordance with the license terms.