Градът, който го нямаше

Заявих от API-то втория по големина запис и получих нула резултата. Не грешка — просто нищо. Това, което открих, когато започнах да ровя, промени цялата архитектура.

Построих нещо, което дърпа данни от източник, изчиства ги, показва ги по-добре от оригинала. Стандартна работа.

После заявих от системата втория по големина запис. Всичко друго връщаше стотици резултати. Този: нула. Не счупен. Просто празен.

Предположих, че аз съм объркал нещо. Проверих кода си три пъти. Тествах endpoint-а директно. Записът съществува в интерфейса им. Просто е... кух.

Тогава започнах да ровя.


Източникът изглеждаше изчерпателен. Широк обхват, полиран интерфейс, чист API. Но доброволното участие означава дупки, които не можеш да видиш от документацията.

Три конкурента имаха данни за същите обекти. Пълни записи. Значи информацията съществува някъде.

Не липсваше endpoint. На endpoint-а му липсваше реалност.


Зададох въпрос, който никой не се беше сетил да зададе: къде са живели тези данни преди интернет?

Отговорът: печатни периодични издания. Архиви. Аналогови формати, които вървят от 1800-те. Публикувани три пъти седмично. Без структурирани данни, само документи на сайт.

Затова свалям един. Плътна институционална проза, обявления, заровени из поделения. Данните са там.

Конкурентите ми го правят ръчно от трийсет години.

Пиша scraper за един следобед. Отчасти любопитство, отчасти напук.


Парсването на документи е мястото, където нещата стават истински болезнени.

Една-единствена дума се цепи от soft hyphen — Unicode U+00AD, невидим за окото, фатален за всеки regex. Взираш се в екрана и мислиш, че шаблонът ти е грешен. Не е. В текста се крие призрачен символ. JavaScript-овото \w не съвпада с non-ASCII символи, така че обикновени думи стават невъзможни за намиране. Числата съдържат фантомни интервали от renderer-а: "20. 000" вместо "20.000."

Всеки бъг отнема повече време да се намери, отколкото да се поправи. Това винаги е съотношението при извличането на текст — 90% детективска работа, 10% код.


Десет записа се материализират от шума. Дати, идентификатори, локации — всичко там, където трябва да бъде. Пускам го два пъти, за да съм сигурен, че не халюцинирам. Същият резултат. Наистина работи.


Парсването ти показва какво има. Започвам да търся какво няма. ID-тата са последователни. Изброявам ги.

53% са мъртви. Системата изтрива приключените записи — без архив, без история. Някои записи съществуват, но имат нула подкрепящи документи. Отговорът: посетете ни на място. През 2026.

Източникът не е база данни. Той е прозорец — и някой постоянно го затваря.


Първият източник на данни оформи архитектурата. Вторият счупи всяко предположение.

Трябваше ми втора архитектура. Което е учтив начин да кажа, че първата всъщност не беше архитектура — само работещо решение, което случайно пасваше на един случай. Странният източник показва истината: строил си за данните, които си имал, не за данните, които ще срещнеш.

Този път изграждам истинска. Registry pattern, споделени интерфейси, базови contracts, които позволяват на всяка имплементация да остане вярна на себе си.

Архитектурата е по-добра, защото изчаках. Ако я бях построил в първия ден, щях да проектирам за единствения източник, който познавах. Вторият — странният — ме принуди да намеря кое всъщност има значение.

Не можеш да проектираш за неизвестното. Но можеш да рефакторираш, когато то пристигне.


Архитектурата ме научи как да строя. Пазарът ме научи за какво да строя.

Влизам на пазар с утвърден играч, който работи от трийсет години. Технологията им изглежда като 2005. Ровът им не е технология — той е доверие, разпознаваемост на марката, десетилетия натрупани данни.

Модерният конкурент стартира преди три години с AI и лъскав UI. Подби цената на стария играч. Три години по-късно старият играч още доминира. Оказва се, по-евтино не значи автоматично по-добре позиционирано.

Закотвянето има значение: първата цена става отправната точка. Лесно е да свалиш по-късно, почти невъзможно да вдигнеш. Абонаментът не е продуктът — той е вратата към това, което стои зад него.

Поставям висока цена. Винаги мога да сляза надолу.


Четири урока, сгъстени:

  1. Авторитетен не значи пълен. Първичният източник пропускаше цял сегмент. Данните съществуваха — просто не там, където някой очакваше.
  2. Вторият източник разкрива архитектурата ти. Научаваш истината за дизайна си само когато нещо откаже формата, която си построил.
  3. Данните не са постоянни. Ако ти трябват, запази ги. Източникът няма.
  4. Ценообразувай за това, в което се превръщаш, не за това, което си. Абонаментът е врата. Построй това, което стои зад нея.

Интересната работа живее в пролуките. Там живея и аз.


Коментари

Boris D. Teoharov

Автор

Здравей, аз съм Борис

Не съм писател. Не съм философ. Просто съм backend инженер от България, който живее между Laravel опашки и индекси със стотици милиони редове. През останалото време чета медицина, която няма работа да чета, френски романи, които разбирам наполовина, и каквото още малката ми гумена глава реши да дъвче. Две спасени кучета ме държат честен.