poradnik

Niech mieszkanie szuka mnie (czyli: jestem cron)

Igor Pielas ·

Szukam mieszkania w Warszawie i nie chce mi się wieczorów spędzać na klikaniu po Otodom, Gratce i kolejnych portalach. Pomyślałem: a jak by tak mieszkania szukały mnie? Zbudowałem sobie więc prywatny portal - House Tinder - który robi za mnie cały skrining, śledzi ceny, generuje matche pod moje filtry, a przez serwer MCP każdy cloud agent może na nim operować. To moja prywatna automatyzacja szukania mieszkania.

Szukam mieszkania w Warszawie. Mam firmę, sześćset innych rzeczy. Klikać codziennie wieczorem po Otodom, Gratce i sprawdzać "co nowego dziś" - nie ma w moim kalendarzu takiej linijki.

W pewnym momencie mnie zastanowiło, czemu ja w ogóle muszę te mieszkania szukać. To one powinny przychodzić do mnie. Postawiłem sobie więc swój własny portal nieruchomości - House Tinder.

Co to właściwie jest

Prywatna aplikacja, którą traktuję jak personal CRM do polowania na mieszkanie. Ekran startowy mam swój, z filtrami, które nazywam "łowami". Ustawiam filtr: "Mokotów, Wilanów, Ursynów, 3 pokoje, do 1.6M, 60-90m², 800m od wybranego adresu" - i to jest cały mój kontakt z portalami. Reszta dzieje się sama.

Co kilka godzin mój worker idzie na Otodom i Gratkę, ściąga oferty pasujące do każdej "łowy", robi diff względem poprzedniego runu (co nowe, co zniknęło, co zmieniło cenę), i wrzuca nowości do osobnego inboxu. Tam czeka na mnie ekran w stylu Tindera - jedna oferta na środku, trzy przyciski: NIE / DOBRE / SUPER. Swipe i lecę dalej. Te oznaczone jako "DOBRE" lub "SUPER" trafiają na osobną listę "👁️ NA OKU" - moja krótka piątka, gdzie śledzę zmiany cen, dopisuję notatki, koryguję adres jeśli agent wpisał błędny.

To wszystko. Ale każdy z tych elementów został wybrany świadomie, więc rozbiję to.

Po co web portal

Bo potrzebuję jednego miejsca decyzyjnego. Notatki, status, ceny w czasie, mapa, historia "łów", to-co-odrzuciłem-i-dlaczego - wszystko trzymane razem, w jednym ciemnym (lub jasnym) UI w paletce, którą sobie zaprojektowałem. Każde wejście do portalu to ja patrzący na zwężony zbiór mieszkań, nie nieskończony scroll po tysiącach ofert.

Po co serwer MCP

Tu jest najciekawsza warstwa. Cała baza danych - łowy, oferty, decyzje triage, snapshoty cen, ulubione - siedzi na Supabase, a obok niej działa serwer MCP (Model Context Protocol). To znaczy, że każdy cloud agent (Claude, mój własny custom assistant, cokolwiek) może:

  • Zapytać przez chat: "ile nowych ofert pojawiło się w ostatnim tygodniu w łowie 'Mokotów 3-pok'?"
  • Wygenerować mi w cloudzie raport: "porównanie cen mieszkań na NA OKU z ostatnich 30 dni".
  • Z poziomu telefonu szepnąć "oznacz ofertę 12345 jako super" - i wrócić do roboty.

To samo źródło prawdy, co UI. Tylko że zamiast klikać, mówię. To jest właśnie ta automatyzacja, która naprawdę liczy.

Pod spodem

Krótko, dla zainteresowanych technicznie:

  • TypeScript strict, monorepo pnpm.
  • Supabase: Postgres + Storage + Auth + pgcron + pgnet.
  • Zero scrapowania DOM - cały data flow przez `_NEXTDATA__` JSON osadzony w HTML. To ten sam state, który dostaje aplikacja portalu w przeglądarce. Stabilniej, czyściej, mniej shenaniganów.
  • Cron: Postgres dosłownie sam w sobie wzywa Edge Functions HTTP-em co kilka godzin. Jeśli ktoś szuka "co automatyzuje moje życie" - to jestem ja, ale jako cron. Stąd tytuł.
  • Multi-portal hybrid: każdy portal ma własne tabele pod pola unikalne (np. Omnibus na Gratce vs agencylicense na Otodom), ale **decyzje user-a są generic** - jedna tabela `listingtriage` z kluczem `(source, external_id)`. Dodanie trzeciego portalu = jedna migracja, zero zmian w UI.
  • Audit trail: każdy scrape zapisuje raw HTML do Storage (gzip, 30 dni TTL). Mogę odtworzyć każdą decyzję z każdej minuty.

Tinder dla mieszkań - czemu

Bo decyzje są binarne. Albo mnie kręci, albo nie. Trzy guziki, opcjonalny modal "z jakiego powodu nie" (8 chipów: dzielnica, cena, parter, agencja, ...) - i to jest wszystko, co potrzebuję. Stan trzymany w prostym state machinie z guardami: oferta odrzucona w inboxie nigdy nie miesza się z ofertą zarchiwizowaną z NA OKU. Dwie różne ścieżki, dwa różne sub-source.

Co dalej

Mapa drogowa zaczyna robić się gęsta:

  1. Kolejne portale. Po Otodom i Gratce dociągnę OLX, Domiportę, Morizon, może jeszcze parę. Architektura multi-portal już jest gotowa - każdy nowy portal to jedna migracja i zero zmian w UI. Im więcej źródeł, tym pełniejszy obraz rynku w jednym inboxie i jednym Tinderze.
  2. Agent-to-agent. Cel finałowy: AI agent, który dostaje moje 5 najlepszych SUPER, czyta kontakty z bazy, pisze maile do agentów nieruchomości i koordynuje jeden optymalny dzień oglądania. Bierze koordynaty mieszkań, układa trasę Google Mapsem, negocjuje godziny ("wolałbym 14:00-16:00, czy mogłaby pani przesunąć?"). Sam pyta, sam negocjuje, sam mi mówi: "wtorek, cztery oglądania w tej kolejności, czas startu 14:30". Ja wsiadam w auto.
  3. AI summarization + anty-prefs. Agent czyta polskie opisy ofert i daje mi TL;DR. Plus uczy się z moich `reject_reason`: jak odrzucam wszystko z parteru, niech mi nawet parterowych nie pokazuje. Niech tnie szum.
  4. Slack digest. Codziennie rano DM: "Masz 7 nowych w łowach Mokotów, spadek 5% w ofercie X, agent Y jeszcze nie odpisał na Twojego maila." Bez wchodzenia gdziekolwiek.

Refleksja

To jest aplikacja, którą można zbudować tylko, jak się jednocześnie jest klientem i programistą. Nikt komercyjnie nie napisze Tinder UI dla decyzji o mieszkaniach z Reject Reason Modal w 8 chipach, bo nikt poza mną tego nie chce. Ale ja - bardzo chcę.

I tak właśnie wygląda dla mnie budowanie z jaj: dziewięć migracji, dwanaście ADR-ów, multi-portal, MCP server, cron, Tinder UI - wszystko po to, żeby nie klikać po Otodom.

Bo czasu mam tyle, ile mam. A mieszkania niech szukają mnie.