Merge pull request 'feat(claims): אכלוס claims.party_name במקור + backfill — סגירת השדה-המת (#224)' (#403) from worktree-claims-party-name-populate into main
This commit was merged in pull request #403.
This commit is contained in:
@@ -221,7 +221,7 @@ async def aggregate_claims_to_arguments(
|
|||||||
|
|
||||||
# Pull all claims for this case, grouped by party.
|
# Pull all claims for this case, grouped by party.
|
||||||
rows = await conn.fetch(
|
rows = await conn.fetch(
|
||||||
"""SELECT id, party_role, claim_text, claim_index, source_document
|
"""SELECT id, party_role, claim_text, claim_index, source_document, party_name
|
||||||
FROM claims
|
FROM claims
|
||||||
WHERE case_id = $1
|
WHERE case_id = $1
|
||||||
ORDER BY party_role, claim_index""",
|
ORDER BY party_role, claim_index""",
|
||||||
@@ -249,10 +249,13 @@ async def aggregate_claims_to_arguments(
|
|||||||
# Map deprecated 'appraiser' or unknown labels to 'unknown'.
|
# Map deprecated 'appraiser' or unknown labels to 'unknown'.
|
||||||
if party not in ALLOWED_PARTIES:
|
if party not in ALLOWED_PARTIES:
|
||||||
party = "unknown"
|
party = "unknown"
|
||||||
party_name = (
|
# Prefer the stored party_name (stamped by the extractor, #224); fall
|
||||||
(r["source_document"] or "").strip()
|
# back to source_document for legacy claims predating the stamping.
|
||||||
if party in SPLIT_PARTIES else ""
|
# Single-voice sides (appellant/committee) stay ''.
|
||||||
)
|
if party in SPLIT_PARTIES:
|
||||||
|
party_name = (r["party_name"] or "").strip() or (r["source_document"] or "").strip()
|
||||||
|
else:
|
||||||
|
party_name = ""
|
||||||
by_group.setdefault((party, party_name), []).append(dict(r))
|
by_group.setdefault((party, party_name), []).append(dict(r))
|
||||||
|
|
||||||
# Valid claim_ids for this case == the ids of the claims we just fetched.
|
# Valid claim_ids for this case == the ids of the claims we just fetched.
|
||||||
|
|||||||
@@ -645,7 +645,12 @@ async def _build_claims_context(case_id: UUID) -> str:
|
|||||||
groups: dict[tuple[str, str], list[dict]] = {}
|
groups: dict[tuple[str, str], list[dict]] = {}
|
||||||
for c in source_claims:
|
for c in source_claims:
|
||||||
role = c.get("party_role", "") or ""
|
role = c.get("party_role", "") or ""
|
||||||
brief = (c.get("source_document", "") or "").strip() if role in SPLIT_PARTIES else ""
|
# Prefer the stored party_name (stamped by the extractor, #224); fall
|
||||||
|
# back to source_document for legacy claims predating the stamping.
|
||||||
|
if role in SPLIT_PARTIES:
|
||||||
|
brief = (c.get("party_name") or "").strip() or (c.get("source_document") or "").strip()
|
||||||
|
else:
|
||||||
|
brief = ""
|
||||||
groups.setdefault((role, brief), []).append(c)
|
groups.setdefault((role, brief), []).append(c)
|
||||||
|
|
||||||
def _sort_key(k: tuple[str, str]) -> tuple[int, str]:
|
def _sort_key(k: tuple[str, str]) -> tuple[int, str]:
|
||||||
|
|||||||
@@ -368,8 +368,15 @@ async def extract_and_store_claims(
|
|||||||
|
|
||||||
# Determine claim_type from document type and title
|
# Determine claim_type from document type and title
|
||||||
claim_type = _infer_claim_type(doc_type, source_name)
|
claim_type = _infer_claim_type(doc_type, source_name)
|
||||||
|
# Stamp party_name at the source (#224). For a multi-litigant side
|
||||||
|
# (respondent / permit_applicant) the brief label IS the source pleading, so
|
||||||
|
# opposing briefs (משיבות 2-3 vs משיבים 4-6) stay distinct downstream without
|
||||||
|
# the aggregator/block-writer having to re-derive it. SPLIT_PARTIES is the
|
||||||
|
# single rule shared with the aggregator (G2); single-voice sides stay ''.
|
||||||
|
from legal_mcp.services.argument_aggregator import SPLIT_PARTIES
|
||||||
for c in claims:
|
for c in claims:
|
||||||
c["claim_type"] = claim_type
|
c["claim_type"] = claim_type
|
||||||
|
c["party_name"] = source_name if c.get("party_role") in SPLIT_PARTIES else ""
|
||||||
|
|
||||||
stored = await db.store_claims(case_id, claims, source_document=source_name)
|
stored = await db.store_claims(case_id, claims, source_document=source_name)
|
||||||
# Mark this document analysed (WS2 / #201). store_claims already replaced
|
# Mark this document analysed (WS2 / #201). store_claims already replaced
|
||||||
|
|||||||
@@ -1918,6 +1918,20 @@ ALTER TABLE cases ADD COLUMN IF NOT EXISTS hearing_attendees JSONB NOT NULL DEFA
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# V52 (#224): backfill claims.party_name for existing rows. The extractor now
|
||||||
|
# stamps party_name = source_document for the multi-litigant sides at write time
|
||||||
|
# (claims_extractor), but claims stored before that shipped have party_name=''.
|
||||||
|
# For those, the brief label is the source pleading — same rule the aggregator
|
||||||
|
# uses (respondent / permit_applicant split). Idempotent: only fills empties, so
|
||||||
|
# re-running is a no-op. Single-voice sides (appellant/committee) stay ''.
|
||||||
|
SCHEMA_V52_SQL = """
|
||||||
|
UPDATE claims SET party_name = source_document
|
||||||
|
WHERE party_role IN ('respondent', 'permit_applicant')
|
||||||
|
AND COALESCE(party_name, '') = ''
|
||||||
|
AND COALESCE(source_document, '') <> '';
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
# Stable, arbitrary key for the session-level advisory lock that serialises
|
# Stable, arbitrary key for the session-level advisory lock that serialises
|
||||||
# schema DDL across processes. Every short-lived process (cron drains, services)
|
# schema DDL across processes. Every short-lived process (cron drains, services)
|
||||||
# re-runs the idempotent migrations on startup; without this lock two processes
|
# re-runs the idempotent migrations on startup; without this lock two processes
|
||||||
@@ -1991,6 +2005,7 @@ async def _apply_schema_ddl(conn: asyncpg.Connection) -> None:
|
|||||||
await conn.execute(SCHEMA_V49_SQL)
|
await conn.execute(SCHEMA_V49_SQL)
|
||||||
await conn.execute(SCHEMA_V50_SQL)
|
await conn.execute(SCHEMA_V50_SQL)
|
||||||
await conn.execute(SCHEMA_V51_SQL)
|
await conn.execute(SCHEMA_V51_SQL)
|
||||||
|
await conn.execute(SCHEMA_V52_SQL)
|
||||||
|
|
||||||
|
|
||||||
async def init_schema() -> None:
|
async def init_schema() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user