Привет, сообщество! Уже долгое время я отмечал на для себя на карте бесплатные парковочные места в центре города; Этот список быстро начал "ходить по рукам" среди друзей и знакомых. Мне пришла в голову идея, а что если развить "списочек для друзей" в какой-то более общественно полезный проект? И с какими техническими челленджами придется столкнуться при попытке навайбкодить мало-мальски production-ready приложение?

Так появилась ГдеПарковка — карта бесплатных парковок, которую наполняют сами водители. Без регистрации: открыл, нашёл место рядом, поехал. Можно добавить точку, фото, комментарий, проголосовать «место живо / места нет», уточнить вместимость и построить маршрут в Яндекс Картах, 2ГИС или Google Maps.
Но ведь платные парковки существуют не просто так!
Легко понять негодование жителей центральных районов, которые не любят шум машин под окнами, а для своей машины, как зеницу ока, оберегают бесплатные "островки". Но треть пробок в центре — это машины, которые уже приехали. Они не едут из точки А в точку Б, они кружат по кварталу в поисках места. Классические исследования городского трафика (Дональд Шуп, UCLA) оценивают долю «поискового» трафика в загруженных районах в 20–30%. Водитель, который заранее знает, где встать, проезжает по вашему району один раз, а не наматывает пять кругов мимо окон, дворов и детских площадок. Карта парковок не добавляет машин в город. Она сокращает самый бессмысленный и раздражающий их пробег.
Да и даже жители центра зачастую стеснены в перемещениях платными парковками. Тот же житель Центрального района Санкт-Петербурга, даже имея прописку, не может просто так поехать по делам в Адмиралтейский район, даже если он начинается через квартал - льготные разрешения действуют только в рамках одного района.
Хаотичная парковка — от незнания, а не от злого умысла. Машина на газоне, на тротуаре, поперёк выезда «я на минутку» - почти всегда водитель, который не нашёл нормального места и сдался. Когда в трёхстах метрах есть легальный бесплатный карман и об этом можно узнать за десять секунд, у брошенной на клумбе машины исчезает оправдание.
Это социальный сервис, а не игрушка. Платная парковка в центре Петербурга стоит до 360 рублей в час, а в Москве еще в пару раз дороже. И пускай для офисного работника с парковкой от работодателя это мелочь, то для медсестры на смене, курьера, сантехника по вызову, человека, который возит родственника в больницу через день, это тысячи рублей в месяц из семейного бюджета. Информация о бесплатных местах всегда существовала — просто раньше она была привилегией местных и «своих». Цель сервиса - устранить эту несправедливость.
«Понаедут чужие в наш двор» — двор публикует только тот, кто хочет. Ваш двор без вас на карте не появится, а если появился и мешает, то жалуйтесь, уберём.
«Из-за вас больше машин» — количество машин определяется работой и делами, а не картой. Карта сокращает круги по кварталу, а не создаёт поездки.
«Пусть платят за парковку» — платят те, кто может. Остальные и так ищут бесплатные места, только медленно и объезжая по три раза ваш квартал.
«Вы легализуете парковку где попало» — наоборот: рейтинг и комментарии топят плохие места, а дисклеймер прямо требует проверять знаки. У хаоса появился фильтр.
Техническая часть
Я не написал руками ни строчки кода. Весь проект — от схемы БД до деплоя — сделан в диалоге с Claude Code, за пару вечеров, с помощью модели Fable.
Босяцкий хак проекта: импорт из закладок Яндекс Карт
У меня была своя подборка из 68 бесплатных парковок Петербурга в закладках Яндекс Карт. Экспорта у Яндекса нет. Зато можно поделиться своей подборкой по ссылке, и публичная подборка это SSR, и в HTML лежит <script class="state-view"> с полным JSON-состоянием, включая все точки:
const state = JSON.parse(html.match(/<script[^>]*class="state-view"[^>]*>(.*?)<\/script>/s)[1]); const items = state.config.bookmarksPublicList.children; // { title: "Парковка", uri: "ymapsbm1://pin?ll=30.290309%2C59.970660", // description: "Санкт-Петербург, улица Профессора Попова, 40" }
Координаты достаются прямо из ymapsbm1://pin?ll=.... Скрипт импорта идемпотентен — точки ближе 30 метров к существующим пропускаются, так что его можно гонять повторно. Так у сервиса в день запуска появился стартовый каталог по Петербургу, а не пустая карта.
Стек
Я придерживаюсь мнения, что при кодинге с ИИ-шкой лучше использовать хорошо задокументированные и скучные технологии. Грубо говоря, используя модный и не сильно хорошо описанный фреймворк, либо сильно меняющийся между версиями, то он будет слабее отражен в весах модели, и будут возникать ошибки. Помню, как я писал экспорт скрипты для KIWI TCMS, и клод вообще не мог сконструировать валидный запрос, пока я не копипастнул ему в контекст избранные файлы из имплементации самого KIWI TCMS, только тогда он разобрался в формате апишки. Поэтому в промпте был заложен принцип: никаких фреймворков. Такое тривиальное архитектурное решение сработало вполне хорошо!
Бэкенд: Node.js + Express + SQLite. Причём не better-sqlite3, а встроенный
node:sqliteиз Node 22+ — ноль нативных зависимостей,npm installне может сломаться в принципе.Фронтенд: vanilla JS + Leaflet с тайлами OSM. Без сборки вообще — файлы из
public/отдаются как есть. Никакого вебпака, вайта, транспиляции. Деплой фронта — этоgit pull.Зависимостей в package.json — четыре: express, multer, sharp, compression. И leaflet, который отдаётся статикой из node_modules.
В сумме: один процесс, одна БД-файл, один каталог data/ со всем состоянием. Бэкап — это sqlite3.backup плюс rsync каталога фотографий, восстановление — скопировать каталог обратно.
Хостинг — VPS на RuVDS за ~300 ₽/мес: 1 vCPU, 1 ГБ RAM. Перед Node стоит Caddy, HTTPS с автопродлением сертификата из коробки. Кстати, HTTPS тут не опция: браузеры отдают navigator.geolocation только в secure context.
Простота использования и секьюрность
Секьюрности нет)))
Защита от накрутки простенькая. «Без регистрации» и «один голос на человека» — требования, противоречащие друг другу. Разрешение конфликта — анонимный clientId (UUID в localStorage) плюс второй рубеж: в таблице голосов хранится солёный хэш IP, и с одного адреса на одну точку принимается не больше пяти голосов от разных «клиентов». Запас — на CGNAT и общий Wi-Fi, сырые IP не хранятся вообще. Это не защита от целеустремлённого ботовода, это защита от накрутки «за пять минут скриптом». Для моего кейса это осознанно достаточный уровень.
Фотографии: сжимаем варварски, и это фича
Пользовательские фото парковок — это «общий план двора». Качество не нужно от слова совсем, поэтому сжатие агрессивное: JPEG quality 45 (mozjpeg), ресайз до 1024px по большей стороне. Телефонное фото на 6 МБ превращается в 50–150 КБ.
await sharp(buffer, { limitInputPixels: 30_000_000 }) .rotate() // применить EXIF-ориентацию до удаления метаданных .resize({ width: 1024, height: 1024, fit: 'inside', withoutEnlargement: true }) .jpeg({ quality: 45, mozjpeg: true }) .toFile(path);
В этих пяти строчках три неочевидных решения:
limitInputPixels— защита от pixel-flood. JPEG 50000×50000 весит меньше 15 МБ, но при декодировании разворачивается в гигабайты RAM. На VPS с гигабайтом памяти это гарантированный OOM. Лимит в 30 мегапикселей режет бомбу на этапе чтения заголовка.Пересжатие как санитайзер. Что бы ни прислали под видом картинки — полиглот-файл, картинку со скриптом в метаданных — на диск ложится честный JPEG, собранный заново.
Re-encode убивает EXIF — включая GPS-координаты автора снимка. Для краудсорсингового сервиса это не мелочь: человек фотографирует парковку у дома.
Плюс все фото проходят через последовательную очередь (sharp.concurrency(1)) — два параллельных декода больших снимков на маленьком VPS складывают процесс, проверено намеренно.
А поскольку имена файлов — UUID и не меняются никогда, отдаются они с Cache-Control: immutable, max-age=1y: повторные открытия карточек не трогают сервер вообще.
Автомодерация комментариев: 70 строк вместо npm-пакета
Хотелось автоматом резать мат и спам-дубликаты до того, как они падают в очередь модератору. Готовые пакеты для русского мата на npm оказались заброшены и наивны, ML-API — платная зависимость с латентностью на каждый комментарий. В итоге — собственный модуль на 70 строк: словарь корней + нормализация против обфускации.
Нормализация делает из «м у д @ к» и «сууукааа» канонические формы: латиница-двойники и цифры приводятся к кириллице, символы-маски выбрасываются, повторы букв схлопываются, «р а з р я д к а» склеивается обратно в слово. А анкеры в регулярках подобраны так, чтобы «курс рубля», «колебание», «обед», «веб-камера» и «не психуй» проходили спокойно. На 24 тестовых кейсах — ноль промахов в обе стороны.
Дубликаты ловятся сравнением нормализованного текста: повтор у той же точки или три одинаковых текста за сутки по всем точкам — до свидания. Отклонённое автоматикой в БД не пишется вообще: спамер не растит нам диск.
Интерфейс

