Andrey Epifancev fb80d8c636 perf: генератор данных через API
Refs #202

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 22:08:30 +04:00

98 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Манифест стенда: что есть в БД и какие URL/пользователей использовать в сценариях.
Путь: perf/results/manifest-s{scale}.json.
Сегмент {direction} в URL листа: web/src/components/common/TableList/TableList.jsx
строит путь как `${table?.direction}`, поэтому при direction == null (JSON null из API)
в URL попадает литерал "null" (маршрут в web/src/app/Routes.jsx:
/table/form/:formId/form-type/:formType/:sheetName/:direction/:year).
Task 3 заполняет `svods` и `modal_pages` по маршрутам Routes.jsx
(/svod, /svod/2, /svods-navigator, /projects/summaries и т.д.) — это просто списки Page(name, url).
Лист свода выбирается вкладкой внутри страницы, не URL: у Page свода url = путь + '#' + имя листа
(`/svod#FORM_1`, `/svod/2#RF`); хеш на маршрутизацию не влияет, сценарий по нему выбирает вкладку.
"""
from __future__ import annotations
import json
from dataclasses import dataclass, field, asdict
from pathlib import Path
from . import RESULTS_DIR
NO_DIRECTION = "null" # см. docstring модуля
USER_KEYS = ("admin", "rf", "rf_coauthor", "dfip")
@dataclass
class Sheet:
form_id: int
form_type: str
sheet: str
direction: str | None
year: int
url: str
rows: int
# чьей оргединице принадлежит форма: "rf" — РФ пользователя `rf` (ему доступна), "ssp" — ССП
# (доступна admin/dfip, но не `rf`). Поле добавлено Task 3, по умолчанию "rf".
owner: str = "rf"
@staticmethod
def build_url(form_id, form_type, sheet, direction, year) -> str:
d = NO_DIRECTION if direction is None else direction
return f"/table/form/{form_id}/form-type/{form_type}/{sheet}/{d}/{year}"
@dataclass
class ProjectReport:
project_id: int
year: int
report_type: str
url: str
rows: int
@dataclass
class Page:
name: str
url: str
@dataclass
class User:
username: str
password: str
role_id: int
@dataclass
class Manifest:
scale: int
users: dict[str, User] = field(default_factory=dict)
sheets: list[Sheet] = field(default_factory=list)
project_reports: list[ProjectReport] = field(default_factory=list)
svods: list[Page] = field(default_factory=list)
modal_pages: list[Page] = field(default_factory=list)
def manifest_path(scale: int, results_dir: Path | None = None) -> Path:
return Path(results_dir or RESULTS_DIR) / f"manifest-s{scale}.json"
def dump(m: Manifest, path) -> None:
path = Path(path)
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(asdict(m), ensure_ascii=False, indent=2), encoding="utf-8")
def load(path) -> Manifest:
d = json.loads(Path(path).read_text(encoding="utf-8"))
return Manifest(
scale=d["scale"],
users={k: User(**v) for k, v in d.get("users", {}).items()},
sheets=[Sheet(**x) for x in d.get("sheets", [])],
project_reports=[ProjectReport(**x) for x in d.get("project_reports", [])],
svods=[Page(**x) for x in d.get("svods", [])],
modal_pages=[Page(**x) for x in d.get("modal_pages", [])],
)