EasyRent
Internal ops platform automating purchase-order, commission, and billing processing for a device rental business
// At a glance
Problem
Back-office staff were processing purchase-order, commission, tracking, and billing files manually in Excel across large device inventories, with no shared tool for validation, merging, or search.
Solution
Built a modular Flask REST API over a Parquet/Excel master data store for fast columnar reads, with broker-free real-time job progress (background threads + Server-Sent Events), chunked file streaming with HTTP Range support, and a React/Vite frontend with role-based access plus a redacted public search tier.
// Key highlights
- →Broker-free real-time job system (threads + SSE + locking) streaming live logs to the UI without external infrastructure
- →Performance-conscious file handling: chunked streaming, HTTP Range requests, and in-memory DataFrame caching
- →Multi-tier access model (public vs. authenticated) on shared endpoints instead of duplicated APIs
- →Domain-specific reconciliation logic to catch mismatches between purchase orders and price lists
- →Full production deployment: Docker, Gunicorn/gevent, Nginx, systemd, CI/CD, bilingual IT/EN/FR frontend
EasyRent is an internal operations platform for a phone/device rental business, built to automate the processing of purchase-order (POBS), commission (PCOM), tracking, and billing files that would otherwise be handled manually in Excel. It gives back-office staff, contact-center agents, and admins a single web app to validate, merge, and search large device inventories, generate shipping and invoicing exports, and monitor long-running jobs in real time — while still exposing a redacted public search tier for external lookups.
Tech Stack
Backend (backend_v2)
- Python 3.11, Flask 2.3, Gunicorn + gevent workers
- Flask-JWT-Extended for authentication, bcrypt for password hashing, custom role-based access control (admin / backoffice / contact_center)
- SQLite for user accounts; Parquet (pyarrow) + Excel as the file-based "master" data store for business records
- pandas, openpyxl, xlrd/xlwt for Excel/CSV ETL
- Flask-CORS with multi-origin allowlisting, python-dotenv, requests
- Docker, Nginx reverse proxy, systemd service, GitHub Actions CI/CD to a VPS
Frontend (frontend_V2)
- React 18 + Vite, React Router 6
- React Context API for state (Auth, Modal) plus custom hooks for real-time logs/operations, theming, and confirmations
- Tailwind CSS with tailwind-variants, react-icons, sonner (toasts), @formkit/auto-animate
- Chart.js (react-chartjs-2) and Recharts for analytics visualizations
- i18next / react-i18next for English, Italian, and French locales
- Axios API layer, Docker + Nginx / Netlify deployment, GitHub Actions CI/CD
Key Features
- JWT authentication with role-based access control and a public/anonymous search tier
- POBS processing pipeline: record verification, insertion, IMEI updates, and a unified mode that chains multiple operations into one job
- PCOM module for device-commission/partner file processing, mergeable with POBS
- Tracking/logistics module that generates shipping files and syncs status back to the master dataset
- Billing (Fatturazione) module: validates POBS and price-list files, previews calculations over a date range, and generates invoicing exports with history
- Reports/analytics module with edition-matching logic to detect missing product editions
- Advanced search with AND/OR filtering, pagination, field-level redaction for public users, and Excel/CSV export
- Historic file browser with preview, download, bulk ZIP download, and delete
- Real-time operation logging via Server-Sent Events with a polling fallback
- Admin user management UI for adding/removing users and assigning roles
Architecture
The backend is a modular Flask REST API (route handlers delegating to a per-domain service layer) backed by a Parquet/Excel "master" store rather than a full relational schema, chosen for fast columnar reads over large device inventories with Excel mirrors for business-user compatibility. Long-running file-processing jobs are spawned as background threads that stream progress to the frontend over SSE, returning a session ID immediately — an async job pattern implemented without an external broker like Celery/Redis, relying on gevent workers to stay non-blocking. Several endpoints use optional JWT auth to serve both public (redacted) and internal (full) responses from the same route instead of duplicating APIs. Large file downloads use chunked streaming and HTTP Range support for partial content, and file previews are cached in memory for a few minutes to make pagination through large spreadsheets instant. The React frontend consumes this API via an Axios service layer, using Context and custom hooks rather than Redux, and renders live job progress and analytics through SSE subscriptions and dual charting libraries.
My Role
- Designed a broker-free real-time job system (threads + SSE + locking) that streams live logs to the UI without external infrastructure
- Built performance-conscious file handling: chunked streaming, HTTP Range requests, and an in-memory DataFrame cache for instant large-file pagination
- Implemented a multi-tier access model (public vs. authenticated) on shared endpoints instead of duplicated APIs, with field-level redaction for data privacy
- Wrote domain-specific reconciliation logic (edition matching/parsing) to catch mismatches between purchase orders and price lists
- Delivered a full production deployment: Docker, Gunicorn/gevent, Nginx, systemd, and CI/CD to a VPS, plus a bilingual (IT/EN/FR) frontend