Интерфейс mobile-first и бессовестно вдохновлён ГдеБЕНЗом: сверху компактная плашка-дисклеймер, дальше карта на весь экран с зелёными, красными и серыми пинами — цвет считается из баланса голосов «место живо / места нет». На телефоне между картой и списком переключаешься пилюлей сверху, на десктопе список висит слева постоянно.
Тап по пину открывает нижнюю шторку-карточку, и в ней весь функционал: описание, вместимость по категориям (от «маленькая, 1–4 места» до «огромная, 50+»), голосование с возможностью передумать, фото, комментарии и история голосов. Там же кнопка «Построить маршрут», которая пробрасывает точные координаты точки в Яндекс Карты, 2ГИС или Google Maps: на телефоне ссылку перехватывает установленное приложение и сразу строит маршрут. Добавление парковки — три действия: кнопка, тап по карте, короткая форма с опциональным фото. Регистрации нет нигде, «личность» пользователя — UUID в localStorage. Ну и PWA: сайт ставится на домашний экран и открывается как приложение, без адресной строки. Также есть админка со статистикой: посещения по дням, счётчики действий, топ точек по рейтингу и «самые спорные» — места, у которых много и ?, и ?, то есть парковки-лотереи.
Выводы
Проект от «а сделаю-ка я» до продакшена с доменом, HTTPS, PWA, SEO и стартовым каталогом занял, суммарно, пару вечеров диалога. Что показывает, что говнопалочные пет-проекты сейчас стало делать проще, чем никогда - в целом, с новыми моделями уже не особо важны технические знания, даже первая итерация по расплывчатому ТЗ более-менее работала и даже неплохо выглядела. Но имея инженерные знания, можно промптить модель так чтобы она закрывала бреши в производительности и безопасности, делать ей всякие замечания и тп. Ну и главное, работает стабильно, лучше чем мои курсовые с первого курса :)
Что еще помогло не накосячить с ИИшкой: скучный стек, коммиты на каждый шаг и живое тестирование руками на реальном устройстве.
Сервис живой: gdeparkovka.ru. По Петербургу каталог уже есть, по другим городам карта ждёт ваших точек, добавление занимает полминуты и не требует регистрации. Критику проекта жду в комментариях! Ну и пользуйтесь на здоровье, информация это общественное благо :)
Комментарии (28)

