88 lines
2.4 KiB
Markdown
88 lines
2.4 KiB
Markdown
---
|
|
type: project
|
|
status: active
|
|
source: git.alwisp.com
|
|
repo: jason/ui-tracker
|
|
repo_url: https://git.alwisp.com/jason/ui-tracker
|
|
language: TypeScript
|
|
branch: main
|
|
tags: [repo, jason]
|
|
updated: 2026-05-29
|
|
---
|
|
|
|
# ui-tracker
|
|
|
|
**Repository:** [jason/ui-tracker](https://git.alwisp.com/jason/ui-tracker) · branch `main` · TypeScript
|
|
|
|
## Summary
|
|
|
|
Unifi Store stock monitor — watches store.ui.com for product restocks and sends Telegram alerts; single Docker container for Unraid with a React admin UI
|
|
|
|
## Current status
|
|
|
|
Active. Synced from Gitea on 2026-05-29.
|
|
|
|
## Documentation overview
|
|
|
|
_Source: PROJECT.md_
|
|
|
|
# UI Stock Tracker — Project Documentation
|
|
|
|
**Status:** ✅ Complete and running
|
|
**Last updated:** 2026-03-29
|
|
|
|
---
|
|
|
|
## Purpose
|
|
|
|
Monitors product pages on [store.ui.com](https://store.ui.com/us/en) for stock availability and sends a Telegram alert the moment a watched item comes back in stock. Runs as a single persistent Docker container on Unraid with a clean web UI for managing tracked products.
|
|
|
|
---
|
|
|
|
## Stack
|
|
|
|
| Layer | Technology |
|
|
|---|---|
|
|
| Frontend | React 18 + TypeScript, Vite, Lucide icons |
|
|
| Backend | Node.js 20 + TypeScript, Express |
|
|
| Database | SQLite via `better-sqlite3` (WAL mode) |
|
|
| Scraper | Puppeteer-core + system Chromium |
|
|
| Alerts | Telegram Bot API (direct HTTP) |
|
|
| Container | Single Docker container — nginx + Node.js managed by supervisord |
|
|
| Web server | nginx — serves frontend, proxies `/api/` to Node.js on port 3001 |
|
|
|
|
---
|
|
|
|
## Container Architecture
|
|
|
|
One container runs three processes via **supervisord**:
|
|
|
|
```
|
|
supervisord
|
|
├── nginx → serves React build on :8080, proxies /api/ → localhost:3001
|
|
└── node → Express API, SQLite, Puppeteer scheduler, Telegram sender
|
|
```
|
|
|
|
The SQLite database is stored on a mounted volume at `/app/data/tracker.db` so it persists across rebuilds.
|
|
|
|
---
|
|
|
|
## Key Features
|
|
|
|
### Stock Detection
|
|
Puppeteer navigates to each product URL and waits for React hydration (2.5s delay), then scans all `<span>` elements for exact text matches:
|
|
- `"Add to Cart"` → `in_stock`
|
|
- `"Sold Out"` → `sold_out`
|
|
- Neither found → `unknown`
|
|
|
|
Product name is pulled from the `og:title` meta tag (with Ubiquiti store suffix stripped). Thumbnail is pulled from `og:image`.
|
|
|
|
### Alert Logic
|
|
- Alert fires **once** when an item transitions to `in_stock` and `alert_sent = 0`
|
|
|
|
…(truncated — see repo)
|
|
|
|
## Notes
|
|
|
|
- Project file auto-created from repo documentation.
|