← Задача 009 — все материалы · оригинал на GitHub

Задача 009 — веб-исследование: модель данных CRM недвижимости и бесплатная гео-карта

Все страницы просмотрены 2026-11-02. Пометка 🔮 Додумал: — вывод без прямого подтверждения источником. Пометка «✅ Проверил запросом» — один тестовый HTTP-запрос из терминала 2026-11-02 (не браузер).

Главное за 30 секунд


1. Модель данных CRM недвижимости

1.1. Физический объект и объявление — разные сущности

1.2. Остальные сущности — как они называются в стандартах и CRM

1.3. Сводная модель, применимая к нашему случаю


2. Нормализация адресов и бесплатные координаты без ключей

2.1. Nominatim (OpenStreetMap) — правила использования, цитаты

2.2. Photon (komoot) — альтернатива на тех же данных OSM

2.3. ICGC Geocoder — официальный геокодер Каталонии

2.4. Catastro (Sede Electrónica del Catastro) — открытый поиск по адресу и по референции

2.5. Открытые данные Барселоны — границы barris и districtes

2.6. Как привязать точку к району


3. Карта локально без сервера

3.1. Leaflet — версия и подключение

3.2. Фильтр по району и типу сделки

3.3. Группировка близких точек — Leaflet.markercluster

3.4. Тайлы и file:// — что работает, а что нет

3.5. Готовые онлайн-инструменты (для сравнения)


4. История переговоров и «предпочтения по переговорам» в CRM

4.1. Стадии воронки (pipeline stages)

4.2. Итог и причина отказа (won / lost, lost reason)

4.3. Заметки об агенте и стиле общения

4.4. Что из этого применимо к маленькой личной базе markdown + JSON


Что берём для маленькой личной базы

  1. Разделить unit и listing. Довод: одну квартиру на Барселонете выставляют 2–3 агентства по разной цене — так делает RESO (Property = объявление, UPI = объект) и idealista при склейке дублей; иначе сравнение цен невозможно.
  2. Ключ дома — 14 символов referencia catastral, ключ квартиры — 20. Довод: бесплатно, без ключа API, однозначно решает «угловой дом с двумя адресами» (проверено на Sant Carles 10 / Pescadors 13).
  3. Координаты — ICGC Geocoder первым, Nominatim запасным, с кэшем в JSON. Довод: ICGC официальный для Каталонии и отдаёт нормализованную улицу и номер; Nominatim требует 1 запрос/с, свой User-Agent и кэш — для десятков адресов это одна минута.
  4. Район считать один раз и хранить codi_barri в записи. Довод: карта и фильтры работают без Turf и без сети; источник — официальный JSON Open Data BCN (CC BY 4.0), перевод в GeoJSON ≈366 КБ одним скриптом.
  5. Карта — один HTML с Leaflet 1.9.4 с CDN и встроенным GeoJSON. Довод: ни сервера, ни сборки; фильтр через L.geoJSON({filter}) и L.control.layers, кластеры — markercluster 1.5.3.
  6. Тайлы — ICGC topografic по умолчанию, OSM — только через python3 -m http.server. Довод: OSM с 2026 года блокирует страницы с file:// без Referer; CARTO теперь требует ключ; ICGC отвечает без Referer и без ключа, лицензия CC-BY.
  7. Переговоры — сущность deal на пару «мы × объявление» с журналом событий. Довод: так устроены Pipedrive и HubSpot; история цены, просмотров и ответов агента — в одном месте, а не размазана по переписке.
  8. Короткий фиксированный список lost_reason + свободный комментарий, обязательный при lost. Довод: Pipedrive и HubSpot советуют готовый список ради сравнимости; валидатор не даст закрыть сделку без причины.
  9. Агент — markdown-заметка с frontmatter, взаимодействия — датированные пункты со ссылкой на сообщение WhatsApp. Довод: паттерн obsidian-crm проверен на личных CRM, читается без программ, а ссылка на сообщение делает каждый факт проверяемым.
  10. Отдельные воронки для покупки, аренды и сабаренды, а не одна общая. Довод: этапы разные (arras и нотариус против документов и договора аренды); общий список стадий путает фильтры.

Готовые ссылки для прототипа

Leaflet 1.9.4 (официальные теги с leafletjs.com/download)

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>

Leaflet.markercluster 1.5.3 (cdnjs, SRI из api.cdnjs.com)

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.5.3/MarkerCluster.css" integrity="sha512-mQ77VzAakzdpWdgfL/lM1ksNy89uFgibRQANsNneSTMD/bj0Y/8+94XMwYhnbzx8eki2hrbPpDm0vD0CiT2lcg==" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.5.3/MarkerCluster.Default.css" integrity="sha512-6ZCLMiYwTeli2rVh3XAPxy3YoR5fVxGdH/pz+KMCzRY2M65Emgkw00Yqmhh8qLGeYQ3LbVZGdmOX9KUjSKr0TA==" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.5.3/leaflet.markercluster.js" integrity="sha512-OFs3W4DIZ5ZkrDhBFtsCP6JXtMEDGmhl0QPlmWYBJay40TT1n3gt2Xuw8Pf/iezgW9CdabjkNChRqozl/YADmg==" crossorigin="anonymous"></script>

Turf.js 7.4.0 (только если point-in-polygon нужен в браузере)

Тайлы с атрибуцией

L.tileLayer('https://geoserveis.icgc.cat/servei/catalunya/mapa-base/wmts/topografic/MON3857NW/{z}/{x}/{y}.png', {
  maxZoom: 20,
  attribution: 'Catalonia &copy; <a href="https://www.icgc.cat/">ICGC</a> (CC BY) | Rest of world &copy; OpenMapTiles &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>'
}).addTo(map);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
  maxZoom: 19,
  referrerPolicy: 'strict-origin-when-cross-origin',
  attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>'
}).addTo(map);

Границы районов Барселоны (Open Data BCN, CC BY 4.0, атрибуция «© Ajuntament de Barcelona»)

Геокодеры (без ключей, с кэшем, не чаще 1 запроса в секунду)