Files
echo/.references/references-only/reference vault/memory/projects/ui-tracker.md
T
2026-06-05 00:49:20 -05:00

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.