feat: enrich lawrisk v2 with permit scopes
This commit is contained in:
parent
cc1bda89a4
commit
90b1c06862
|
|
@ -14,20 +14,22 @@ def _compose_prompt(payload: Dict[str, Any]) -> str:
|
||||||
"""Build a natural-language prompt snippet from structured payload."""
|
"""Build a natural-language prompt snippet from structured payload."""
|
||||||
region = payload.get("region", {})
|
region = payload.get("region", {})
|
||||||
theme = payload.get("theme", {})
|
theme = payload.get("theme", {})
|
||||||
scopes = payload.get("business_scopes", [])
|
|
||||||
permits = payload.get("permits", [])
|
permits = payload.get("permits", [])
|
||||||
|
|
||||||
lines: List[str] = []
|
lines: List[str] = []
|
||||||
lines.append(f"地区:{region.get('name', '')}")
|
lines.append(f"地区:{region.get('name', '')}")
|
||||||
lines.append(f"主题事项:{theme.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:
|
for permit in permits:
|
||||||
pname = permit.get("name", "")
|
pname = permit.get("name", "")
|
||||||
lines.append(f"许可事项:{pname}")
|
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", [])
|
risks = permit.get("risks", [])
|
||||||
for idx, risk in enumerate(risks, start=1):
|
for idx, risk in enumerate(risks, start=1):
|
||||||
detail_parts = []
|
detail_parts = []
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from typing import Dict, List, Tuple
|
from typing import Dict, List
|
||||||
|
|
||||||
import pg8000.dbapi as pg
|
import pg8000.dbapi as pg
|
||||||
|
|
||||||
|
|
@ -71,6 +71,39 @@ def load_business_scopes(region_id: str) -> List[Dict[str, str]]:
|
||||||
return scopes
|
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]]:
|
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."""
|
"""Return permits with attached risk entries for a region-theme pair."""
|
||||||
sql = """
|
sql = """
|
||||||
|
|
@ -103,11 +136,11 @@ def load_permits_and_risks(region_id: str, theme_id: str) -> List[Dict[str, obje
|
||||||
{
|
{
|
||||||
"id": pid,
|
"id": pid,
|
||||||
"name": str(permit_name),
|
"name": str(permit_name),
|
||||||
|
"business_scopes": [],
|
||||||
"risks": [],
|
"risks": [],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if risk_id is None:
|
if risk_id is not None:
|
||||||
continue
|
|
||||||
entry["risks"].append(
|
entry["risks"].append(
|
||||||
{
|
{
|
||||||
"id": str(risk_id),
|
"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 "",
|
"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())
|
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")
|
raise ValueError("Region/theme combination not found")
|
||||||
region_uuid, region_name, theme_uuid, theme_name = row
|
region_uuid, region_name, theme_uuid, theme_name = row
|
||||||
|
|
||||||
scopes = load_business_scopes(region_id)
|
|
||||||
permits = load_permits_and_risks(region_id, theme_id)
|
permits = load_permits_and_risks(region_id, theme_id)
|
||||||
return {
|
return {
|
||||||
"region": {"id": str(region_uuid), "name": str(region_name)},
|
"region": {"id": str(region_uuid), "name": str(region_name)},
|
||||||
"theme": {"id": str(theme_uuid), "name": str(theme_name)},
|
"theme": {"id": str(theme_uuid), "name": str(theme_name)},
|
||||||
"business_scopes": scopes,
|
|
||||||
"permits": permits,
|
"permits": permits,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue