Skip to content

feat(etl): разширяване на allowlist-а за публична собственост с 300 проверени фирми - #246

Merged
todorkolev merged 3 commits into
mainfrom
feat/seed-state-owned-expand
Jul 23, 2026
Merged

feat(etl): разширяване на allowlist-а за публична собственост с 300 проверени фирми#246
todorkolev merged 3 commits into
mainfrom
feat/seed-state-owned-expand

Conversation

@todorkolev

Copy link
Copy Markdown
Collaborator

Какво

Разширява курирания allowlist за публична собственост scripts/seed-state-owned.sql от 100 на 400 фирми (state 240, municipal 111, mixed 49 — от които 300 нови реда). Той badge-ва ЕИК-та на печеливши фирми като държавни/общински/смесени, за да не разчита UI на евристики по вида на възложителя.

Как е съставен

Изследователско претърсване в четири фази: (1) кандидати от собствения ни корпус (17.5k изпълнителя — топ по спечелена стойност + шаблони по име: УМБАЛ/МБАЛ/ДКЦ, ВиК, ДП, горски предприятия, общински транспорт…); (2) седем регистрови направления (АППК регистър на публичните предприятия, БЕХ енергийна група, транспорт/пристанища/летища, държавни и общински болници, горски/земеделски ДП, общински дружества на големите градове); (3) верификация на всеки кандидат поотделно срещу източник с текуща мажоритарна собственост, fail-closed при несигурност; (4) валидация на контролния код по Булстат.

  • Всеки от 300-те нови реда е с валиден Булстат контролен код и потвърдена собственост срещу източник.
  • 276 кандидата отхвърлени — включително приватизационните капани: Петрол, УниКредит Булбанк, А1, ЧЕЗ/Енерго-Про, Софарма Трейдинг, ДЖИ ПИ Груп, Хидрострой, Инфра Експерт, Европейски пътища.
  • Само 49 от новите реално печелят договори в текущия корпус; другите 251 са изпреварващо заредени от регистрите и ще влязат в сила при бъдеща победа.

За решение от ревюто (умишлено оставени видими)

  • Чисти институции, не търговски дружества, badge-нати като state: НАП (печели 1 договор), Лесотехнически университет, НАИМ-БАН, НИГГГ-БАН, Национална служба за съвети в земеделието, НЦПКПС. Политика на проекта: badge-ваме ли всеки публичен собственик или само дружества? Ако второто — да се махнат.
  • Една фирма под две ЕИК-та (и двете с реална история — оставени): БУЛ БИО-НЦЗПБ (ЕАД 207939249 + ЕООД 130428132), ТСВ (ЕАД 205677435 печели 89 млн. + стара ДП форма 130847116), Летище Пловдив (115007069 + 825320507, без победи).
  • В ликвидация (оставени заради историята): Паркстрой (827183548), Обредни дейности (123515601) — без победи в корпуса.
  • Мажоритарно частни / концесия — да се следи рамката: Слънчев бряг АД (75% държава/25% частник), Летище Горна Оряховица (държавно, но управлявано от частен концесионер).
  • Изключено при съставянето: Тролейбусен транспорт-Пазарджик АД (мажоритарно частен, печелеше 1.0 млн.) — не влиза в allowlist за публична собственост.

Бележки

…ties

Adds 300 checksum-valid ЕИК to scripts/seed-state-owned.sql (state 194, municipal 69, mixed 37) from a research sweep over the АППК public-enterprise register, the БЕХ energy group, state forestry enterprises, state/municipal hospitals and ДКЦ, ports/airports, and the municipal companies of the largest cities. Every entity's current majority ownership was verified against a source; majority-private and privatized companies (Петрол, УниКредит Булбанк, А1, ЧЕЗ/Енерго-Про, Софарма Трейдинг, ДЖИ ПИ Груп, Хидрострой, ...) were deliberately excluded.

Also drops the pre-existing checksum-invalid Топлофикация София dup (831609043); identical one-line removal as #203, no conflict.

@ydimitrof ydimitrof left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Преглед на PR: разширяване на allowlist-а за публична собственост (+300 фирми)

ВЕРДИКТ: COMMENT — не блокиращо; препоръчвам изясняване на 2 точки преди merge. Не съм публикувал коментари автоматично — това е чернова за Вашия преглед.


Phase 0 — Сигурност (задължителен сканинг): ЧИСТО ✅

  • Файлът е статичен seed (само INSERT ... VALUES) без потребителски вход → няма повърхност за SQL injection.
  • Няма хардкоднати тайни (API ключове/пароли/токени), няма URL-и, няма мрежови/exec повиквания.
  • Няма промени в зависимости, няма обфускация, backdoor или инжектиран код сред редовете.
  • Проверих за неекраниран апостроф в имена (би счупил стринг литерал) — няма такъв. OWASP: не е приложима динамична конкатенация.

Проверка на целостта на данните (изпълнена локално): ОТЛИЧНА ✅

Валидирах и 300-те нови реда със скрипт:

  • 300/300 са 9-цифрени ЕИК; 300/300 минават контролната сума по Булстат — потвърждава твърдението в коментара „проверен контролен код“.
  • Няма дублирани ЕИК в новото множество.
  • Премахнатият ред 831609043 („Топлофикация София“) е бил с невалидна контролна сума и дубликат на валидния 831609046 — коректно почистване.
  • Разпределение: state=194, mixed=36, municipal=70.

