bharatgraph / api /routes /profile.py
abinazebinoy's picture
fix(BUG-03/22): removed duplicate fallback block; added sources field to ProfileResponse
99375ed
Raw
History Blame Contribute Delete
6.02 kB
import os, sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException
from loguru import logger
from api.models import ProfileResponse, ProfileSection, SourceDocument
from api.dependencies import get_db
router = APIRouter()
@router.get("/profile/{entity_id}", response_model=ProfileResponse)
def get_profile(entity_id: str, driver=Depends(get_db)):
logger.info(f"[Profile] entity_id={entity_id}")
with driver.session() as session:
pol = session.run(
"MATCH (p:Politician {id: $id}) RETURN p", id=entity_id
).single()
if pol:
p = dict(pol["p"])
sections = []
contracts = session.run(
"""
MATCH (p:Politician {id: $id})-[:DIRECTOR_OF]->(c:Company)
-[:WON_CONTRACT]->(ct:Contract)
RETURN c.name AS company, ct.order_id AS order_id,
ct.amount_crore AS amount, ct.buyer_org AS buyer,
ct.order_date AS date
ORDER BY ct.amount_crore DESC
""",
id=entity_id
).data()
if contracts:
sections.append(ProfileSection(
section="Contracts via Associated Companies",
data=contracts,
sources=[SourceDocument(
institution="Government e-Marketplace",
document_title="GeM Procurement Order",
url="https://gem.gov.in",
)]
))
audits = session.run(
"""
MATCH (a:AuditReport)-[:FLAGS]->(s:Scheme)
WHERE toLower(a.title) CONTAINS toLower($name)
RETURN a.title AS title, a.year AS year,
a.amount_crore AS amount, s.name AS scheme
""",
name=p.get("name", "")
).data()
if audits:
sections.append(ProfileSection(
section="CAG Audit Mentions",
data=audits,
sources=[SourceDocument(
institution="Comptroller and Auditor General",
document_title="Performance Audit Report",
url="https://cag.gov.in/en/audit-report",
)]
))
return ProfileResponse(
entity_id=entity_id,
entity_type="Politician",
name=p.get("name", ""),
overview={
"party": p.get("party"),
"state": p.get("state"),
"criminal_cases": p.get("criminal_cases"),
"total_assets": p.get("total_assets"),
"education": p.get("education"),
"source": p.get("source"),
},
sections=sections,
generated_at=datetime.now().isoformat(),
)
co = session.run(
"MATCH (c:Company {id: $id}) RETURN c", id=entity_id
).single()
if co:
c = dict(co["c"])
contracts = session.run(
"""
MATCH (c:Company {id: $id})-[:WON_CONTRACT]->(ct:Contract)
RETURN ct.order_id AS order_id, ct.amount_crore AS amount,
ct.buyer_org AS buyer, ct.order_date AS date
ORDER BY ct.amount_crore DESC
""",
id=entity_id
).data()
sections = []
if contracts:
sections.append(ProfileSection(
section="Government Contracts Won",
data=contracts,
sources=[SourceDocument(
institution="Government e-Marketplace",
document_title="GeM Procurement Order",
url="https://gem.gov.in",
)]
))
return ProfileResponse(
entity_id=entity_id,
entity_type="Company",
name=c.get("name", ""),
overview={
"cin": c.get("cin"),
"status": c.get("status"),
"state": c.get("state"),
"class": c.get("company_class"),
},
sections=sections,
generated_at=datetime.now().isoformat(),
)
# Generic fallback: return whatever node exists for this ID
with driver.session() as session:
generic = session.run(
"""
MATCH (n {id: $id})
RETURN n, labels(n)[0] AS label
""",
id=entity_id
).single()
if generic:
n = dict(generic["n"])
label = generic["label"] or "Unknown"
name = n.get("name") or n.get("title") or n.get("ngo_name") or n.get("company_name") or entity_id
# Build context-aware sections
sections = []
overview = {k: v for k, v in n.items()
if k not in ("id",) and v is not None}
return ProfileResponse(
entity_id=entity_id,
entity_type=label,
name=name,
overview=overview,
sections=sections,
sources=[SourceDocument(
institution="BharatGraph Knowledge Graph",
document_title=f"{label} Record",
url="https://abinaze.github.io/bharatgraph",
)],
generated_at=datetime.now().isoformat(),
)
# BUG-07 FIX: Generic fallback handles AuditReport, Contract, NGO,
# ElectoralBond, EnforcementAction, Tender, InsolvencyOrder, etc.
raise HTTPException(status_code=404, detail=f"Entity {entity_id} not found")