Spaces:
Runtime error
Runtime error
| """Bridge report-template section IDs to standard-paragraph section IDs. | |
| When the PDF report template and Word standard-paragraphs file share the same | |
| canonical RICS L3 codes (D1, D2, …), aliases are identity mappings. Title overlap | |
| is used only when Word paragraph buckets use legacy alternate codes. | |
| """ | |
| from __future__ import annotations | |
| import re | |
| from pathlib import Path | |
| from backend.core.template_discoverer import ( | |
| DiscoveredChunk, | |
| discover_standard_paragraph_chunks, | |
| discover_standard_paragraph_titles, | |
| ) | |
| from backend.models.schema import SectionDefinition | |
| _STOP_WORDS = frozenset({ | |
| "about", "with", "from", "this", "that", "level", "section", "inside", | |
| "outside", "other", "property", "report", "survey", "your", "the", "and", | |
| }) | |
| def _title_tokens(title: str) -> set[str]: | |
| return { | |
| w for w in re.findall(r"[a-z]{4,}", (title or "").lower()) | |
| if w not in _STOP_WORDS | |
| } | |
| def _score_titles(report_title: str, paragraph_title: str) -> int: | |
| a, b = _title_tokens(report_title), _title_tokens(paragraph_title) | |
| if not a or not b: | |
| return 0 | |
| return len(a & b) | |
| def build_section_alias_map( | |
| report_sections: list[SectionDefinition], | |
| paragraph_titles: dict[str, str], | |
| ) -> dict[str, str]: | |
| """Map each report-template section id to a standard-paragraph section id. | |
| Strategy (in order): | |
| 1. Exact id match when the Word file has the same code. | |
| 2. Best title-token overlap (minimum 2 shared significant words). | |
| 3. Fallback: report id maps to itself (retrieval uses title+notes only). | |
| """ | |
| aliases: dict[str, str] = {} | |
| for sec in report_sections: | |
| if sec.id in paragraph_titles: | |
| aliases[sec.id] = sec.id | |
| continue | |
| best_id: str | None = None | |
| best_score = 0 | |
| for pid, ptitle in paragraph_titles.items(): | |
| score = _score_titles(sec.title, ptitle) | |
| if score > best_score: | |
| best_score = score | |
| best_id = pid | |
| if best_id and best_score >= 2: | |
| aliases[sec.id] = best_id | |
| else: | |
| aliases[sec.id] = sec.id | |
| return aliases | |
| def paragraph_titles_from_word(path: Path) -> dict[str, str]: | |
| """Return ``{section_id: title}`` from the standard-paragraphs Word file.""" | |
| return discover_standard_paragraph_titles(path) | |
| def paragraph_chunks_from_word(path: Path) -> list[DiscoveredChunk]: | |
| return discover_standard_paragraph_chunks(path) | |