Mishootk
07.07.2026 08:49Похоже, что уже отработан стандартный промпт: "сделай приложение [где_хрень]". Карта, точки, метрика точки, список, рейтинг, достоверность, серверная часть.
Бензин, парковки, гречка, дождь...
Предлагаю на развитие идеи: большая "соцсеть гдехрень?", которая уже запрограммирована, запущен сервер, есть приложение. Любой пользователь регистрируется, может создать свой тип точек интереса или присоединиться к информированию существующих. Дальше стандартный сценарий администрируем, модерируем, монетизируем, продаем платформу заинтересованным серьезным людям, хороним когда-то хорошую идею и тратим схайпованные деньги.
boriswinner Автор
07.07.2026 08:49Не для всех типов точек это подойдет :) тот же "гдебенз" дает много функционала по типу бензина, обновлению его в наличии (все меняется динамически) и тд. У каждого типа точек своя специфика

Mishootk
07.07.2026 08:49Вы же понимаете, что если не "вайбкодить за вечер", а запрограммировать с головой и создать продукт, то в нем будут мультисвойства (на "вайбкодерном" - это тип бензина), и актуальность по множественному критерию: время, количество отзывов, расчет расхода, т.е. устаревание (на "вайбкодерном" - все менятеся динамически). И это не "специфика", а абстрактная модель с настраиваемыми параметрами.

Petroleum_man
07.07.2026 08:49С бензом история завелась, но будут ли люди делиться бесплатными местами - большой вопрос

pozhilou
07.07.2026 08:49Думаю будут, я тоже решил внести свой вклад и добавил точку, о которой знал, но она была не отмечена)

boriswinner Автор
07.07.2026 08:49для Петербурга я уже добавил свою личную коллекцию, которую год собирал) так что в масштабах Спб сервис уже полезен. А дальше зависит от сообщества - но сегодня уже начали появляться точки в Москве, Красноярске, Екатеринбурге!

