Matching
PropertyMatcher applies hard filters first and soft scoring second. A
property that fails a hard requirement is never rescued by a high score.
- class app.alba_core.matching.MatchingOutput(matches: list[MatchResult], rejected_reasons: dict[str, int])[source]
Collection of successful matches and aggregate rejection reasons.
- class app.alba_core.matching.PropertyMatcher(top_n: int = 3)[source]
Hard filters first, soft scoring second.
The most important rule is that scoring never rescues a listing that failed a hard requirement such as city, budget, or minimum bedrooms.
- match(requirements: RentalRequirements, properties: list[PropertyRecord]) MatchingOutput[source]
Filter, score, sort, and return the best matching properties.
Example
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
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)