Poradnik dla programistów

Walidacja danych kontrahenta przed zapisem w bazie

6 października 2026, Filip Benklewski

Dlaczego walidacja przed zapisem ma znaczenie

W małych firmach dane kontrahentów trafiają do systemów z wielu źródeł: formularzy, importów CSV, plików Excel, maili, CRM-ów i ręcznych wpisów. Jeśli zapisujemy je bez sprawdzenia, szybko pojawiają się te same problemy: literówki w nazwach, niepoprawne numery identyfikacyjne, brak spójności adresów, błędne formaty kont bankowych i duplikaty tych samych firm zapisane kilka razy.

Walidacja przed zapisem nie jest tylko „ładnym dodatkiem” do aplikacji. To podstawowy element porządku w danych. Im wcześniej wyłapiemy błąd, tym mniej kosztuje jego naprawa. Najlepiej robić to już na etapie wejścia danych do systemu, a nie dopiero podczas raportowania, wysyłki dokumentów czy integracji z zewnętrznym API.

W praktyce chodzi o dwa poziomy kontroli:

  • Walidacja składniowa – czy wartość ma poprawny format, np. długość, dozwolone znaki, zgodność z maską.
  • Walidacja logiczna – czy dana wartość ma sens biznesowy, np. czy NIP przechodzi algorytm kontrolny, a IBAN ma właściwy układ.

Jakie pola warto sprawdzać od razu

Dla danych kontrahenta najczęściej opłaca się walidować przynajmniej:

  • NIP – poprawna długość, cyfry i suma kontrolna.
  • REGON – poprawny format i suma kontrolna.
  • IBAN – struktura numeru rachunku zgodna z krajem i suma kontrolna.
  • Nazwę firmy – obecność znaku, brak samych spacji, sensowna długość.
  • Adres – podstawowe reguły, np. brak pustych wartości w kluczowych polach.
  • E-mail i telefon – poprawny format, jeśli są wymagane do kontaktu.
  • Identyfikator zewnętrzny – brak duplikatów w obrębie jednego systemu.

Nie każdą regułę da się sprawdzić lokalnie. Na przykład zgodność kontrahenta z VAT UE, białą listą czy danymi urzędowymi zwykle wymaga już osobnego zapytania do API. Mimo to podstawowa walidacja lokalna nadal jest konieczna, bo odsieje większość błędów wynikających z literówek i złego formatu.

Walidacja w warstwie aplikacji i w bazie danych

Najbezpieczniej jest rozdzielić odpowiedzialność. Część reguł sprawdza aplikacja, a część baza danych.

Aplikacja jest dobrym miejscem na:

  • komunikaty przyjazne dla użytkownika,
  • szybkie odrzucenie błędnych danych,
  • standaryzację zapisu, np. usuwanie spacji z NIP-u,
  • wykrywanie duplikatów jeszcze przed zapisem.

Baza danych powinna pilnować:

  • NOT NULL dla pól wymaganych,
  • UNIQUE dla identyfikatorów, które nie mogą się powtarzać,
  • ograniczeń CHECK, gdy reguła da się wyrazić prostym warunkiem,
  • spójności typów danych, np. liczby, daty, długości tekstu.

Takie podejście chroni przed sytuacją, w której ktoś ominie frontend albo importuje dane inną ścieżką niż standardowy formularz.

Przykład: prosty test NIP i REGON w Pythonie

Poniższy przykład pokazuje, jak można sprawdzić podstawowy format i sumę kontrolną dla NIP-u oraz REGON-u. To nie zastępuje pełnej walidacji biznesowej, ale dobrze działa jako pierwsza linia obrony.

def valid_nip(nip: str) -> bool:
    nip = ''.join(ch for ch in nip if ch.isdigit())
    if len(nip) != 10:
        return False

    weights = [6, 5, 7, 2, 3, 4, 5, 6, 7]
    s = sum(int(nip[i]) * weights[i] for i in range(9))
    control = s % 11
    return control != 10 and control == int(nip[9])


def valid_regon(regon: str) -> bool:
    regon = ''.join(ch for ch in regon if ch.isdigit())
    if len(regon) == 9:
        weights = [8, 9, 2, 3, 4, 5, 6, 7]
        s = sum(int(regon[i]) * weights[i] for i in range(8))
        control = s % 11
        if control == 10:
            control = 0
        return control == int(regon[8])
    return False

W praktyce warto przed taką funkcją zrobić jeszcze normalizację wejścia: usunąć spacje, myślniki i inne znaki separujące, a następnie zapisać wartość w jednolitym formacie.

