[ Automatyzacje ]

Panel profili firm — dziesięć źródeł w jednym miejscu

Panel do aplikacji desktopowej: zbiera nowe informacje z dziesięciu źródeł, scala je po numerach rejestrowych i składa w profile firm z pochodzeniem pól.

Live · 2026 · TypeScript · Electron · SQLite · Node.js · Playwright · REST API

Potok

  1. 1

    zrodla-adaptery

  2. 2

    tozsamosc-firm

  3. 3

    rozstrzyganie

  4. 4

    redakcja

4 etapy · 2026

O projekcie

Osobny panel wewnątrz aplikacji desktopowej, który zbiera świeże informacje z dziesięciu źródeł, sprowadza je do jednego miejsca i składa w PROFILE FIRM — uporządkowane, przeredagowane i podpisane tym, skąd każda pojedyncza informacja pochodzi.

Zacznę od zdania, które przewraca zwykłe wyobrażenie o takim narzędziu: TO NIE JEST PROJEKT O POBIERANIU, TO PROJEKT O TOŻSAMOŚCI. Pobranie dziesięciu stron jest najłatwiejszą częścią i zajmuje dzień. Cała trudność zaczyna się sekundę później, bo te same dziesięć źródeł nazywa jedną firmę dziesięcioma sposobami: raz z formą prawną, raz bez, raz wielkimi literami, raz ze skrótem, raz z literówką z cudzego formularza. Scalanie po nazwie daje śmieci — i to śmieci wyglądające na porządek.

Dlatego scalanie idzie WYŁĄCZNIE po identyfikatorach rejestrowych: numerze NIP, numerze REGON i numerze KRS. Dopiero gdy rekord da się przypiąć do identyfikatora, wchodzi do profilu; bez identyfikatora ląduje w poczekalni do rozstrzygnięcia przez człowieka, a nie w profilu „najbardziej podobnej” firmy. Powód jest asymetryczny i warto go nazwać: DWA DUPLIKATY SĄ KŁOPOTEM, ALE BŁĘDNIE SCALONY PROFIL JEST FAŁSZEM. Pierwszy da się połączyć, drugi wymyśla firmę, która nie istnieje, i nikt się nie dowie, dopóki ktoś nie zadzwoni pod zły numer.

Numer NIP ma sumę kontrolną, a REGON występuje w wersji dziewięcio- i czternastocyfrowej. Sprawdzenie sumy kontrolnej przed zapisem kosztuje mikrosekundę i zatrzymuje literówkę, zanim zdąży urosnąć w osobny, widmowy rekord. To jedna z tych kontroli, których prawie nikt nie robi, a która zdejmuje całą klasę problemów: identyfikator, który nie przechodzi sumy kontrolnej, NIE JEST identyfikatorem, choć wygląda jak on.

Drugą rzeczą, która odróżnia profil od zlepka, jest POCHODZENIE ZAPISANE PRZY KAŻDYM POLU, a nie przy rekordzie. Pierwsze pytanie, jakie zadaje każdy użytkownik takiego panelu, brzmi: skąd wiadomo, że ta firma ma czterdziestu pracowników. Odpowiedź „z agregatu dziesięciu źródeł” jest bezwartościowa. Dlatego każde pole niesie źródło, moment pobrania i SUROWĄ WARTOŚĆ w brzmieniu, w jakim ją podało źródło — żeby dało się sprawdzić nie tylko wynik, ale i drogę do niego.

Z tego wynika trzecia rzecz: SPRZECZNOŚĆ ŹRÓDEŁ JEST NORMĄ, NIE AWARIĄ. Jedno źródło mówi czterdziestu pracowników, drugie sto dwudziestu, bo liczą w innym momencie i w innej definicji. System, który po cichu wybiera jedną liczbę i pokazuje ją jako fakt, kłamie przez zamilczenie. Tutaj obowiązuje zadeklarowana kolejność pierwszeństwa — osobna dla każdego rodzaju pola, bo do adresu najlepszy jest rejestr, a do oferty strona własna firmy — a rozjazd przekraczający próg jest OZNACZONY I WIDOCZNY, zamiast wygładzony.

Słowo „najnowsze” też wymaga definicji, bo w tej dziedzinie jest zdradliwe. Data na stronie bywa nieobecna, bywa nieprawdziwa, a najczęściej jest datą ostatniej zmiany szablonu, nie treści. Świeżość liczy się więc z tego, co obserwowalne: ze ZMIANY WYDOBYTYCH PÓL, a nie z deklarowanej daty ani z odcisku surowego HTML-a. To rozróżnienie jest praktyczne — przemalowanie strony przez źródło zmienia cały HTML i zgłosiłoby „wszystko nowe”, zalewając panel fałszywymi zmianami.

Dziesięć źródeł znaczy DZIESIĘĆ RZECZY, KTÓRE PSUJĄ SIĘ OSOBNO, i to jest najtrudniejsza część utrzymania. Każdy adapter ma dlatego kanarka: znany rekord o znanej z góry wartości, sprawdzany przy KAŻDYM przebiegu. Kiedy kanarek milczy, adapter jest zepsuty — i wtedy właściwym zachowaniem jest WSTRZYMANIE zasilania z tego źródła, a nie zapisanie pustych pól. To jest najczęstsza droga, którą takie systemy niszczą własną bazę: zepsuty adapter zwraca zero rekordów, logika nadpisuje dobre dane pustką, a przebieg kończy się sukcesem.

Redakcja, o którą chodzi w tym projekcie, ma ostrą granicę: WOLNO PRZEREDAGOWAĆ, NIE WOLNO DOPISAĆ. Surowy tekst ze strony nie jest profilem — bywa marketingową sieczką, bywa powtórzeniem tego samego w czterech miejscach. Warstwie redakcyjnej wolno więc skrócić, uporządkować, usunąć powtórzenia i ułożyć w stałe sekcje. Nie wolno jej dołożyć ANI JEDNEGO faktu, którego nie ma w źródle, a przy każdym zredagowanym akapicie zostaje odnośnik do surowego tekstu, z którego powstał.

Granica prawna jest tu częścią projektu, nie załącznikiem. Zbieranie publicznych danych o firmach jest dozwolone, ale nie w dowolny sposób: reguły w pliku robots i regulaminy źródeł są respektowane, zabezpieczeń dostępu się nie obchodzi, a tempo zapytań jest uprzejme wobec cudzego serwera. Rzecz, którą najczęściej się przegapia: DANE JEDNOOSOBOWEJ DZIAŁALNOŚCI TO DANE OSOBOWE. Pola, które ich dotyczą, są oznaczone jako takie, mają zapisaną podstawę i mają drogę do sprostowania oraz usunięcia — a nie „usuniemy, jeśli ktoś napisze”.

Panel jest LOKALNY, bo mieszka w aplikacji desktopowej i musi działać, gdy sieci nie ma. Pracuje na ostatniej synchronizacji, synchronizuje się przyrostowo i wznawia po przerwaniu, a nie zaczyna od zera. Najważniejsza reguła jest jednak inna i dotyczy ludzkiej pracy: DECYZJE REDAKCYJNE PRZEŻYWAJĄ SYNCHRONIZACJĘ. Gdyby przychodzące dane nadpisywały to, co redaktor poprawił, każde odświeżenie kasowałoby jego robotę — a narzędzie, które zjada własną pracę użytkownika, przestaje być używane w tydzień.

Na koniec rzecz, która wygląda na drobiazg, a rozstrzyga o zaufaniu: ŚWIEŻOŚĆ JEST CECHĄ POLA, NIE PROFILU. Adres może mieć dwa lata, a przychód dwa dni. Jedna data „zaktualizowano” na całym profilu jest przez to myląca w najgorszym możliwym momencie — kiedy ktoś na tej podstawie dzwoni. Każde pole ma więc własny wiek, a pole po przekroczeniu sufitu nieświeżości jest POKAZANE JAKO NIEAKTUALNE, zamiast udawać bieżące.

Problem

Informacje o firmach leżą w dziesięciu miejscach, w dziesięciu formatach i z dziesięcioma wariantami tej samej nazwy. Ręczne zbieranie ich do jednego profilu zajmuje godziny na firmę, a scalanie po nazwie produkuje albo duplikaty, albo — gorzej — profile scalone błędnie, których nikt nie wychwyci, bo wyglądają porządnie.

Rozwiązanie

Scalanie wyłącznie po identyfikatorach rejestrowych ze sprawdzoną sumą kontrolną, pochodzenie zapisane przy każdym polu, zadeklarowana kolejność pierwszeństwa i widoczny znacznik przy sprzeczności źródeł. Każdy adapter ma kanarka, a jego milczenie wstrzymuje zasilanie zamiast nadpisywać dobre dane pustką.

