Commit Graph

8 Commits

Author SHA1 Message Date
Deeman
e33b28025e fix: use SQLite-compatible space format in utcnow_iso(), fix credits ordering
utcnow_iso() now produces 'YYYY-MM-DD HH:MM:SS' (space separator) matching
SQLite's datetime('now') so lexicographic comparisons like
'published_at <= datetime(now)' work correctly.

Also add `id DESC` tiebreaker to get_ledger() ORDER BY to preserve
insertion order when multiple credits are added within the same second.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 10:30:18 +01:00
Deeman
a05c230ce3 fix(tests): replace datetime.utcnow() with utcnow_iso() in test files
Also fixes test_supplier_webhooks.py fromisoformat() comparisons:
expires (naive, from DB) now compared against datetime.now(UTC).replace(tzinfo=None)
to avoid mixing naive/aware datetimes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 10:24:16 +01:00
Deeman
ffe4b111eb fix: remove double language prefix from article URLs
generate_articles() was storing url_path with lang prefix (/en/markets/...)
but the content blueprint is registered at /<lang>, producing double-prefix
URLs like /en/en/markets/italy. Fix: store url_path without prefix, build
full_url with prefix for SEO tags (canonical, OG, hreflang, breadcrumbs).

Also removes /markets from RESERVED_PREFIXES since article sub-paths under
/markets/ are valid pSEO content URLs, not blueprint routes.

Subtask 1 of pSEO template improvements.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 02:01:33 +01:00
Deeman
f0f6e7542f feat: move article generation to background worker queue
- Add generate_articles task handler to worker.py
- template_generate and template_regenerate now enqueue tasks instead
  of running inline (was blocking HTTP request for seconds with 1k articles)
- rebuild_all enqueues per-template + inline rebuilds manual articles
- Update tests to check task enqueue instead of immediate article creation

Subtask 4 of CMS admin improvement.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 01:17:59 +01:00
Deeman
afd46398af test: add E2E and unit tests for pSEO CMS flows
38 new tests covering all previously untested code paths:

Content module unit tests:
- TestDiscoverTemplates: discovery, empty dir, invalid frontmatter
- TestLoadTemplate: config+body loading, missing template, schema normalization
- TestExtractFaqPairs: FAQ extraction, no FAQ section, end-of-doc
- TestBuildBreadcrumbs: path segments, root, hyphenated labels
- TestBuildJsonld: BreadcrumbList, Article, FAQPage, headline truncation
- TestPreviewArticle: rendering, unknown row, language, unknown template

Admin route E2E tests:
- TestAdminTemplateDetail: config view, columns, sample data, unknown slug
- TestAdminTemplatePreview: rendered article, bad key/template redirects
- TestAdminTemplateGenerate: form display, article+scenario creation, unknown
- TestAdminTemplateRegenerate: idempotent update, unknown template redirect
- TestAdminTemplates: list shows discovered templates from disk

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 12:48:26 +01:00
Deeman
f1181342ad feat: SSG-inspired pSEO CMS — git templates + DuckDB direct reads
Replace the old CSV-upload-based CMS with an SSG architecture where
templates live in git as .md.jinja files with YAML frontmatter and
data comes directly from DuckDB serving tables. Only articles and
published_scenarios remain in SQLite for routing/state.

- Content module: discover, load, generate, preview functions
- Migration 0018: drop article_templates + template_data, recreate
  articles + published_scenarios without FK references, add
  template_slug/language/date_modified/seo_head columns
- Admin routes: read-only template views with generate/regenerate/preview
- SEO pipeline: canonical URLs, hreflang (EN+DE), JSON-LD (Article,
  FAQPage, BreadcrumbList), Open Graph tags baked at generation time
- Example template: city-cost-de.md.jinja for German city market data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 12:25:44 +01:00
Deeman
2521ba61b6 fix(test): correct article slug in test_article_url_and_title
Article slug is template_slug + city_slug ("city-cost-miami"),
not just the city slug ("miami").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 10:48:43 +01:00
Deeman
4ae00b35d1 refactor: flatten padelnomics/padelnomics/ → repo root
git mv all tracked files from the nested padelnomics/ workspace
directory to the git repo root. Merged .gitignore files.
No code changes — pure path rename.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 00:44:40 +01:00