diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 11db255..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,68 +0,0 @@ -# Agent Operating Guide - -Use this file as the first entrypoint for work in this repository. - -If [DEPLOYMENT-PROFILE.md](./DEPLOYMENT-PROFILE.md) exists and contains filled-in defaults, read it immediately after this file and treat it as the source of preloaded project preferences unless the destination repository provides stronger instructions. - -## Default Behavior - -- Inspect the repository before making assumptions. -- Prefer implementing and verifying work over giving abstract advice unless the user explicitly asks for planning only. -- Read only the skill files needed for the current task. -- Reuse existing project patterns, naming, architecture, and conventions. -- Test or validate changes when feasible, then summarize outcomes and any remaining risks. -- Update or create documentation when the change affects usage, onboarding, behavior, or developer workflow. -- If repository-specific instructions conflict with this suite, follow the repository-specific instructions. - -## How To Load Skills - -1. Read [DEPLOYMENT-PROFILE.md](./DEPLOYMENT-PROFILE.md) if it is filled in for this deployment. -2. Read [SKILLS.md](./SKILLS.md). -3. Identify the task category and open the matching hub file. -4. Open only the specialized skill files relevant to the request. -5. Combine skills when the task spans multiple areas. -6. Avoid loading unrelated skills just because they exist. - -## Context Economy Rules - -- Default to reading one hub and two to four specialized skills for a normal task. -- Add more skills only when they materially change the approach, output, or quality bar. -- Prefer depth in the relevant skills over shallow loading across many categories. -- If two skills overlap heavily, choose the one that best matches the main risk or deliverable. -- Re-open the index when the task shifts, but do not reload the entire library reflexively. -- Treat the deployment profile as the early context layer and avoid re-reading it unless the task changes the relevant preference area. - -## Instruction Precedence - -Apply guidance in this order: - -1. Destination repository instructions -2. [DEPLOYMENT-PROFILE.md](./DEPLOYMENT-PROFILE.md) -3. Generic routing and skill guidance from this suite - -## Routing Table - -| Task type | Start here | -| --- | --- | -| Feature work, refactors, reviews, tests, backend, frontend | [hubs/software-development.md](./hubs/software-development.md) | -| Failing tests, bugs, incident-style analysis, root-cause work | [hubs/debugging.md](./hubs/debugging.md) | -| Technical docs, onboarding, release notes, change communication | [hubs/documentation.md](./hubs/documentation.md) | -| UX evaluation, UI polish, interaction quality, content design | [hubs/ui-ux.md](./hubs/ui-ux.md) | -| Product copy, launch messaging, marketing content | [hubs/marketing.md](./hubs/marketing.md) | -| Ideation, option generation, structured brainstorming | [hubs/brainstorming.md](./hubs/brainstorming.md) | - -## Combination Rules - -- For new features, combine implementation + test strategy + relevant docs. -- For UI work, combine frontend implementation + UX review + product copy when text matters. -- For broken behavior, combine bug triage + debugging workflow + change summary when a fix lands. -- For launch or release tasks, combine technical docs or release notes with messaging or marketing skills as needed. -- For high-risk changes, add security review, observability, or performance optimization as appropriate. -- For long-lived system changes, add architecture and system design, dependency lifecycle, or database migration planning when relevant. - -## Output Expectations - -- Deliver concrete work products, not just observations. -- State key assumptions when the repository does not answer them. -- Call out blockers, tradeoffs, risks, and unverified areas clearly. -- Keep explanations concise and action-oriented. diff --git a/DEPLOYMENT-PROFILE.md b/DEPLOYMENT-PROFILE.md deleted file mode 100644 index 9a81284..0000000 --- a/DEPLOYMENT-PROFILE.md +++ /dev/null @@ -1,99 +0,0 @@ -# Deployment Profile - -Use this file to stage prefilled defaults before deploying the suite into other repositories. - -This file is the canonical source of preloaded build, tool, environment, workflow, and quality preferences for the deployed bundle. Keep it concise enough to be read early in a session. - -## Precedence - -1. Destination repository instructions -2. This deployment profile -3. Generic `AGENTS.md`, hubs, and skill files - -## How To Maintain This File - -- Fill out [PROJECT-PROFILE-WORKBOOK.md](./PROJECT-PROFILE-WORKBOOK.md) first. -- Rewrite the answers here as agent-facing defaults, not as questions. -- Prefer short, durable defaults over long policy prose. -- Update this file when your preferred build, tool, or workflow defaults change materially. - -## Global Defaults - -- Optimize first for full-stack web application repositories. -- Assume Windows and PowerShell for local development, but keep Docker and Linux deployment realities in mind. -- Prefer compatibility-first tooling and standard stack defaults when multiple valid tools exist. -- Favor Node and TypeScript for application work, while using Python when it is the best fit for tooling or automation. -- Run the most relevant local tests for the changed area by default, and broaden verification for risky changes. -- Ask clarifying questions before meaningful changes when product intent or risk is unclear. -- Update documentation for meaningful changes, especially README content, Unraid install docs, roadmaps, and shipped or release-oriented summaries. -- Hold user-facing work to a high polish bar by default. -- Provide concise change summaries after meaningful work and call out rollout or migration impact when relevant. -- Optimize hardest against regressions and broken behavior. - -## Software Development Defaults - -- Favor modular boundaries and cleaner separation early rather than waiting for severe pain. -- Operate as a full-stack agent by default and work comfortably across frontend and backend. -- Prefer mainstream modern patterns for the stack when multiple valid options exist. -- Assume relational databases first unless the repository clearly indicates otherwise. -- Be careful with schema and migration work, but do not overengineer small changes. -- Prefer small, safe, frequent dependency upgrades with focused validation. -- Treat performance as important early, especially on critical paths. -- Apply a basic secure-defaults baseline: validate input, handle secrets safely, and respect auth boundaries. -- Maintain good operational hygiene with meaningful logs and diagnostics on important paths, and add more for risky systems. -- Use feature work as an opportunity for meaningful surrounding cleanup when the added refactoring clearly improves the change. - -## Debugging Defaults - -- Start with the fastest trustworthy signal rather than forcing a single debugging order. -- Lean on logs and traces heavily before guessing. -- During live or user-impacting incidents, stabilize first and diagnose more deeply after impact is reduced. -- Prefer reversible mitigations such as rollbacks, flags, or partial disablement when risk is high. -- Add regression tests for higher-risk or recurring bugs rather than treating every fix as a mandatory test addition. -- Explain root cause clearly by connecting symptom, cause, and why the fix works. -- Avoid temporary compromises unless there is no safer path. -- Bundle observability improvements with medium or high-risk bug fixes when they would make future diagnosis easier. - -## Documentation Defaults - -- Treat documentation as part of most meaningful implementation work unless it is clearly unnecessary. -- Default to practical onboarding that includes prerequisites, setup steps, validation, and common gotchas. -- Create or update ADRs for major technical decisions and meaningful pattern shifts. -- Write concise, audience-aware change summaries that call out user impact when relevant. -- Maintain strong API and integration documentation by default for meaningful backend or interface work. -- Prefer examples, snippets, and commands in places where they reduce ambiguity and improve adoption. -- Update docs for any meaningful user-facing, setup, or team workflow change. -- Bias toward concise documentation for reference material and more complete guidance for onboarding and operational content. - -## UI/UX Defaults - -- Prefer reuse of existing design-system components and patterns, but allow custom patterns when they clearly improve the experience. -- Do not assume extra accessibility work by default beyond the repository or task requirements unless the task calls for it. -- Design responsively for both desktop and mobile by default. -- Reuse components when they fit well, and create new abstractions when they are likely to matter again. -- Hold interface copy to a highly polished product-copy standard by default. -- Use motion and visual flourish actively enough to make interfaces feel premium. -- Bias toward bold, distinctive UI within reason rather than purely conservative continuity. -- Treat UI work as incomplete until important states, copy quality, polish, and edge cases are addressed. - -## Marketing Defaults - -- Prioritize a mixed audience with a lean toward technical and product-savvy readers. -- Use a premium, distinctive, and persuasive voice. -- Keep marketing claims persuasive but grounded in real features and outcomes. -- Default to a fuller launch kit when marketing work is requested: release notes, launch copy, landing page sections, and social or email variants as appropriate. -- Balance launch messaging with evergreen discoverability, but do not let SEO weaken clarity. -- Favor sharp, polished product copy with strong differentiation and clear calls to action. -- Frame positioning conservatively around real value rather than aggressive comparative claims. -- Prefer clear, action-oriented CTAs without heavy urgency. - -## Brainstorming Defaults - -- Favor breadth first when generating ideas. -- Generate three options by default before recommending one. -- Compare ideas primarily through user value, differentiation, and implementation realism. -- Prioritize roadmap or opportunity choices through strategic fit, user value, and implementation cost. -- Balance innovation with execution realism and require a believable path to implementation. -- Use a short-to-medium horizon with practical sequencing for roadmap framing. -- Turn brainstorming into a scoped implementation plan once a preferred option is selected. -- Do not filter ideas out too early; raise concerns and explore alternatives that may offer more value before narrowing. diff --git a/PROJECT.md b/PROJECT.md index d364e3d..4e8f868 100644 --- a/PROJECT.md +++ b/PROJECT.md @@ -1,242 +1,32 @@ -# UI Stock Tracker — Project Documentation +# UI Stock Tracker — Design Notes & Development History -**Status:** ✅ Complete and running -**Last updated:** 2026-06-06 +Supplementary notes that go beyond the [README](./README.md): the reasoning behind the trickier parts of the scraper and the notable fixes made during development. For setup, architecture, API, and schema, see the README; for deployment see [UNRAID.md](./UNRAID.md). ---- +## Stock Detection Rationale -## Purpose +The scraper classifies each product page as `in_stock`, `sold_out`, or `unknown` using case- and whitespace-insensitive substring matching against the page's buttons. Two non-obvious details drove the matching rules: -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. +**Auth-state difference.** The scraper runs logged out. On a sold-out item, Ubiquiti shows `"Login for Notifications"` to logged-out visitors instead of the logged-in `"Notify me when available"`. Both strings must be in the sold-out list, or logged-out checks would fall through to `unknown`. ---- +**The `label` attribute exists only on the in-stock button.** The production DOM carries `label="Add to Cart"` on the primary Add-to-Cart button (confirmed in DevTools), but the sold-out "Login for Notifications" button has no `label` attribute. So in-stock has two redundant signals (the attribute *and* the button text) while sold-out relies on text alone — this asymmetry is by design, not an oversight. -## Stack +When neither signal matches, the scraper logs a `[Scraper] UNKNOWN debug` payload (page title, button labels, button texts) so a misclassification can be diagnosed from container logs without reproducing locally. -| 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, waits for React hydration (2.5s + active wait for `