Открития за изясняване (не блокиращи)

1. Нова стойност ownership_kind = 'mixed' (36 реда) — ПОТВЪРДЕТЕ схемата. До момента данните ползваха само state/municipal. Ако колоната има CHECK/enum ограничение или ETL логика надолу по веригата разчита на затворено множество стойности, тези 36 реда ще счупят seed-а или ще бъдат игнорирани при обработка. Моля потвърдете, че 'mixed' е позволена и обработена стойност.

2. Кръстосани дубликати спрямо съществуващите редове. Диффът показва само добавеното; не мога да проверя срещу вече наличните ~120 реда. Ако има UNIQUE(eik), случаен сблъсък ще прекъсне seed-а. Моля пуснете seed-а срещу чиста БД, за да го потвърдите.

Забележки за качество на данните (леки)

  • Логически дубликат: „Летище Пловдив ЕАД“ е с два различни ЕИК (115007069 и 825320507) — вероятно стар/нов Булстат. Безвредно за allowlist, но си струва да се остави само единият.
  • „БУЛ БИО - НЦЗПБ“ присъства и като ЕАД (207939249), и като ЕООД (130428132) — един субект, две правни форми.
  • Анотации в canonical_name: (Варна), (фондация), (в ликвидация) — canonical_name е добре да е чистото регистрирано име; метаданните е по-добре в отделна колона. Субектите „в ликвидация“ — умишлено ли остават в allowlist-а?
  • Обхват/семантика: включени са и бюджетни институции, не търговски държавни дружества — напр. 131063188 НАП, „Лесотехнически университет“, „Държавен авиационен оператор“, институти на БАН. Ако allowlist-ът е само за публична собственост изобщо — ОК; ако е за държавни предприятия, това е разширяване на обхвата.

Съответствие с CLAUDE.md

Няма частична имплементация, TODO, мъртъв код или дублиране на код. Това е чисто данни; за seed от този тип автоматизиран тест, който проверява контролните суми/уникалността при зареждане, би бил добър, но не е блокер.


ENGLISH (mirror)

VERDICT: COMMENT — non-blocking; clarify 2 items before merge. Comments not auto-posted; this is a draft for your review.

Phase 0 security scan: CLEAN. Static seed (INSERT ... VALUES), no user input → no SQL-injection surface; no secrets, URLs, dependency/obfuscation/backdoor; no unescaped apostrophes in names.

Data-integrity check (run locally): EXCELLENT. All 300 EIKs are 9-digit and all pass the Bulstat checksum; no duplicate EIKs in the added set; the removed 831609043 was an invalid-checksum duplicate of 831609046 — correct cleanup.

Items to clarify (non-blocking):

  1. New ownership_kind = 'mixed' (36 rows) — confirm the column's CHECK/enum and downstream ETL accept it, or the seed/processing may break.
  2. Cross-duplicates vs. the ~120 pre-existing rows can't be checked from the diff; run against a clean DB if eik is UNIQUE.

Data-quality notes: „Летище Пловдив ЕАД“ has two EIKs (115007069/825320507); „БУЛ БИО - НЦЗПБ“ appears as both ЕАД/ЕООД; parenthetical annotations in canonical_name ((в ликвидация) etc.); several budgetary institutions (НАП 131063188, universities, BAS institutes) included — scope question if the list targets commercial state enterprises only.

Comment thread scripts/seed-state-owned.sql
Comment thread scripts/seed-state-owned.sql
Comment thread scripts/seed-state-owned.sql
Comment thread scripts/seed-state-owned.sql

@lyubomir-bozhinov lyubomir-bozhinov left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Прегледах на връх ef53977. Данни-само PR (400 реда: 240 state / 110 municipal / 50 mixed; ~300 нови).

Спот-проверка — класификациите държат през трите вида: state (Информационно обслужване АД, Български пощи ЕАД, Монетен двор ЕАД, Мини Марица-изток ЕАД), municipal (Топлофикация София ЕАД, Софинвест/Софекострой), mixed (ВиК-дружествата — държавно+общинско съвместно, коректно „mixed"). Методологията (4-фазно претърсване) е разумна.

Не мога да проверя всичките 400 в ревю — а грешна класификация тук не е козметична: badge-ва печеливша фирма като публична и мени как се чете рискът ѝ. Затова две неща:

  • Provenance (препоръка): редовете са (eik, kind, name) без източник на ред. За класификация публично/частно, която гейтва рисковата презентация, неодитируем ред е слабост („provenance е moat-ът"). Добави коментар-източник на ред (ТР/партида/ПМС) или поне на блок — за да е проследимо и преразглеждаемо. Форматът съвпада със стария файл, тъй че не е блокер, но при 400 реда залогът расте.
  • Периодична пре-верификация (фирми се приватизират/ликвидират — вече виждам „в ликвидация" в списъка).

Одобрявам; provenance-ът е follow-up, не блокер.

@midt-admin midt-admin left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Одобрено (batch merge към staging).

@midt-admin midt-admin left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Одобрено - нишките резолвнати (вкл. решението за state обхвата), CI зелен.

@todorkolev
todorkolev merged commit ee5e1a2 into main Jul 23, 2026
1 check passed
todorkolev added a commit to lyubomir-bozhinov/sigma that referenced this pull request Jul 23, 2026
todorkolev added a commit to DanielStoychev/sigma that referenced this pull request Jul 23, 2026
todorkolev added a commit that referenced this pull request Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants