feat: enrich lawrisk v2 with permit scopes

This commit is contained in:
Codex Agent 2025-10-23 16:15:46 +08:00
parent cc1bda89a4
commit 90b1c06862
2 changed files with 57 additions and 20 deletions

View File

@ -14,20 +14,22 @@ def _compose_prompt(payload: Dict[str, Any]) -> str:
"""Build a natural-language prompt snippet from structured payload."""
region = payload.get("region", {})
theme = payload.get("theme", {})
scopes = payload.get("business_scopes", [])
permits = payload.get("permits", [])
lines: List[str] = []
lines.append(f"地区:{region.get('name', '')}")
lines.append(f"主题事项:{theme.get('name', '')}")
if scopes:
scope_text = "".join(scope.get("description", "") for scope in scopes if scope.get("description"))
if scope_text:
lines.append(f"涉及经营范围:{scope_text}")
for permit in permits:
pname = permit.get("name", "")
lines.append(f"许可事项:{pname}")
permit_scopes = permit.get("business_scopes", [])
if permit_scopes:
scope_text = "".join(
scope.get("description", "") for scope in permit_scopes if scope.get("description")
)
if scope_text:
lines.append(f" 经营范围:{scope_text}")
risks = permit.get("risks", [])
for idx, risk in enumerate(risks, start=1):
detail_parts = []

View File

@ -1,7 +1,7 @@
from __future__ import annotations
import os
from typing import Dict, List, Tuple
from typing import Dict, List
import pg8000.dbapi as pg
@ -71,6 +71,39 @@ def load_business_scopes(region_id: str) -> List[Dict[str, str]]:
return scopes
def _load_permit_scopes_for_region(
conn: pg.Connection, region_id: str, permit_ids: List[str]
) -> Dict[str, List[Dict[str, str]]]:
"""Return mapping of permit_id -> business scopes for that permit within region."""
scope_map: Dict[str, List[Dict[str, str]]] = {pid: [] for pid in permit_ids}
if not permit_ids:
return scope_map
sql = """
SELECT rps.permit_id, bs.id, bs.description
FROM region_permit_scopes rps
JOIN business_scopes bs ON bs.id = rps.scope_id
WHERE rps.region_id = %s
ORDER BY rps.permit_id, bs.description
"""
cur = conn.cursor()
try:
cur.execute(sql, (region_id,))
except pg.ProgrammingError as exc:
# 42P01 => undefined_table; allow fallback when migration not yet applied.
sqlstate = getattr(exc, "sqlstate", "")
if sqlstate == "42P01":
return scope_map
raise
for permit_id, scope_id, description in cur.fetchall():
pid = str(permit_id)
if pid not in scope_map:
continue
scope_map[pid].append({"id": str(scope_id), "description": str(description)})
return scope_map
def load_permits_and_risks(region_id: str, theme_id: str) -> List[Dict[str, object]]:
"""Return permits with attached risk entries for a region-theme pair."""
sql = """
@ -103,11 +136,11 @@ def load_permits_and_risks(region_id: str, theme_id: str) -> List[Dict[str, obje
{
"id": pid,
"name": str(permit_name),
"business_scopes": [],
"risks": [],
},
)
if risk_id is None:
continue
if risk_id is not None:
entry["risks"].append(
{
"id": str(risk_id),
@ -117,6 +150,11 @@ def load_permits_and_risks(region_id: str, theme_id: str) -> List[Dict[str, obje
"summary": summary or "",
}
)
permit_ids = list(permits.keys())
scope_map = _load_permit_scopes_for_region(conn, region_id, permit_ids)
for pid in permit_ids:
permits[pid]["business_scopes"] = scope_map.get(pid, [])
return list(permits.values())
@ -138,12 +176,9 @@ def load_theme_payload(region_id: str, theme_id: str) -> Dict[str, object]:
raise ValueError("Region/theme combination not found")
region_uuid, region_name, theme_uuid, theme_name = row
scopes = load_business_scopes(region_id)
permits = load_permits_and_risks(region_id, theme_id)
return {
"region": {"id": str(region_uuid), "name": str(region_name)},
"theme": {"id": str(theme_uuid), "name": str(theme_name)},
"business_scopes": scopes,
"permits": permits,
}