Funkcje

  • scalanie po numerach NIP, REGON i KRS — nigdy po nazwie firmy
  • suma kontrolna identyfikatora sprawdzana przed zapisem, nie po
  • rekord bez identyfikatora idzie do poczekalni, nie do najbardziej podobnego profilu
  • pochodzenie przy KAŻDYM polu: źródło, moment i surowa wartość ze źródła
  • zadeklarowana kolejność pierwszeństwa, osobna dla każdego rodzaju pola
  • rozjazd źródeł ponad próg oznaczony i widoczny, a nie wygładzony
  • kanarek w każdym adapterze; jego milczenie wstrzymuje zasilanie ze źródła
  • redakcji wolno skrócić i uporządkować, nie wolno dopisać faktu
  • wiek liczony per pole; pole po suficie nieświeżości pokazane jako nieaktualne

Moduły

  • zrodla-adaptery

    warstwa pobierania

    Dziesięć adapterów, każdy z własnym kontraktem, tempem i kanarkiem.

    • jeden adapter to jedno źródło i jeden kontrakt — brak wspólnego kodu do współdzielenia awarii
    • kanarek: znany rekord o znanej wartości sprawdzany przy każdym przebiegu
    • milczenie kanarka WSTRZYMUJE zasilanie; zero rekordów nie nadpisuje dobrych danych
    • tempo zapytań i reguły z pliku robots respektowane osobno dla każdego źródła
    • odpowiedź źródła zachowana w całości, żeby dało się odtworzyć, skąd wzięło się pole
  • tozsamosc-firm

    rozpoznawanie podmiotu

    Przypina rekord do firmy po identyfikatorze rejestrowym albo odmawia przypięcia.

    • klucze: numer NIP, REGON i KRS; nazwa firmy NIGDY nie jest kluczem
    • suma kontrolna numeru NIP i obie długości numeru REGON sprawdzane przed zapisem
    • rekord bez identyfikatora trafia do poczekalni z podpowiedziami dla człowieka
    • scalenie dwóch profilów jest operacją odwracalną i zapisaną w historii
    • nazwy i skróty trzymane jako ALIASY przy profilu, do wyszukiwania, nie do scalania
  • pola-pochodzenie

    magazyn z metryką

    Trzyma każde pole razem z jego źródłem, momentem i surową wartością.

    • pochodzenie przy polu, nie przy rekordzie — pytanie zawsze dotyczy jednej liczby
    • surowa wartość w brzmieniu źródła obok wartości znormalizowanej
    • historia pola jest dopisywana; poprzednia wartość nie znika przy aktualizacji
    • wiek pola liczony osobno i wystawiony do interfejsu
    • pole po przekroczeniu sufitu nieświeżości oznaczone, nie ukryte i nie odświeżone na siłę
  • rozstrzyganie

    warstwa uzgadniania

    Wybiera wartość widoczną w profilu i pokazuje, gdy źródła się nie zgadzają.

    • kolejność pierwszeństwa ZADEKLAROWANA i osobna per rodzaj pola, nie ustalana doraźnie
    • do adresu i formy prawnej pierwszeństwo ma rejestr, do oferty — strona własna firmy
    • rozjazd ponad próg zapala znacznik przy polu razem z listą wartości i źródeł
    • ręczna decyzja człowieka bije kolejność i jest zapisana jako decyzja, nie jako dane
    • brak wartości we wszystkich źródłach zostaje brakiem; pole nie dostaje wartości domyślnej
  • swiezosc

    wykrywanie zmian

    Rozstrzyga, co jest naprawdę nowe, nie opierając się na dacie ze strony.

    • porównanie na WYDOBYTYCH POLACH, nie na odcisku surowego HTML-a
    • data podana przez źródło traktowana jako poszlaka, nie jako fakt
    • przemalowanie strony przez źródło nie zgłasza się jako zmiana wszystkich danych
    • zmiana pola tworzy zdarzenie z wartością przed i po, gotowe do przeglądu
    • próg istotności: literówka i zmiana wielkości liter nie budzą panelu
  • redakcja

    warstwa redakcyjna

    Zamienia surowy tekst w profil czytelny dla człowieka, bez dokładania treści.

    • wolno skrócić, uporządkować, usunąć powtórzenia i ułożyć w stałe sekcje
    • NIE WOLNO dopisać faktu, którego nie ma w źródle — to jest granica, nie wytyczna
    • każdy zredagowany akapit ma odnośnik do surowego tekstu, z którego powstał
    • profil ma stałą strukturę sekcji, więc dwie firmy da się czytać tym samym ruchem
    • wersje redakcji zapisane; da się wrócić do poprzedniego brzmienia
  • panel-lokalny

    interfejs desktopowy

    Panel w aplikacji desktopowej: działa bez sieci i nie zjada pracy redaktora.

    • pracuje na ostatniej synchronizacji; brak sieci nie blokuje przeglądania
    • synchronizacja przyrostowa i wznawialna, ze stanem po każdej porcji
    • DECYZJE REDAKCYJNE PRZEŻYWAJĄ SYNCHRONIZACJĘ — przychodzące dane ich nie nadpisują
    • kolizja lokalnej poprawki z nową wartością ze źródła pokazana do rozstrzygnięcia
    • baza lokalna w SQLite, więc panel startuje natychmiast i nie czeka na serwer
  • granice-prawne

    warstwa zgodności

    Pilnuje, żeby zbieranie i trzymanie tych danych było zgodne z prawem.

    • reguły z pliku robots i regulaminy źródeł respektowane; zabezpieczeń dostępu się nie obchodzi
    • dane jednoosobowej działalności oznaczone jako DANE OSOBOWE, z zapisaną podstawą
    • droga do sprostowania i usunięcia opisana i wykonalna, nie obiecana
    • retencja osobna dla pól firmowych i dla pól osobowych
    • eksport profilu niesie informację o źródłach, więc dalsze użycie nie gubi pochodzenia

