CRITICAL FIX: get_deals_by_radius returns polygon metadata, not deals

## Root Cause
After Pydantic migration, get_deals_by_radius() was attempting to validate
API responses as Deal objects. However, this endpoint returns POLYGON METADATA
(with fields: dealscount, polygon_id, settlementNameHeb), NOT individual deals.

All responses failed Pydantic validation (missing dealAmount, dealDate),
resulting in empty lists and 0 deals returned from ALL queries.

## Fixes Applied

### 1. client.py - get_deals_by_radius()
- Return type: `List[Deal]` → `List[Dict[str, Any]]`
- Remove Pydantic validation - return raw metadata dicts
- Update docstring to clarify this returns polygon metadata
- Add note to use find_recent_deals_for_address() for actual deals

### 2. client.py - find_recent_deals_for_address()
- Update to handle polygon metadata dicts (not Deal objects)
- Use dict.get('polygon_id') instead of model attribute access
- Rename variable: `nearby_deals` → `nearby_polygons` for clarity

### 3. fastmcp_server.py - get_deals_by_radius() tool
- Update to handle dict responses (not Deal objects)
- Remove strip_bloat_fields() call (not needed for metadata)
- Update docstring with WARNING about polygon metadata
- Change response keys: "deals" → "polygons", "total_deals" → "total_polygons"

### 4. Tests
- test_govmap_client.py: Update to expect dicts, not Deal objects
- test_fastmcp_tools.py: Update 3 tests to mock dict responses

## Impact
-  find_recent_deals_for_address() NOW WORKS (was returning 0 deals)
-  All 174 tests passing
-  E2E API test confirmed working with real data

## API Behavior Documented
get_deals_by_radius endpoint design:
1. Returns polygon/area metadata (not individual deals)
2. Extract polygon_ids from metadata
3. Call get_street_deals(polygon_id) to get actual deals
4. This workflow is automated in find_recent_deals_for_address()

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Nitzan Pomerantz
2025-10-27 09:38:21 +02:00
parent d8259ae2cf
commit 247ddad8cd
4 changed files with 84 additions and 75 deletions
+11 -9
View File
@@ -128,14 +128,16 @@ class TestGovmapClient:
@patch('requests.Session')
def test_get_deals_by_radius_success(self, mock_session_class):
"""Test successful deals by radius query."""
"""Test successful polygon metadata retrieval by radius."""
mock_response = Mock()
# API returns polygon metadata (not actual deals)
mock_response.json.return_value = [
{
"objectid": 12345,
"dealAmount": 1500000.0,
"dealDate": "2024-01-15",
"dealscount": "30",
"settlementNameHeb": "תל אביב-יפו",
"streetNameHeb": "דיזנגוף",
"houseNum": 50,
"polygon_id": "123-456"
}
]
@@ -148,11 +150,11 @@ class TestGovmapClient:
client = GovmapClient()
result = client.get_deals_by_radius((3870000.123, 3770000.456), radius=50)
# Now returns List[Deal]
# Now returns List[Dict] - polygon metadata, not Deal objects
assert len(result) == 1
assert isinstance(result[0], Deal)
assert result[0].objectid == 12345
assert result[0].settlement_name_heb == "תל אביב-יפו"
assert isinstance(result[0], dict)
assert result[0]["objectid"] == 12345
assert result[0]["polygon_id"] == "123-456"
mock_session.get.assert_called_once()
@patch('requests.Session')
@@ -245,9 +247,9 @@ class TestGovmapClient:
]
)
# Mock radius response - now returns List[Deal]
# Mock radius response - now returns List[Dict] (polygon metadata)
mock_radius.return_value = [
Deal(objectid=1, deal_amount=1500000, deal_date="2025-01-01", polygon_id="123-456")
{"objectid": 1, "dealscount": "10", "polygon_id": "123-456", "settlementNameHeb": "Tel Aviv"}
]
# Mock street deals response - now returns List[Deal]