Mishootk
07.07.2026 08:49С бензом история завелась на хайпе и любопытстве. Практически такой информатор сам себя губит и практической пользы нет. Заправку у дома все местные будут помечать как пустую. Немного удаленные от дома - как полную. Чтобы лично для себя уменьшить очередь и повысить вероятность заправиться. А гоняться по зеленым кружочкам будут доверчивые и не понимающие механику процесса.
Польза для клиентов от аналога "гдебенза" может быть только в приложении топливной компании по актуальным данным наличия (с остатком) и онлайн картинки с камеры на территории. Как, например, сделано на автомобильной госгранице - при существовавшей альтернативе заезда в Финляндию через 2-3 КПП я уже по дороге выбирал маршрут с учетом загрузки пунктов.
Вопрос только в том, является ли данная опция выгодной для топливной компании. Я думаю, если бы она давала хорошую прибыль, информатор о наличии уже бы появился сразу же как начались проблемы.

alcanoid
07.07.2026 08:49Если бы она давала прибыль, то появилась бы раньше. В текущих же условиях заправка практически гарантированно распродаст имеющийся бензин безо всех этих телодвижений, а кричать о избытке топлива может быть тупо небезопасно.

Bardakan
07.07.2026 08:49Цель сервиса - выровнять это неравенство.
во первых, вырАвнять, во-вторых, неравенства не выравнивают, а устраняют, исправляют и т.п.
max9
вы техническими методами пытаетесь забороть плату за воздух и воровство бесплатных парковок у людей.
тем более, что из года в год эти места будут сокращаться в перспективе до 0.
boriswinner Автор
Действуем в рамках наших возможностей :)
Mishootk
Разве это не то же самое по смыслу в ЯндексКартах?
boriswinner Автор
там нет многих локаций, и нет возможности отметить свои точки для всех. Конкретно всякие углы-дворы в центральных районах Петербурга на Яндекс картах не отмечены
Mishootk
У ЯК есть API взять их базу, и уже к ней сделать свое дополнение и добавочные свойства в вашем приложении?
boriswinner Автор
можно сдампить их бесплатные парковки, да. Но только не все бесплатные парковки имеют ценность - скорее только те, которые окружены платными в каком-то радиусе
salnicoff
Вот-вот. Успешно решена не та задача.
Ну и вдогонку еще пару соображений.
1) Я в своем городе знаю все места, где можно стоять. После того, как нам сделали подарок на Новый год и ввели платные парковки, смотрю карту платных парковок и запоминаю, что еше в одном месте нельзя стоять.
2) Знакомые не раз уже вертли всяким навигаторам и вставали, а им прилетал штраф, и было это еще до эпидемии платных парковок. Ваша система абсолютно не защищена от ложной информации, кто-то наверняка будет ставить точки парковки на местах парковки платной. Мало того, есть даже люди, которые заинтересованы в таких подставах.
Petroleum_man
Штраф за что прилетал? Платная парковка всегда либо знаком, либо разметкой отмечена. Нет знака, нет разметки - значит бесплатная. То же самое - про то, а можно ли там вообще парковаться (ПДД, знаки, разметка)
salnicoff
Штраф прилетал за ротозейство. На улице в самом начале повесили знак «Остановка запрещена», в навигаторе этого не было. Водитель знак проигнорировал, встал, поймали.
alcanoid
Ну глаза-то у водителя есть бай дизайн, так сказать. Приехал, увидел, что бесплатной парковки нет, поехал дальше. Может, ещё и в приложение написал, что точка недействительна. Хуже никому не стало.
salnicoff
Глаза-то есть, только не все водители умеют ими пользоваться. Равно как руками и ногами.
Это сценарий для адекватного водителя. А если там между рулем и сиденьем прокладка?
alcanoid
Это уже слегка выходит за рамки проблем, решаемых приложением. Прокладка и так будет ездить, страдать, а потом припаркуется под знаком.
salnicoff
Потом — штраф прокладке, а затем прокладка выкатит претензии автору.
alcanoid
Ну какие там претензии? Кол поставит в маркете приложений?
salnicoff
Почитайте тут: https://habr.com/ru/articles/1049576/ Человек сделал приложение с расписанием, а на него накатали бумаги, что он в свою деревню не дает автобусов — все же думают, что он злобный перевозчик. И это в деревне посреди Сибири. А тут — центр СПб...
alcanoid
Ну не накатали на него бумаги, это ваше личное допущение из комментариев к статье.
salnicoff
Ну он уже в одном шаге от этого. С учетом населения СПб этот шаг будет сделан довольно быстро.
alcanoid
У меня из этого разговора складывается впечатление, что вы уже в шаге от того, чтобы сделать это самостоятельно, лишь бы обосновать данную точку зрения.