Files
willhaben-tracker/docs/phase-2/Phase.md

83 lines
5.2 KiB
Markdown

# Phase 2 — User Experience & Advanced Filtering
## Scope
This phase introduces **user-facing features** that significantly improve the experience of keyword tracking. Currently, every matching ad triggers an instant notification regardless of price, location, or time of day — leading to noise for popular keywords.
After this phase:
- Users can configure price ranges and postcodes per keyword
- Notifications respect mute hours (no alerts at 3 AM)
- Users opt into digest mode (bundled summaries instead of individual pings)
## Architecture
```
┌──────────────────────────────────────────────┐
│ User Interaction Layer │
│ │
│ Telegram Bot Commands: │
│ /set_price_min <kw> <€> │
│ /set_price_max <kw> <€> │
│ /set_postcode <kw> <list> │
│ /mute_hours <start>-<end> │
│ /digest on|off │
│ │
└──────────┬───────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ Database Schema (extended) │
│ │
│ keywords table: │
│ + price_min int │
│ + price_max int │
│ + allowed_postcodes text[] │
│ │
│ user_settings table (new): │
│ telegram_id text PK │
│ mute_start time │
│ mute_end time │
│ digest_mode bool DEFAULT false │
│ digest_interval int DEFAULT 60 │
└──────────┬───────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ Notification Pipeline (modified) │
│ │
│ For each new ad: │
│ ├─ filter by price_min/max? → skip │
│ ├─ filter by allowed_postcodes? → skip │
│ ├─ user in mute hours? │
│ │ digest_on → buffer to digest_table │
│ │ digest_off→ skip notification │
│ └─ normal → send now │
│ │
│ Digest scheduler (separate task): │
│ every digest_interval: │
│ collect buffered notifications per user │
│ format as summary message │
│ send single message │
│ clear buffer │
└──────────────────────────────────────────────┘
```
## Tasks
| Task | File | Description |
|------|------|-------------|
| Price range filters per keyword | [task-price-filters.md](./task-price-filters.md) | Add `price_min` and `price_max` columns to the keywords table; filter ads during processing based on these thresholds. Bot commands to set/unset. |
| Location / postcode filters per keyword | [task-postcode-filters.md](./task-postcode-filters.md) | Add `allowed_postcodes` text[] column to keywords; only notify if an ad's location matches any allowed postcode. |
| Mute hours per user | [task-mute-hours.md](./task-mute-hours.md) | Create `user_settings` table with configurable mute window (start/end time in UTC); suppress notifications during this window. |
| Digest / summary notifications | [task-digest-notifications.md](./task-digest-notifications.md) | Buffer notifications for users with digest mode enabled; send a bundled summary at configured intervals instead of individual alerts. |
## General Acceptance Criteria
- [ ] Users can set price min/max on any keyword and only receive notifications within that range
- [ ] Postcode filtering works — ads outside allowed postcodes are silently skipped (not counted as new)
- [ ] Mute hours suppress all notifications to a user during the configured window, regardless of keyword
- [ ] Digest mode buffers individual alerts and sends one summary message at the configured interval
- [ ] All filters combine correctly: an ad is only notified if it passes price + postcode checks AND the user is not muted (or digest mode active)
- [ ] The bot provides clear feedback when a filter setting is changed ("Keyword X: price range set to €100–€500")
- [ ] Admin can view all keyword filters and user settings via `/keywords` command output