გორა.
AI-translation · draft (awaiting native review)
Aperwind — каталог недвижимости Таиланда

ბიზნეს-ლოგიკა

Рынок, покупатель, путь по сайту и правила, по которым каталог решает, что показывать.

~4 წუთი წასაკითხი · 843 სიტყვა

TL;DR

Aperwind — публичный каталог новостроек Таиланда для иностранного покупателя. 839 строк каталога в базе, 657 лотов на витрине, 370 проектов, четыре региона: Пхукет, Бангкок, Самуи, Паттайя. Две локали, русская и английская, каждая страница живёт по своему адресу.

Данные приходят не из нашей админки, а из Google-таблицы агентства, которую ведут менеджеры. Она меняется каждый день и без предупреждения: коды лотов переименовывают, строки переставляют, проекты переименовывают с опечатками, цены правят. Отсюда вся логика проекта — она отвечает не на вопрос «как показать объект», а на вопрос «как не соврать посетителю, когда источник сегодня другой».

Что это и как устроено

Рынок и покупатель

Покупатель тайской новостройки почти всегда находится в другой стране. Он не может приехать и посмотреть, он выбирает по фотографиям и цифрам, и проверить их ему нечем. Ниша устроена так, что проверять как раз и приходится.

Цену называет менеджер, а не сайт. Типовой каталог пишет «цена по запросу» или показывает прошлогоднее число. У нас цены приходят из прайсов застройщиков и сверяются с таблицей поставщика ежедневно; лот без цены остаётся на витрине как «Цена по запросу» и не участвует в минимумах, медианах и расчёте доходности.

На фотографиях чаще всего рендер. Замер показал: из 195 обложек витрины настоящей съёмкой были 39. По файлу одно от другого не отличается — EXIF срезан у всех 564 файлов в папках со словом «render», а имя файла врёт в обе стороны. Кадры пересмотрены глазами, решение по каждому лежит в git вместе с обоснованием.

Настоящая фотография тоже может показывать не тот дом. У одного проекта на 276 апартаментов обложкой стояла честная съёмка одноэтажной виллы из его же папки. У двух посёлков одного застройщика — один и тот же файл байт в байт. Для этого в проверке данных есть отдельное правило на дубли обложек по md5.

Срок сдачи и рассрочка живут дольше стройки. Сданному дому нельзя показывать будущий срок и «рассрочку на период строительства», замороженному — обещание сдачи. Статус проекта из таблицы напрямую управляет тем, какие блоки страница вообще рисует.

В таблице поставщика есть служебные строки и чужие контакты. Столбец с комментариями менеджеров наружу не отдаётся никогда: там телефоны и мессенджеры сторонних агентов. Из него достаются только числа — срок договора, депозит, предоплата.

Путь посетителя

Шаг 1. Вход

Заход из поиска приходит не на главную, а сразу на страницу района, комплекса или лота. Поэтому у каждого раздела свой адрес вида /{язык}/buy/{город}/{район}/{тип}/{слаг}, и любая из шести ступеней открывается сама по себе. Язык выбирается по заголовку Accept-Language с учётом веса q: заголовок «английский понимаю плохо, русский хорошо» раньше уводил русского посетителя на английскую версию.

Шаг 2. Подбор

Каталог фильтруется по цене, спальням и типу жилья и сортируется по цене, площади или «рекомендуем». Фильтр — обычная GET-форма: без JavaScript она работает так же, а пустые поля вычищаются из адреса редиректом, чтобы у одной выдачи не было второго адреса. Цены считаются в батах, переключение на доллар, евро или рубль идёт на клиенте по курсам, которые обновляет ночной крон.

Шаг 3. Проверка

Страница лота показывает галерею, планировки, видеотур, таблицу платежей, расчёт расходов при покупке и соседние предложения того же комплекса. Страница жилого комплекса собирает все лоты проекта, а гид по району — рынок вокруг. Гидов 100, их тексты лежат в git и правятся конвейером с проверкой чисел: текст, который обещает «от 4,2 млн», не должен переживать изменение каталога молча.

Шаг 4. Заявка

Форма отдаёт заявку в базу и уведомление в Telegram. Заявка сохраняется даже у посетителя, который отказался от аналитики: лид — бизнес-запись, он не зависит от статистики.

Что необычного

Собственный номер лота. Код поставщика идентификатором не является: пять пар «проект + код» повторяются, девять строк несут заглушку. Поэтому каждому лоту один раз выдаётся собственный постоянный номер (882 выдано), и он не переиспользуется. По нему держатся и адрес страницы, и дата последней правки в карте сайта.

Снять с витрины — не значит удалить. Снятая карточка исчезает из списков и счётчиков, но её страница остаётся живой, индексируемой и в карте сайта. Иначе каждое движение в таблице поставщика било бы по уже накопленным позициям в поиске.

Три числа вместо одного. 839 строк в базе, 657 на витрине, 600 в карте сайта. Разница — снятая вторичка и аренда, служебные строки и тонкие страницы без фотографий и описания, которым в карте сайта делать нечего.

Правки данных переживают синк. Ежедневный перенос пересобирает лоты, поэтому ручные решения — снятие, порядок карточек, рекомендованные проекты — лежат в отдельных таблицах с ключом «слаг проекта + код», а фильтры вроде снятой вторички живут в коде приложения.

Гео и язык

Восемь локалей описаны в коде, включены две: русская и английская. Русская — основная аудитория агентства, английская отвечает за остальной мир и стоит x-default в hreflang. Новый язык добавляется строкой в список: меню в шапке, hreflang, og:locale и карта сайта строятся из одного источника.

География берётся из справочника владельца таблицы и не додумывается. Регион и район — разные уровни, район по названию проекта не угадывается, расстояние до пляжа показывается в метрах с именем пляжа. Для Бангкока море не показывается вовсе: в девяти строках источника там стоит «40 km from the See», и это известное исключение, а не данные.