Bundles feature WIP + fix request-access products cap (20 -> 200)

- app/main.py: raise products_raw[:20] cap to [:200] in /api/request-access
  and /api/request-more-access - was silently truncating access requests
  with more than 20 selected products
- accumulated bundles/product-page WIP (config, models, runtime, templates)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-29 13:58:09 +00:00
parent f5c53f01bf
commit 40de4d5a0f
12 changed files with 2407 additions and 457 deletions
+21
View File
@@ -1,6 +1,7 @@
import datetime as dt
import json
import logging
import re
import contextvars
from pathlib import Path
from typing import Optional
@@ -86,6 +87,26 @@ def format_service_comment(raw_text: str) -> Markup:
return Markup(_md(raw))
def format_seo_description(raw_text: str) -> Markup:
"""Render a service's long-form SEO description (public /product/{slug}
page) to HTML. Unlike format_service_comment() (short dashboard card
text), this source text may carry its own leading '# Product Name'
title line - the page template already renders an <h1> with the name,
so a duplicate <h1> here would hurt SEO. We drop that leading title
line if present, and downgrade any other single-# headings (section
headers like '# Возможности') to ## so the page never emits more than
one <h1>."""
raw = (raw_text or "").replace("\r\n", "\n").replace("\r", "\n").strip()
if not raw:
return Markup("")
lines = raw.split("\n")
if lines and re.match(r"^#\s+", lines[0]):
lines = lines[1:]
body = "\n".join(lines).strip()
body = re.sub(r"(?m)^#\s+", "## ", body)
return Markup(_md(body))
def parse_rdp_target(target: str) -> dict:
raw = (target or "").strip()
if not raw: