Files
willhaben-tracker/docs/phase-3/Phase.md
T

4.9 KiB

Phase 3 — Scalability & Advanced Features

Scope

This phase introduces structural improvements that make the project maintainable, extensible, and testable. Currently, the entire system is a single async Python process with no tests and no CI/CD pipeline. After this phase:

  • Automated tests provide confidence for every change (≥80% coverage)
  • CI/CD pipeline runs on every push to validate code quality
  • Multi-marketplace architecture enables adding new sources without modifying core logic

Architecture

┌──────────────────────────────────────────────────────┐
│  Project Structure (post-Phase-3)                     │
│                                                      │
│  willhaben-tracker/                                   │
│    ├── worker/                                        │
│    │   ├── src/                                       │
│    │   │   ├── main.py       (entry point, scheduler) │
│    │   │   ├── db.py         (asyncpg pool mgmt)      │
│    │   │   ├── bot.py        (Telegram handlers)      │
│    │   │   ├── notifier.py   (message sending)        │
│    │   │   ├── scraper.py    (base scraper class)     │
│    │   │   ├── scrapers/                                 │
│    │   │   │   ├── __init__.py                          │
│    │   │   │   ├── willhaben.py  (willhaben-specific)   │
│    │   │   │   └── base.py       (abstract base class)  │
│    │   │   ├── health.py     (healthcheck endpoint)   │
│    │   │   └── migrate.py    (migration runner)       │
│    │   ├── tests/                                       │
│    │   │   ├── conftest.py                                │
│    │   │   ├── test_scraper.py                            │
│    │   │   ├── test_notifier.py                           │
│    │   │   └── ...                                      │
│    │   ├── Dockerfile                                   │
│    │   └── requirements.txt                             │
│    ├── .github/                                         │
│    │   └── workflows/                                   │
│    │       └── ci.yml     (pytest + flake8 + coverage)  │
│    ├── pyproject.toml   (coverage config, tools)        │
│    └── docker-compose.yml                               │
└──────────────────────────────────────────────────────┘

Multi-marketplace abstraction:
  
  ScraperBase (abstract):
    - async fetch_ads(keyword) → list[dict]
    - async parse_response(html/json) → list[dict]
    - normalize_ad(raw) → dict with standard keys
    
  WillhabenScraper(ScraperBase):
    - implements willhaben-specific URL, headers, parsing
  
  Future: KleinAnzeigenScraper, MobileScraper, ...

CI/CD Pipeline (.github/workflows/ci.yml):
  
  on: push to main, feat/*; pull_request
  
  jobs:
    lint-and-test:
      └─ python 3.12
         ├─ flake8 (linting)
         ├─ pytest --cov=src tests/ (unit + integration tests)
         └─ coverage >= 80% (fail if not met)

Tests Structure:
  
  Unit tests:
    - test_scraper_pagination() — verify pagination logic with mock responses
    - test_price_filters() — verify filter functions
    - test_notification_retry() — verify retry queue behavior
  
  Integration tests:
    - Test against real willhaben API (rate-limited, cached)
    - PostgreSQL test container via docker-compose

Tasks

Task File Description
Multi-marketplace abstraction layer task-multi-marketplace.md Refactor scraper.py into a base class + per-marketplace implementations. Introduces a standard ad schema and factory for registering new sources.
Test suite with pytest (≥80% coverage) task-testing-pytest.md Add comprehensive unit tests covering scraper parsing, notification logic, price/postcode filters, retry queue, and scheduler flow. Configure coverage thresholds.

General Acceptance Criteria

  • CI pipeline runs on every push to main and feature branches — fails if lint or coverage checks are not met
  • Code coverage is ≥80% across all source files in worker/src/
  • Multi-marketplace abstraction works — adding a new marketplace requires only creating one file under scrapers/ with no changes to core logic
  • All existing functionality (willhaben scraping, notifications) continues to work after refactoring
  • The /health endpoint exposes test results or coverage stats (optional enhancement)