Jak ograniczać duplikaty kontrahentów

Duplikaty często powstają nie dlatego, że ktoś tworzy dwa rekordy świadomie, ale dlatego, że dane są zapisane w różnych wariantach. Ten sam podmiot może mieć:

  • różne wielkości liter,
  • dodatkowe spacje,
  • skróconą albo pełną nazwę,
  • wpisany raz NIP, a raz brak NIP-u,
  • różne formaty numeru telefonu.

Dlatego przed porównaniem warto dane ujednolicić. Najprostsze kroki to:

  • zamiana tekstu na małe litery,
  • usunięcie podwójnych spacji,
  • obcięcie znaków specjalnych tam, gdzie nie są potrzebne,
  • normalizacja numerów identyfikacyjnych do samych cyfr,
  • zachowanie jednego, ustalonego formatu dla IBAN-u.

Dobrą praktyką jest też określenie, które pola są kluczowe przy wykrywaniu duplikatów. Dla firmy często będzie to NIP, a gdy go brakuje – kombinacja nazwy i adresu. Nie ma jednego uniwersalnego wzorca, ale zawsze warto jasno ustalić regułę deduplikacji.

Walidacja przy imporcie CSV i Excela

Importy są częstym źródłem błędów, bo plik wygląda poprawnie wizualnie, a pod spodem kryje niejednorodne formaty. Typowe problemy to:

  • liczby zapisane jako tekst,
  • daty w różnych lokalnych formatach,
  • niewidoczne znaki końca linii,
  • puste komórki w wymaganych kolumnach,
  • przypadkowe spacje na końcu pola,
  • mieszanie separatorów dziesiętnych.

Przed zapisem warto taki plik przejść etapem transformacji. Dobrze działa prosty schemat:

  • wczytaj dane,
  • zmapuj kolumny do modelu wewnętrznego,
  • normalizuj wartości,
  • sprawdź reguły obowiązkowe,
  • zapisz tylko poprawne rekordy,
  • odrzucone rekordy zwróć z opisem błędu.

To ważne także w automatyzacjach, np. w n8n. Jeśli od razu wrzucimy błędne dane do CRM albo bazy, później będziemy musieli czyścić skutki w wielu miejscach naraz.

Przykład: ograniczenia w PostgreSQL

Baza może dopilnować podstawowych reguł, nawet jeśli aplikacja ich nie sprawdzi. Przykład pokazuje prostą tabelę z ograniczeniami długości i unikalności.

CREATE TABLE kontrahenci (
  id bigserial PRIMARY KEY,
  nip text UNIQUE,
  regon text,
  nazwa text NOT NULL,
  iban text,
  created_at timestamptz NOT NULL DEFAULT now(),
  CONSTRAINT nip_dlugosc CHECK (nip IS NULL OR length(regexp_replace(nip, '\D', '', 'g')) = 10)
);

Takie ograniczenie nie zastąpi pełnej logiki walidacyjnej, ale daje dodatkową ochronę. Jeśli dane trafią do bazy z pominięciem aplikacji, wciąż nie przejdą podstawowych warunków.

Kiedy warto iść krok dalej

Po walidacji lokalnej kolejnym etapem jest wzbogacenie danych o sprawdzenia zewnętrzne. W zależności od procesu może to być:

  • weryfikacja numeru VAT w rejestrach,
  • sprawdzenie konta na białej liście,
  • potwierdzenie danych adresowych,
  • pobranie kursu walut do przeliczeń,
  • porównanie danych z rejestrem urzędowym.

Nie trzeba robić tego przy każdym zapisie w czasie rzeczywistym. Często lepszy jest model mieszany: szybka walidacja w formularzu i dodatkowa weryfikacja asynchroniczna w tle. Dzięki temu użytkownik od razu widzi błąd w oczywistych przypadkach, a system stopniowo doszczelnia dane.

Podsumowanie

Walidacja danych kontrahenta przed zapisem to prosty sposób na uniknięcie bałaganu w bazie, raportach i integracjach. Najlepiej sprawdzać zarówno format, jak i sens biznesowy danych, normalizować wejście, ograniczać duplikaty i wzmacniać wszystko regułami w bazie.

Dobrze zaprojektowany proces walidacji nie musi być skomplikowany. Wystarczy konsekwencja: jedna ścieżka dla importów, jednoznaczne reguły dla kluczowych pól i zapis tylko tego, co przeszło kontrolę.

Jeśli chcesz zautomatyzować walidację lub uzupełnianie danych w swoich procesach, sprawdź API dla programistów albo bezpłatne narzędzia.

← Wszystkie poradniki: dla programistów