Architektura

Podstawa
panel w aplikacji desktopowej (Electron, TypeScript) z lokalną bazą SQLite; pracuje na ostatniej synchronizacji, gdy sieci nie ma
Źródła
dziesięć adapterów z osobnym kontraktem i osobnym tempem; awaria jednego nie zatrzymuje pozostałych dziewięciu
Kanarek
znany rekord o znanej wartości sprawdzany przy każdym przebiegu; milczenie wstrzymuje zasilanie ze źródła
Zasada nadpisywania
zero rekordów NIGDY nie nadpisuje danych istniejących — to najczęstsza droga, którą takie systemy niszczą własną bazę
Tożsamość
scalanie po numerach NIP, REGON i KRS ze sprawdzoną sumą kontrolną; nazwa firmy służy do szukania, nie do scalania
Rekord bez identyfikatora
poczekalnia z podpowiedziami dla człowieka; nigdy automatyczne przypięcie do najbardziej podobnego profilu
Pochodzenie
przy KAŻDYM polu: źródło, moment pobrania, surowa wartość w brzmieniu źródła i wartość znormalizowana
Sprzeczności
zadeklarowana kolejność pierwszeństwa per rodzaj pola; rozjazd ponad próg oznaczony przy polu wraz z listą źródeł
Świeżość
porównanie na wydobytych polach, nie na odcisku HTML-a; wiek liczony per pole, z sufitem nieświeżości
Granica redakcji
skracanie i porządkowanie wolno, dopisywanie faktów nie; każdy akapit ma odnośnik do surowego tekstu
Praca człowieka
decyzje redakcyjne i ręczne rozstrzygnięcia przeżywają synchronizację i są zapisane jako decyzje, nie jako dane
Dane osobowe
pola jednoosobowej działalności oznaczone, z podstawą i osobną retencją; droga do sprostowania i usunięcia wykonalna
Uprzejmość wobec źródeł
reguły z pliku robots i regulaminy respektowane, tempo zapytań ograniczone, zabezpieczenia dostępu nietykane

Technologie

  • TypeScript
  • Electron
  • SQLite
  • Node.js
  • Playwright
  • REST API

Autor

  • Zdjęcie: Mariusz PerzyńskiMariusz PerzyńskiClient Relations & Operations

[ Kontakt ]

Chcesz podobne rozwiązanie w swojej firmie?

Opowiedz nam o swoim pomyśle — wrócimy z konkretną propozycją i wyceną.

Automatic AI

hello@automaticai.pl · automaticai.pl