A production-grade fullstack application that automates vehicle history data retrieval through mobile VIN scanning and intelligent web scraping. Reduces manual lookup time from ~5 minutes to under 10 seconds (or ~50ms for cached requests).
| Metric | Before | After | Improvement |
|---|---|---|---|
| Lookup Time | ~5 minutes (manual) | 10 seconds | 97% faster |
| Cached Response | N/A | ~50ms | 99.5% faster |
| VIN Entry Errors | Human input errors | Camera scanning | Eliminated |
flowchart LR
subgraph Mobile["📱 Android App"]
Camera["Camera Scanner\n(Dynamsoft SDK)"]
UI["Material Design UI"]
end
subgraph AWS["☁️ AWS EC2"]
Nginx["Nginx\n(SSL/Reverse Proxy)"]
Express["Express.js API"]
Cache{{"PostgreSQL\nCache"}}
Playwright["Playwright\nBrowser Automation"]
end
subgraph External["🌐 External"]
VehicleDB["Vehicle History\nService"]
end
Mobile -->|"HTTPS"| Nginx
Nginx --> Express
Express --> Cache
Cache -->|"Cache Hit (~50ms)"| Express
Cache -->|"Cache Miss"| Playwright
Playwright --> VehicleDB
VehicleDB --> Playwright
Playwright -->|"Store"| Cache
Express -->|"JSON Response"| Mobile
Flow:
- User scans VIN barcode with mobile camera
- Mobile app sends VIN to backend API via HTTPS
- Backend checks PostgreSQL cache for existing data
- Cache hit: Return immediately (~50ms)
- Cache miss: Playwright scrapes data, stores in cache, returns to app
saga/
├── backend/ # Node.js/Express API + PostgreSQL cache
├── mobile/ # Android Kotlin VIN scanner app
└── package.json # Monorepo workspace configuration
| Technology | Purpose |
|---|---|
| Node.js + TypeScript | Runtime and type safety |
| Express.js v5 | REST API framework |
| Playwright + Stealth | Browser automation |
| PostgreSQL 16 | Data caching with TTL |
| Prisma ORM | Type-safe database access |
| PM2 | Process management |
| Nginx | Reverse proxy, SSL termination |
| Technology | Purpose |
|---|---|
| Kotlin | Primary language |
| Coroutines | Async operations |
| OkHttp | HTTP client |
| Dynamsoft SDK | VIN barcode scanning |
| Material Design 3 | UI components |
| Technology | Purpose |
|---|---|
| AWS EC2 (Ubuntu 24.04) | Application hosting |
| Let's Encrypt | SSL certificates |
| Endpoint | Method | Description |
|---|---|---|
/api/scrape |
POST | Scrape VIN data { "vin": "...", "force": false } |
/api/health |
GET | Server health check |
/api/session |
GET | Browser session status |
/api/cache/stats |
GET | Cache statistics (admin) |
- Backend: Node.js 18+, npm, PostgreSQL 16
- Mobile: Android Studio, JDK 17
cd backend
# Install dependencies
npm install
# Configure environment
cp .env.example .env
# Edit .env with your credentials
# Run development server
npm run server:devEnvironment Variables:
| Variable | Description |
|---|---|
PORT |
Server port (default: 3000) |
DATABASE_URL |
PostgreSQL connection string |
CACHE_TTL_HOURS |
Cache freshness (default: 24) |
LOGIN_EMAIL |
Authentication email |
LOGIN_PASSWORD |
Authentication password |
- Open
mobile/in Android Studio - Configure
local.properties:DYNAMSOFT_LICENSE_KEY=your_license_key BACKEND_BASE_URL=https://your-backend-url.com
- Build and run on device/emulator
# Start with PM2
pm2 start ecosystem.config.js
# Monitor logs
pm2 logs vin-scraperSee AWS EC2 Deployment Guide and PostgreSQL Cache Setup Guide for detailed instructions.
./gradlew assembleRelease| Scenario | Response Time | Request Share |
|---|---|---|
| Cache Hit (fresh) | 30-80ms | ~70% |
| Cache Stale (refresh) | 5-10s | ~10% |
| Cache Miss (new VIN) | 8-15s | ~20% |
Monthly Cost: ~$18-22 (EC2 t3.small + storage)
| Document | Description |
|---|---|
| Technical Overview | Architecture and performance details |
| AWS EC2 Deployment | Production deployment guide |
| PostgreSQL Cache Setup | Cache implementation guide |
ISC