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>
This commit is contained in:
Deeman
2026-02-24 01:17:59 +01:00
parent 81b361859d
commit f0f6e7542f
3 changed files with 80 additions and 34 deletions

View File

@@ -1019,7 +1019,7 @@ class TestAdminTemplateGenerate:
assert "3" in html # 3 rows available
assert "Generate" in html
async def test_generate_creates_articles(self, admin_client, db, pseo_env):
async def test_generate_enqueues_task(self, admin_client, db, pseo_env):
async with admin_client.session_transaction() as sess:
sess["csrf_token"] = "test"
@@ -1030,11 +1030,16 @@ class TestAdminTemplateGenerate:
})
assert resp.status_code == 302
articles = await fetch_all("SELECT * FROM articles")
assert len(articles) == 3
scenarios = await fetch_all("SELECT * FROM published_scenarios")
assert len(scenarios) == 3
# Generation is now queued, not inline
tasks = await fetch_all(
"SELECT * FROM tasks WHERE task_name = 'generate_articles'"
)
assert len(tasks) == 1
import json
payload = json.loads(tasks[0]["payload"])
assert payload["template_slug"] == "test-city"
assert payload["start_date"] == "2026-04-01"
assert payload["articles_per_day"] == 2
async def test_generate_unknown_template_redirects(self, admin_client, db, pseo_env):
resp = await admin_client.get("/admin/templates/nonexistent/generate")
@@ -1042,13 +1047,7 @@ class TestAdminTemplateGenerate:
class TestAdminTemplateRegenerate:
async def test_regenerate_updates_articles(self, admin_client, db, pseo_env):
from padelnomics.content import generate_articles
# First generate
await generate_articles("test-city", date(2026, 3, 1), 10)
initial = await fetch_all("SELECT * FROM articles")
assert len(initial) == 3
async def test_regenerate_enqueues_task(self, admin_client, db, pseo_env):
async with admin_client.session_transaction() as sess:
sess["csrf_token"] = "test"
@@ -1057,9 +1056,14 @@ class TestAdminTemplateRegenerate:
})
assert resp.status_code == 302
# Same count — upserted, not duplicated
articles = await fetch_all("SELECT * FROM articles")
assert len(articles) == 3
# Regeneration is now queued, not inline
tasks = await fetch_all(
"SELECT * FROM tasks WHERE task_name = 'generate_articles'"
)
assert len(tasks) == 1
import json
payload = json.loads(tasks[0]["payload"])
assert payload["template_slug"] == "test-city"
async def test_regenerate_unknown_template_redirects(self, admin_client, db, pseo_env):
async with admin_client.session_transaction() as sess: