Commit Graph

91 Commits

Author SHA1 Message Date
Nitzan Pomerantz f5e0605393 Add GitHub Actions CI workflow for PR testing
- Runs unit tests with pytest on Python 3.12
- Only triggers on PRs to main branch
- Includes code coverage reporting (non-blocking)
- Lint checks for code quality (non-blocking)
- Integration tests are optional and non-blocking

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-25 00:53:48 +03:00
Nitzan Pomerantz 433642117d Merge pull request #3 from nitzpo/e2e-run
Fix: E2E bugs from real-world MCP testing
2025-10-25 00:44:35 +03:00
Nitzan Pomerantz fde0afa7a1 Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-10-25 00:43:26 +03:00
Nitzan Pomerantz 8be71aec55 Update tests/test_govmap_client.py
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-10-25 00:41:24 +03:00
Nitzan Pomerantz b62815ec08 Fix: Strip bloat fields to resolve MCP token limit issues
Problem:
- get_valuation_comparables failed with 61,565 tokens (exceeded 25K MCP limit)
- Large MULTIPOLYGON shape data consumed ~40-50% of response tokens
- Not useful for LLM analysis, only bloating responses

Solution:
1. Added strip_bloat_fields() helper to remove:
   - shape: Large coordinate data
   - sourceorder: Internal ordering field
   - source_polygon_id: Internal reference field

2. Applied to 5 MCP tools returning deal data:
   - get_deals_by_radius
   - get_street_deals
   - find_recent_deals_for_address
   - get_neighborhood_deals
   - get_valuation_comparables

3. Reduced get_valuation_comparables default max_comparables: 200 → 50

Results:
- Token usage reduced by ~87% (61K → ~7-8K tokens)
- All tools now work within MCP token limits
- Cleaner, more efficient responses
- No loss of useful data for LLM analysis

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-25 00:40:31 +03:00
Nitzan Pomerantz ee0b9466d4 Fix: Critical filtering bugs - missing data handling
Fixed two critical bugs in filter_deals_by_criteria():

Bug #1: CRASH on None property type
- Issue: Code called .lower() on None when propertyTypeDescription was null
- Impact: Would crash MCP tool in production with incomplete data
- Fix: Check if deal_type is None/empty before calling .lower()

Bug #2: Missing data passes through filters
- Issue: Deals with None/missing values passed filters when they shouldn't
- Example: Filtering by area=60-70 would include deals with assetArea=None
- Impact: get_valuation_comparables returned inflated results with bad data
- Fix: Explicitly check for None when filter is active and exclude those deals

Changes:
- Property type filter: Check for None/empty before normalization
- Area filter: Exclude deals with missing area when min/max_area specified
- Room filter: Exclude deals with missing rooms when min/max_rooms specified
- Price filter: Exclude deals with missing price when min/max_price specified
- Invalid data: Changed from 'pass' to 'continue' to exclude bad data

Added 6 comprehensive unit tests:
- test_filter_excludes_missing_property_type
- test_filter_excludes_missing_area
- test_filter_excludes_missing_rooms
- test_filter_excludes_missing_price
- test_filter_excludes_invalid_numeric_data
- test_filter_allows_missing_data_when_no_filter

This fixes the E2E issue where get_valuation_comparables was returning
incomplete results. Now filters properly exclude deals with missing data.

Test results: 34/34 passing (6 new tests added)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-25 00:08:05 +03:00
Nitzan Pomerantz c19af4cd4e Fix: Resolve 2 pre-existing test failures
Fixed both failing tests for 100% test coverage (28/28 passing):

Test 1: test_client_initialization_with_custom_url
- Issue: Test was passing string to GovmapClient constructor
- Fix: Import GovmapConfig and create proper config object
- Changes: Added import and wrapped custom_url in GovmapConfig

Test 2: test_find_recent_deals_for_address_integration
- Issue: Test expected date-first sorting, but function sorts by priority first
- Fix: Updated test expectations to match actual business logic
- Behavior: Results sorted by source priority (building > street > neighborhood), then date
- Changes: Added priority field to mock data and fixed assertions

All 28 tests now passing 

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 23:53:54 +03:00
Nitzan Pomerantz fe0a96ab83 Fix: Address E2E bugs from real-world MCP testing
Fixes three critical bugs discovered during live testing with Claude:

Bug #1: Same building detection always returned 0
- Root cause: deal.get('address') returned empty string
- Fix: Construct address from streetNameHeb + houseNum fields
- Added test: test_same_building_detection_with_api_fields

Bug #2: Property type filter too strict
- Root cause: Exact match failed for variants like 'דירת גג'
- Fix: Use flexible substring matching with normalization

