Delay PF permit competitor removal
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 35s

This commit is contained in:
Grendgi
2026-06-05 12:36:15 +03:00
parent 7a4d03c905
commit 1b8382a6ca
5 changed files with 23 additions and 3 deletions

View File

@@ -56,3 +56,7 @@ def _migrate_competitor_listings_auto_fields() -> None:
conn.execute(text("ALTER TABLE competitor_listings ADD COLUMN permit_number VARCHAR(100)"))
if "auto_discovered" not in columns:
conn.execute(text("ALTER TABLE competitor_listings ADD COLUMN auto_discovered BOOLEAN NOT NULL DEFAULT 0"))
if "permit_missing_checks" not in columns:
conn.execute(
text("ALTER TABLE competitor_listings ADD COLUMN permit_missing_checks INTEGER NOT NULL DEFAULT 0")
)

View File

@@ -82,6 +82,7 @@ class CompetitorListing(Base):
agency_name: Mapped[str | None] = mapped_column(String(300), nullable=True)
permit_number: Mapped[str | None] = mapped_column(String(100), nullable=True)
auto_discovered: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
permit_missing_checks: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
current_price: Mapped[float | None] = mapped_column(Float, nullable=True)
currency: Mapped[str | None] = mapped_column(String(10), nullable=True, default="AED")

View File

@@ -40,6 +40,7 @@ BAYUT = BayutScraper()
# Same-building suggestions beyond exact permit matches are a browse heuristic —
# cap how many we show so the page stays usable.
_SUGGEST_OTHERS_LIMIT = 30
_PERMIT_MISSING_DELETE_THRESHOLD = 3
# Bayut moved to fully client-side rendering (no __NEXT_DATA__, Algolia keys
# hidden), so it can't be scraped over plain HTTP — disabled until we add a
@@ -237,12 +238,14 @@ def _hide_tracked_suggestions(
def sync_permit_competitors(
db: Session,
project: Project,
*,
count_missing: bool = True,
) -> tuple[list[str], dict[str, list[ScrapedListing]], str | None]:
"""Auto-maintain competitor listings with the same DLD permit.
Exact-permit matches are added automatically. Previously auto-discovered
exact-permit listings that disappear from the next permit search are
deleted. Manual competitors are never auto-deleted.
exact-permit listings are deleted only after several consecutive permit
searches miss them. Manual competitors are never auto-deleted.
"""
changes: list[str] = []
our_permit = resolve_our_permit(project)
@@ -268,6 +271,7 @@ def sync_permit_competitors(
listing = existing.get(key)
if listing:
listing.permit_number = item.permit_number or our_permit
listing.permit_missing_checks = 0
if item.title:
listing.title = item.title
if item.agent_name:
@@ -287,6 +291,11 @@ def sync_permit_competitors(
continue
if _listing_key(listing.source, listing.external_id) in matched_keys:
continue
if not count_missing:
continue
listing.permit_missing_checks = (listing.permit_missing_checks or 0) + 1
if listing.permit_missing_checks < _PERMIT_MISSING_DELETE_THRESHOLD:
continue
changes.append(_format_listing_removed(project, listing, auto=True))
db.delete(listing)

View File

@@ -115,7 +115,7 @@ def cmd_suggest(payload: dict[str, Any]) -> None:
project = db.get(Project, project_id)
if not project:
_fail("project not found")
changes, suggestions, permit = sync_permit_competitors(db, project)
changes, suggestions, permit = sync_permit_competitors(db, project, count_missing=False)
db.commit()
if changes:
notify_project_changes(project, changes)