fix: exclude room-less Property from every price bound - #15
Merged
Conversation
Close #10. `filterHotels` guarded only the max_price side of the band. A room-less Property has `price_from = Infinity`, and `Infinity < minPrice` is `false`, so such a Property wrongly *passed* a `min_price` floor — a null-priced hotel surfacing inside a price-bounded result. Root cause (confirmed by a red test): the asymmetric guard. A Property with no bookable rate has no price and should satisfy neither bound. Guard the non-finite `price_from` up front so it fails both the floor and the ceiling symmetrically. - Regression test: extend the room-less case in search.test.ts to cover the min_price floor and a full band, alongside the existing max_price ceiling. - Document the ruling in ADR-0003 (consequences) and ASSUMPTIONS.md. The seed has 0 room-less Properties (40/40 have Rooms), so this is a defensive-path correctness fix with no observable change today. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Owner
Author
|
Post-mortem — what would have caught this earlier The original The regression test in this PR closes that gap: the room-less case now covers the floor, the ceiling, and a full band together, so the two sides can't drift apart again. No architectural change needed — the seam was fine; the test coverage was one-sided. |
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #10.
The bug
filterHotels(src/domain/search.ts) guarded only themax_priceside of the band. A room-less Property hasprice_from = Infinity, andInfinity < minPriceisfalse, so such a Property passed amin_pricefloor — e.g.GET /hotels?min_price=1000would surface a Property whoseprice_fromisnull.Root cause
Confirmed with a red test first: the asymmetric guard.
Infinity > maxPricealready excluded room-less Properties from the ceiling, but nothing excluded them from the floor.Fix
A Property with no bookable rate has no price and should satisfy neither bound. Guard the non-finite
price_fromup front so it fails both sides symmetrically.Documentation
Verification
test/search.test.tsto cover themin_pricefloor and a full band (the existingmax_priceceiling assertion stays).npm run verify(typecheck → lint → test): clean, 54/54 pass.Impact
Defensive-path only — the seed has 0 room-less Properties (40/40 have Rooms), so there is no observable change today.
🤖 Generated with Claude Code