Bug #3: Deal deduplication used non-existent field
- Root cause: Deduplication key referenced deal.get('address')
- Fix: Removed non-existent field from deduplication key

Also added _calculate_distance() helper for future radius filtering.

Test results: 26/28 passing (2 pre-existing failures unrelated)
References: .cursor/plans/MCP-E2E-TEST-SUMMARY.md

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 23:47:07 +03:00
Nitzan Pomerantz 43d031d7c1 Getting ready for phase 3 2025-10-24 23:36:58 +03:00
Nitzan Pomerantz f3054c6231 Merge pull request #2 from nitzpo/phase-2
Complete Phase 2: Market Analysis, Filtering & Documentation
2025-10-24 23:35:27 +03:00
Nitzan Pomerantz 56ed1029e0 Fix tests for time_period_months filtering implementation
Update tests to pass time_period_months=None for tests using old dates
(2022-2023) to disable time filtering. This is necessary because the
time_period_months parameter is now properly implemented and filters
out old deals by default.

Tests fixed:
- test_calculate_market_activity_score_success
- test_calculate_market_activity_score_high_activity
- test_get_market_liquidity_success
- test_get_market_liquidity_quarterly_breakdown

All market analysis tests now pass (25/27 tests passing, 2 pre-existing
failures unrelated to our changes).

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 19:36:04 +03:00
Nitzan Pomerantz 943a03ae5a Improve test assertion specificity and formatting
Replace broad assertion (mean > 0) with specific expected value using
pytest.approx for floating-point comparison. This makes the test more
robust and prevents future regressions.

Changes:
- Change area_stats mean assertion from > 0 to == pytest.approx(80.0)
- Add final newline to file per convention

Expected mean: (80 + 90 + 70) / 3 = 80.0

Addresses PR #2 review comments on line 527.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 19:27:32 +03:00
Nitzan Pomerantz ac6c780419 Improve fastmcp_server error handling and code quality
Refactor repetitive try-except blocks using _safe_calculate_metric helper
function to reduce code duplication and improve maintainability.

Changes:
- Add _safe_calculate_metric helper to centralize error handling
- Remove misleading default values (0/"unknown") in summary fields
- Use None defaults instead to clearly indicate unavailable data
- Add final newline to file per convention

This prevents LLMs from misinterpreting 0 as "zero investment potential"
when it actually means "data unavailable".

Addresses PR #2 review comments on lines 733, 749, and 759.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 19:26:52 +03:00
Nitzan Pomerantz e5fb218ac0 Refactor date parsing and implement time period filtering
Extract duplicated date parsing logic into a reusable _parse_deal_dates
helper method. This centralizes error handling, validation, and date
grouping logic across multiple market analysis functions.

Key improvements:
- DRY: Eliminates code duplication across three functions
- Implements time_period_months filtering (fixes unused parameter bug)
- Returns both monthly and quarterly breakdowns in one pass
- Consistent error handling and logging
- Better maintainability

This change fixes the unused time_period_months parameters in both
calculate_market_activity_score and get_market_liquidity functions.

Addresses PR #2 review comments on lines 1013, 1058, and 1257.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 19:23:06 +03:00
Nitzan Pomerantz 11512045dd Extract magic numbers into named constants
Define module-level constants for market activity, volatility, and liquidity
thresholds. This improves code readability and makes threshold values easier
to maintain and adjust in the future.

Constants added:
- ACTIVITY_VERY_HIGH_THRESHOLD, ACTIVITY_HIGH_THRESHOLD, etc.
- VOLATILITY_VERY_VOLATILE_THRESHOLD, VOLATILITY_VOLATILE_THRESHOLD, etc.
- LIQUIDITY_VERY_HIGH_THRESHOLD, LIQUIDITY_HIGH_THRESHOLD, etc.

Addresses PR #2 review comments on lines 1084 and 1224.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 19:22:03 +03:00
Nitzan Pomerantz 2968711307 Complete Phase 2: Market Analysis, Filtering & Documentation
This commit implements all Phase 2 functionality with architectural
improvements over the original plan.

## Phase 2.1: Property Valuation Data 
- filter_deals_by_criteria() with comprehensive filtering
- calculate_deal_statistics() for statistical aggregations
- _extract_floor_number() for Hebrew floor parsing
- _calculate_std_dev() helper function
- MCP tools: get_valuation_comparables, get_deal_statistics

## Phase 2.2: Market Activity & Investment Analysis 
- calculate_market_activity_score() - deal frequency & velocity
  * Activity score (0-100), trend analysis, monthly distribution
  * Classifies markets: very_high, high, moderate, low, very_low
