feat(affiliate): tests, ruff cleanup, CHANGELOG + PROJECT.md (commit 9/9)

- 26 tests in web/tests/test_affiliate.py covering hash_ip determinism,
  daily rotation, product CRUD, bake_product_cards marker replacement,
  click redirect (302 + logged), inactive/unknown 404, multi-retailer
- ruff: fix E741 ambiguous var (l → line in _form_to_product), F401 unused
  import, I001 import sort in admin/routes.py
- CHANGELOG: affiliate product system entry
- PROJECT.md: affiliate system moved to Done, Wirecutter backlog item removed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Deeman
2026-02-28 21:06:01 +01:00
parent 1fdd2d07a4
commit 5c22ea9780
4 changed files with 360 additions and 6 deletions

View File

@@ -1,7 +1,7 @@
# Padelnomics — Project Tracker
> Move tasks across columns as you work. Add new tasks at the top of the relevant column.
> Last updated: 2026-02-27 (Phase 2b — EU NUTS-2 spatial join + US state income).
> Last updated: 2026-02-28 (Affiliate product system — editorial gear cards + click tracking).
---
@@ -132,6 +132,7 @@
- [x] **pSEO article noindex**`noindex` column on articles (migration 0025), `NOINDEX_THRESHOLDS` per-template lambdas in `content/__init__.py`, robots meta tag in `article_detail.html`, sitemap exclusion, pSEO dashboard count card + article row badge; 20 tests
- [x] **group_key static article grouping** — migration 0020 adds `group_key TEXT` column; `_sync_static_articles()` auto-upserts `data/content/articles/*.md` on admin page load; `_get_article_list_grouped()` groups by `COALESCE(group_key, url_path)` so EN/DE static cornerstones pair into one row
- [x] **Email-gated report PDF**`reports/` blueprint with email capture gate + PDF download; premium WeasyPrint PDF (full-bleed navy cover, Padelnomics wordmark watermark, gold/teal accents); `make report-pdf` target; EN + DE i18n (26 keys, native German); state-of-padel report moved to `data/content/reports/`
- [x] **Affiliate product system** — "Wirecutter for padel" editorial gear cards embedded in articles via `[product:slug]` / `[product-group:category]` markers, baked at build time; `/go/<slug>` click-tracking redirect (302, GDPR daily-rotated IP hash, rate-limited); admin CRUD with live preview, HTMX filter/search, status toggle; click stats dashboard (pure CSS charts); 10 German equipment review article scaffolds; 26 tests
### SEO & Legal
- [x] Sitemap (both language variants, `<lastmod>` on all entries)
@@ -243,7 +244,6 @@
### Marketing & Content
- [ ] LinkedIn presence (ongoing — founder posts, thought leadership)
- [ ] "Wirecutter for padel" affiliate site (racket reviews, gear guides)
- [ ] "The Padel Business Report" newsletter
- [ ] Equipment supplier affiliate partnerships (€5001,000/lead or 5%)
- [ ] Padel podcasts (guest appearances)