Matching ======== ``PropertyMatcher`` applies hard filters first and soft scoring second. A property that fails a hard requirement is never rescued by a high score. .. autoclass:: app.alba_core.matching.MatchingOutput :members: .. autoclass:: app.alba_core.matching.PropertyMatcher :members: Example ------- .. code-block:: python from app.alba_core.matching import PropertyMatcher from app.alba_core.models import RentalRequirements from app.propertyme.cache import load_property_cache properties = load_property_cache("data/propertyme_property_seed_latest.json") requirements = RentalRequirements( city="Queenstown", budget_max=5000, bedrooms_min=3, move_in_timing="asap", priority="location", ) output = PropertyMatcher(top_n=3).match(requirements, properties) print(output.rejected_reasons) for match in output.matches: print(match.property.address, match.score, match.match_notes) No-match handling ----------------- .. code-block:: python impossible = RentalRequirements(city="Auckland", budget_max=100, bedrooms_min=8) output = PropertyMatcher().match(impossible, properties) if not output.matches: print("No real listing fits the current hard filters.") print(output.rejected_reasons)