- analyze_investment_potential() - price trends & stability
  * Price appreciation rate via linear regression
  * Volatility score using coefficient of variation
  * Investment score combining appreciation & stability
- get_market_liquidity() - turnover & liquidity metrics
  * Quarterly/monthly breakdowns, velocity scoring
  * Trend direction, most active periods
- MCP tool: get_market_activity_metrics (unified tool)

## Phase 2.3: Enhanced Deal Filtering 
- Property type, room count, price, area, floor filtering
- All integrated into existing tools
- Hebrew floor number parsing support

## Testing 
- Added 15 comprehensive unit tests (all passing)
- Coverage: market activity, investment analysis, liquidity, filtering
- Edge cases: empty data, invalid dates, insufficient data

## Documentation 
- Created CLAUDE.md (~250 lines) - AI agent guidance
  * Development commands, architecture overview
  * Product vision from USECASES.md
  * Available tools with status indicators
- Updated TASKS.md - Phase 2 marked 100% complete

## Architectural Improvements
- 1 unified MCP tool instead of 6 separate tools (simpler API)
- 1 flexible filtering function instead of 3 (more composable)
- All logic in govmap.py (no new files, better cohesion)
- ~955 lines added with comprehensive documentation

## Design Principles Followed
 MCP provides data, LLM provides intelligence
 No predictions - only statistical calculations
 Comprehensive error handling & input validation
 Well-documented with detailed docstrings

Phase 2 Progress: 100% complete (60% overall project completion)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 18:51:50 +03:00
Nitzan Pomerantz 53e730ea66 Merge pull request #1 from nitzpo/comprehensive-plan-phase-1
Comprehensive-plan-phase-1
2025-10-23 00:12:13 +03:00
Nitzan Pomerantz d9e42bea17 Some more small fixes 2025-10-23 00:11:41 +03:00
Nitzan Pomerantz 49bfc7b940 CR Fixes and update markdownlint 2025-10-22 23:59:07 +03:00
Nitzan Pomerantz 7780d89bb4 Update tasks and plan 2025-10-19 01:02:36 +03:00
Nitzan Pomerantz 85f52a8108 Main updates of Phase 1 2025-10-19 00:58:46 +03:00
Nitzan Pomerantz b844760147 Remove old file 2025-10-19 00:58:27 +03:00
Nitzan Pomerantz e0dacbc5b9 Fix requirements 2025-10-19 00:58:20 +03:00
Nitzan Pomerantz c71f950eb7 Added documentation 2025-10-19 00:58:11 +03:00
Nitzan Pomerantz ffd7c84aa7 Added plan 2025-10-19 00:57:50 +03:00
Nitzan Pomerantz fb1f276a80 Add amenities to usecases 2025-10-19 00:02:15 +03:00
Nitzan Pomerantz 055b2bcc2a Add markdownlint 2025-10-19 00:02:06 +03:00
Nitzan Pomerantz 9ee5372b1c Another iteration 2025-07-14 14:26:53 +03:00
Nitzan Pomerantz 650048445f Optimization because of long running times 2025-07-14 13:40:36 +03:00
Nitzan Pomerantz 80dfaa28f0 Improving parameters 2025-07-14 13:12:44 +03:00
Nitzan Pomerantz eb4bf3894c Use cases guide 2025-07-13 01:07:54 +03:00
Nitzan Pomerantz 4f3b74ceaf Refactor fastmcp 2025-07-13 01:05:16 +03:00
Nitzan Pomerantz dd6d78b48b Refactor govmap 2025-07-13 01:03:15 +03:00
Nitzan Pomerantz a1fa75a878 mcp clean up 2025-07-13 00:56:47 +03:00
Nitzan Pomerantz d8c18cb2f7 mcp second iteration 2025-07-13 00:50:51 +03:00
Nitzan Pomerantz 76bdc323df MCP server first iteration 2025-07-12 22:11:12 +03:00
Nitzan Pomerantz 1f1f4fc0ec Added tests 2025-07-12 17:48:50 +03:00
Nitzan Pomerantz f422aeaa79 First iteration 2025-07-12 17:45:54 +03:00
Nitzan Pomerantz f3d3a8efd4 Update gitignore for python 2025-07-12 17:44:48 +03:00
Nitzan Pomerantz f5ba5bd5c1 Commit start prompt that was used by gemini to generate start2 prompt for claude 4 2025-07-12 17:43:43 +03:00
Nitzan Pomerantz f199defdf7 Initial commit 2025-07-12 12:27:22 +03:00