diff --git a/web/src/padelnomics/admin/routes.py b/web/src/padelnomics/admin/routes.py index b0729fc..398b022 100644 --- a/web/src/padelnomics/admin/routes.py +++ b/web/src/padelnomics/admin/routes.py @@ -2142,7 +2142,7 @@ async def scenario_preview(scenario_id: int): async def scenario_pdf(scenario_id: int): """Generate and immediately download a business plan PDF for a published scenario.""" from ..businessplan import get_plan_sections - from ..planner.calculator import validate_state + from ..planner.calculator import calc, validate_state scenario = await fetch_one("SELECT * FROM published_scenarios WHERE id = ?", (scenario_id,)) if not scenario: @@ -2153,7 +2153,7 @@ async def scenario_pdf(scenario_id: int): lang = "en" state = validate_state(json.loads(scenario["state_json"])) - d = json.loads(scenario["calc_json"]) + d = calc(state) sections = get_plan_sections(state, d, lang) sections["scenario_name"] = scenario["title"] sections["location"] = scenario.get("location", "") @@ -2274,6 +2274,18 @@ async def _sync_static_articles() -> None: template_slug, group_key, now_iso, now_iso), ) + # Build HTML so the article is immediately servable (cornerstones have no template) + if template_slug is None: + from ..content.routes import BUILD_DIR, bake_product_cards, bake_scenario_cards + + body = raw[m.end():] + body_html = mistune.html(body) + body_html = await bake_scenario_cards(body_html, lang=language) + body_html = await bake_product_cards(body_html, lang=language) + build_dir = BUILD_DIR / language + build_dir.mkdir(parents=True, exist_ok=True) + (build_dir / f"{slug}.html").write_text(body_html) + def _build_article_where( status: str = None, @@ -2601,15 +2613,18 @@ async def articles_bulk(): from ..content.routes import BUILD_DIR rows = await fetch_all( - f"SELECT id, slug FROM articles WHERE {where} LIMIT 5000", tuple(where_params) + f"SELECT id, slug, template_slug FROM articles WHERE {where} LIMIT 5000", + tuple(where_params), ) for a in rows: build_path = BUILD_DIR / f"{a['slug']}.html" if build_path.exists(): build_path.unlink() - md_path = Path("data/content/articles") / f"{a['slug']}.md" - if md_path.exists(): - md_path.unlink() + # Only remove source .md for generated articles; cornerstones have no template + if a["template_slug"] is not None: + md_path = Path("data/content/articles") / f"{a['slug']}.md" + if md_path.exists(): + md_path.unlink() await execute(f"DELETE FROM articles WHERE {where}", tuple(where_params)) from ..sitemap import invalidate_sitemap_cache invalidate_sitemap_cache() @@ -2655,16 +2670,18 @@ async def articles_bulk(): from ..content.routes import BUILD_DIR articles_rows = await fetch_all( - f"SELECT id, slug FROM articles WHERE id IN ({placeholders})", + f"SELECT id, slug, template_slug FROM articles WHERE id IN ({placeholders})", tuple(article_ids), ) for a in articles_rows: build_path = BUILD_DIR / f"{a['slug']}.html" if build_path.exists(): build_path.unlink() - md_path = Path("data/content/articles") / f"{a['slug']}.md" - if md_path.exists(): - md_path.unlink() + # Only remove source .md for generated articles; cornerstones have no template + if a["template_slug"] is not None: + md_path = Path("data/content/articles") / f"{a['slug']}.md" + if md_path.exists(): + md_path.unlink() await execute( f"DELETE FROM articles WHERE id IN ({placeholders})", tuple(article_ids),