Skip to content

Instantly share code, notes, and snippets.

@Przemocny
Created November 9, 2025 19:28
Show Gist options
  • Select an option

  • Save Przemocny/0b19cc52f771b71d62d47e5197ecd625 to your computer and use it in GitHub Desktop.

Select an option

Save Przemocny/0b19cc52f771b71d62d47e5197ecd625 to your computer and use it in GitHub Desktop.
LPD - Direct: Simple Process Language.md

📘 LPD-Direct: Specyfikacja Języka Procesowego

1. Wprowadzenie i Filozofia

LPD-Direct (Logiczny Przepływ Danych) to deklaratywny język pseudokodu służący do projektowania, dokumentowania i automatyzacji procesów biznesowych oraz technologicznych.

Jego głównym celem jest eliminacja bariery komunikacyjnej między ekspertami biznesowymi (wiedzącymi dlaczego coś robimy) a zespołami technicznymi (wiedzącymi jak to zrobić). Składnia wymusza łączenie instrukcji technicznych z ich uzasadnieniem biznesowym.

Fundamenty LPD-Direct:

  • Czytelność: Kod musi być zrozumiały dla osoby nietechnicznej.
  • Kontekst: Każda akcja musi mieć jawnie zdefiniowany cel biznesowy.
  • Pełna Kontrola: Język obsługuje nie tylko sukces ("happy path"), ale też błędy, decyzje ludzkie i sztuczną inteligencję.
  • Jednoznaczność: Każda konstrukcja ma dokładnie jedną interpretację.

2. Struktura Skryptu

Każdy proces opisany w LPD-Direct składa się z trzech głównych sekcji:

  1. Wyzwalacz (TRIGGER): Definicja, co uruchamia proces.
  2. Ciało Procesu: Logiczna sekwencja operacji podzielona na fazy (np. Gromadzenie, Przetwarzanie, Decyzje).
  3. Zakończenie: Jawny sygnał końca przepływu.

2.1. Żelazna Zasada: Podwójny Komentarz

Każde polecenie operacyjne musi być poprzedzone dwoma komentarzami. To nie jest opcjonalne.

  • // Co robimy: (Opis techniczny czynności)
  • // Po co: (Uzasadnienie biznesowe)

Wyjątki: TRIGGER i SYSTEMS nie wymagają podwójnego komentarza (mają wbudowany opis).

// Co robimy: Filtrujemy zamówienia ze statusem 'Anulowane'.
// Po co: Aby nie naliczać prowizji od sprzedaży, która nie doszła do skutku.
FILTER ZAMOWIENIA WHERE Status != 'Anulowane' AS ZAMOWIENIA_SKUTECZNE

2.2. Deklaracja Systemów (SYSTEMS)

Opcjonalna sekcja definiująca zewnętrzne systemy i oprogramowanie używane w procesie. Umieszczana bezpośrednio po TRIGGER, przed pierwszym SET/LOAD.

Składnia:

// SYSTEMS:
// - <Nazwa Systemu>: <Typ> - <Opis, co zawiera/robi>
// - <Nazwa Systemu>: <Typ> - <Opis>

Przykład:

// TRIGGER: SCHEDULE EVERY DAY AT 09:00 CET

// SYSTEMS:
// - ERP Firma: REST API - System fakturowania i zarządzania płatnościami klientów
// - BazaHR: PostgreSQL - Baza danych pracowników i struktury organizacyjnej
// - Salesforce: REST API - CRM do zarządzania leadami i kontaktami
// - Mail Service: SMTP - Serwer pocztowy do wysyłki automatycznych powiadomień
// - Slack: Webhook - Komunikator zespołowy do alertów operacyjnych

// Co robimy: Ustalamy dzisiejszą datę.
// Po co: Do obliczeń terminów.
SET DZISIAJ = CURRENT_DATE()

Cel: Dokumentacja zależności procesu od zewnętrznych systemów - ułatwia onboarding nowych osób i identyfikację punktów awarii.

Format wpisu:

  • Nazwa Systemu: Nazwa używana w aliasach LOAD/SEND
  • Typ: REST API, GraphQL, SQL (PostgreSQL/MySQL), SMTP, Webhook, File System, itp.
  • Opis: Zwięzły opis roli systemu w procesie (1 zdanie)

3. Typy Danych i Literały

3.1. Typy Podstawowe

Typ Przykład Opis
STRING 'Tekst' Tekst w pojedynczych apostrofach
NUMBER 123, 45.67 Liczby całkowite i dziesiętne
BOOLEAN TRUE, FALSE Wartości logiczne
NULL NULL Brak wartości
DATE 2024-01-15 Data w formacie ISO 8601
DATETIME 2024-01-15T09:00:00Z Data i czas w formacie ISO 8601

3.2. Typy Złożone

Typ Przykład Opis
DATASET Rezultat LOAD/FILTER/CALCULATE Tabela danych z nazwanymi kolumnami
LIST [1, 2, 3] Lista wartości

3.3. Jednostki Fizyczne

Jednostki są częścią literału i muszą być oddzielone spacją:

SET PROG_VIP = 5000 EUR
SET TIMEOUT = 30 SECONDS
SET DELAY = 7 DAYS

Dostępne jednostki: EUR, USD, PLN, SECONDS, MINUTES, HOURS, DAYS, WEEKS, MONTHS, YEARS, PERCENT


4. Konwencje Nazewnicze (OBOWIĄZKOWE)

4.1. Zmienne i Datasety

Format: UPPER_SNAKE_CASE

SET DZISIAJ = CURRENT_DATE()
LOAD API FROM '...' AS WSZYSTKIE_ZALEGLOSCI
FILTER DATA WHERE x > 10 AS WYNIK_FILTROWANIA

4.2. Kolumny w Datasetach

Format: Bez cudzysłowów, PascalCase z podkreślnikami dla złożonych nazw

FILTER SPRZEDAZ WHERE Status = 'Aktywny' AS RESULT
CALCULATE on DATA:
    Marza_PLN = Cena_Sprzedazy - Koszt_Zakupu
AS RESULT_Z_MARZA

Wyjątek: Jeśli nazwa kolumny zawiera spacje lub znaki specjalne, użyj pojedynczych apostrofów:

FILTER DATA WHERE 'Full Name' = 'Jan Kowalski' AS RESULT

4.3. Stringi Literalne

Format: Zawsze w pojedynczych apostrofach '...'

SET NAZWA = 'Raport Miesięczny'
SEND ALERT 'Uwaga: wykryto anomalię!' TO 'Slack / #alerts'

5. Operatory

5.1. Operatory Porównania

Operator Znaczenie Przykład
= Równe Status = 'Aktywny'
!= Różne Status != 'Anulowane'
> Większe Kwota > 1000
>= Większe lub równe Kwota >= 1000
< Mniejsze Kwota < 1000
<= Mniejsze lub równe Termin_Platnosci <= DZISIAJ

5.2. Operatory Logiczne

Operator Znaczenie Przykład Precedencja
NOT Negacja NOT (x > 10) 1 (najwyższa)
AND Koniunkcja x > 10 AND y < 20 2
OR Alternatywa Status = 'A' OR Status = 'B' 3 (najniższa)

Nawiasy: Używaj () do wymuszenia kolejności wykonywania.

FILTER DATA WHERE (Status = 'Aktywny' OR Status = 'Testowy') AND Kwota > 1000 AS RESULT

5.3. Operatory Specjalne

Operator Znaczenie Przykład
IS NULL Sprawdza czy wartość jest NULL Email IS NULL
IS NOT NULL Sprawdza czy wartość nie jest NULL Email IS NOT NULL
IS EMPTY Sprawdza czy dataset jest pusty DATASET IS EMPTY
IS NOT EMPTY Sprawdza czy dataset zawiera dane DATASET IS NOT EMPTY

5.4. Operatory Arytmetyczne

Operator Znaczenie Precedencja
+ Dodawanie 2
- Odejmowanie 2
* Mnożenie 1 (najwyższa)
/ Dzielenie 1
% Modulo (reszta z dzielenia) 1

6. Funkcje Wbudowane

6.1. Funkcje Daty i Czasu

Funkcja Zwraca Przykład
CURRENT_DATE() Dzisiejsza data 2024-01-15
CURRENT_DATETIME() Obecna data i czas 2024-01-15T09:30:00Z
ADD_DAYS(date, n) Data + n dni ADD_DAYS(DZISIAJ, 7)
SUBTRACT_DAYS(date, n) Data - n dni SUBTRACT_DAYS(DZISIAJ, 30)
FORMAT_DATE(date, format) Formatowanie daty FORMAT_DATE(DZISIAJ, 'DD-MM-YYYY')
DAYS_BETWEEN(date1, date2) Różnica w dniach DAYS_BETWEEN(Termin, DZISIAJ)

6.2. Funkcje Tekstowe

Funkcja Zwraca Przykład
UPPER(string) Tekst wielkimi literami UPPER('test')'TEST'
LOWER(string) Tekst małymi literami LOWER('TEST')'test'
TRIM(string) Tekst bez spacji na krańcach TRIM(' test ')'test'
LENGTH(string) Długość tekstu LENGTH('test')4
CONCAT(str1, str2, ...) Łączenie tekstów CONCAT('A', 'B')'AB'
SUBSTRING(string, start, len) Wycinek tekstu SUBSTRING('test', 1, 2)'te'

6.3. Funkcje Numeryczne

Funkcja Zwraca Przykład
ROUND(number, decimals) Zaokrąglenie ROUND(3.14159, 2)3.14
CEIL(number) Zaokrąglenie w górę CEIL(3.1)4
FLOOR(number) Zaokrąglenie w dół FLOOR(3.9)3
ABS(number) Wartość bezwzględna ABS(-5)5
MIN(a, b, ...) Minimum MIN(1, 5, 3)1
MAX(a, b, ...) Maksimum MAX(1, 5, 3)5

6.4. Funkcje Agregujące (tylko w CALCULATE)

Funkcja Zwraca Przykład
SUM(column) Suma wartości SUM(Kwota)
AVG(column) Średnia AVG(Ocena)
COUNT(column) Liczba rekordów COUNT(ID)
MIN(column) Minimum MIN(Cena)
MAX(column) Maksimum MAX(Cena)

7. Składnia Konstrukcji

7.1. Wyzwalacze (TRIGGER)

Składnia: // TRIGGER: <typ> <parametry>

Typy wyzwalaczy:

// TRIGGER: SCHEDULE EVERY DAY AT 08:00 CET
// TRIGGER: SCHEDULE EVERY MONDAY AT 09:00 CET
// TRIGGER: SCHEDULE EVERY 1st DAY OF MONTH AT 00:00 UTC
// TRIGGER: ON WEBHOOK RECEIVE (endpoint: '/api/nowy-klient')
// TRIGGER: MANUAL BY USER (Rola: 'Analityk Danych')
// TRIGGER: ON FILE UPLOAD (path: '/uploads/*.csv')

Wyzwalacz jest zawsze jednolinijkowy i znajduje się na początku procesu.


7.2. Zmienne Globalne (SET i OVERRIDE)

SET - Deklaracja Zmiennej

Składnia: SET <ZMIENNA> = <wartość>

Deklaruje nową zmienną globalną. Zmienna nie może być nadpisana przez kolejny SET.

// Co robimy: Zapisujemy dzisiejszą datę w zmiennej.
// Po co: Aby użyć jej później do filtrowania przeterminowanych zadań.
SET DZISIAJ = CURRENT_DATE()

// Co robimy: Definiujemy próg kwotowy dla zamówień VIP.
// Po co: Aby łatwo zmienić tę wartość w przyszłości bez przeszukiwania całego kodu.
SET PROG_VIP = 5000 EUR

Błąd - próba nadpisania przez SET:

SET DZISIAJ = CURRENT_DATE()
SET DZISIAJ = ADD_DAYS(DZISIAJ, 1)  // ❌ BŁĄD: Nie można nadpisać zmiennej przez SET

OVERRIDE - Nadpisanie Istniejącej Zmiennej

Składnia: OVERRIDE <ZMIENNA> = <wartość>

Nadpisuje wartość istniejącej zmiennej. Zmienna musi być wcześniej zadeklarowana przez SET.

// Co robimy: Zapisujemy dzisiejszą datę.
// Po co: Punkt startowy dla obliczeń.
SET DZISIAJ = CURRENT_DATE()

// Co robimy: Przesuwamy datę o 1 dzień do przodu.
// Po co: Aby obliczyć termin "jutro" dla procesu planowania.
OVERRIDE DZISIAJ = ADD_DAYS(DZISIAJ, 1)

Błąd - OVERRIDE bez wcześniejszego SET:

OVERRIDE NOWA_ZMIENNA = 100  // ❌ BŁĄD: Zmienna nie została wcześniej zadeklarowana

Uwaga: OVERRIDE należy używać ostrożnie - może prowadzić do trudniejszego śledzenia przepływu danych. W większości przypadków lepiej utworzyć nową zmienną:

SET DZISIAJ = CURRENT_DATE()
SET JUTRO = ADD_DAYS(DZISIAJ, 1)  // ✅ Preferowane - jasne co jest co

7.3. Gromadzenie Danych (LOAD)

Składnia: LOAD <źródło> FROM <lokalizacja> [parametry] AS <DATASET>

Typy źródeł:

API

// Co robimy: Pobieramy listę faktur niezapłaconych z API ERP.
// Po co: Aby zidentyfikować klientów zalegających z płatnościami.
LOAD API FROM 'https://erp.firma.pl/api/invoices?status=unpaid' AS FAKTURY
ON ERROR: STOP AND ALERT 'Admin ERP'

SQL

// Co robimy: Pobieramy listę aktywnych pracowników z bazy HR.
// Po co: Aby wiedzieć, komu naliczyć wynagrodzenie.
LOAD SQL FROM 'BazaHR' QUERY 'SELECT * FROM employees WHERE status = active' AS PRACOWNICY
ON ERROR: RETRY 3 TIMES THEN STOP AND ALERT 'Zespół Kadr'

Plik CSV/Excel

// Co robimy: Wczytujemy dane sprzedażowe z pliku Excel.
// Po co: Aby przeanalizować wyniki sprzedaży w ostatnim kwartale.
LOAD FILE FROM '/data/sprzedaz_Q4.xlsx' SHEET 'Sprzedaż' AS DANE_SPRZEDAZY
ON ERROR: STOP AND ALERT 'Data Analyst'

Uwagi:

  • 'BazaHR' to alias zdefiniowany w konfiguracji środowiska (poza zakresem języka)
  • Credentials są zarządzane przez środowisko wykonawcze

7.4. Filtrowanie (FILTER)

Składnia: FILTER <DATASET> WHERE <warunek> AS <NOWY_DATASET>

// Co robimy: Filtrujemy faktury przeterminowane o ponad 7 dni.
// Po co: Dajemy klientom tydzień "okresu karencji" zanim zaczniemy windykację.
FILTER WSZYSTKIE_ZALEGLOSCI WHERE Termin_Platnosci <= SUBTRACT_DAYS(DZISIAJ, 7) AS ZALEGLOSCI_DO_WINDYKACJI

Złożone warunki:

// Co robimy: Filtrujemy zamówienia aktywne lub testowe z kwotą powyżej 1000 EUR.
// Po co: Aby wykluczyć anulowane zamówienia i małe transakcje testowe.
FILTER ZAMOWIENIA WHERE (Status = 'Aktywny' OR Status = 'Testowy') AND Kwota > 1000 EUR AS ZAMOWIENIA_WAZNE

7.5. Sortowanie (SORT)

Składnia: SORT <DATASET> BY <kolumna> <ASC|DESC> [, <kolumna> <ASC|DESC> ...] AS <NOWY_DATASET>

Kierunki sortowania:

  • ASC - rosnąco (od najmniejszej do największej)
  • DESC - malejąco (od największej do najmniejszej)

Sortowanie po jednej kolumnie:

// Co robimy: Sortujemy produkty według ceny rosnąco.
// Po co: Aby pokazać najtańsze produkty na początku listy.
SORT PRODUKTY BY Cena ASC AS PRODUKTY_POSORTOWANE

Sortowanie po wielu kolumnach:

// Co robimy: Sortujemy zamówienia według daty malejąco, a potem według kwoty rosnąco.
// Po co: Aby zobaczyć najnowsze zamówienia, a wśród nich najpierw te najmniejsze.
SORT ZAMOWIENIA BY Data_Zamowienia DESC, Kwota ASC AS ZAMOWIENIA_POSORTOWANE

Uwagi:

  • Domyślny kierunek to ASC jeśli nie podano
  • Przy sortowaniu po wielu kolumnach, pierwsza kolumna ma najwyższy priorytet
  • Wartości NULL są traktowane jako najmniejsze (pojawiają się na początku przy ASC)

7.6. Grupowanie i Agregacja (GROUP)

Składnia:

GROUP <DATASET> BY <kolumna1> [, <kolumna2> ...]:
    <Agregat1> = <funkcja_agregująca>(kolumna)
    <Agregat2> = <funkcja_agregująca>(kolumna)
AS <NOWY_DATASET>

Wcięcia: Obowiązkowe 4 spacje dla każdego wiersza wewnątrz bloku.

Funkcje agregujące: SUM(), AVG(), COUNT(), MIN(), MAX()

Grupowanie po jednej kolumnie:

// Co robimy: Grupujemy sprzedaż według produktu i sumujemy sprzedane jednostki.
// Po co: Aby zobaczyć, ile sztuk każdego produktu sprzedaliśmy w sumie.
GROUP SPRZEDAZ BY Produkt:
    Suma_Jednostek = SUM(Ilosc)
    Suma_Przychodu = SUM(Cena * Ilosc)
AS SPRZEDAZ_PER_PRODUKT

Grupowanie po wielu kolumnach:

// Co robimy: Grupujemy zamówienia według kraju i miasta klienta.
// Po co: Aby zobaczyć średnią wartość zamówienia w każdym mieście.
GROUP ZAMOWIENIA BY Kraj, Miasto:
    Liczba_Zamowien = COUNT(ID_Zamowienia)
    Srednia_Wartosc = AVG(Kwota)
    Max_Zamowienie = MAX(Kwota)
AS STATYSTYKI_LOKALIZACJI

Semantyka:

  • Resultat zawiera jedną linię na unikalną kombinację wartości w kolumnach GROUP BY
  • Kolumny użyte w GROUP BY są automatycznie dostępne w wyniku
  • Wszystkie inne kolumny muszą być zagregowane

Przykład z rzeczywistymi danymi:

Wejście (SPRZEDAZ):
| Produkt | Kraj | Kwota |
|---------|------|-------|
| Laptop  | PL   | 5000  |
| Laptop  | PL   | 4500  |
| Laptop  | DE   | 6000  |
| Mysz    | PL   | 100   |

GROUP SPRZEDAZ BY Produkt, Kraj:
    Suma_Sprzedazy = SUM(Kwota)
    Liczba = COUNT(Kwota)
AS WYNIK

Wyjście (WYNIK):
| Produkt | Kraj | Suma_Sprzedazy | Liczba |
|---------|------|----------------|--------|
| Laptop  | PL   | 9500           | 2      |
| Laptop  | DE   | 6000           | 1      |
| Mysz    | PL   | 100            | 1      |

7.7. Obliczenia (CALCULATE)

Składnia:

CALCULATE on <DATASET>:
    <Nowa_Kolumna_1> = <wyrażenie>
    <Nowa_Kolumna_2> = <wyrażenie>
AS <NOWY_DATASET>

Wcięcia: Obowiązkowe 4 spacje dla każdego wiersza wewnątrz bloku.

// Co robimy: Wyliczamy marżę dla każdego produktu.
// Po co: Aby zidentyfikować najmniej rentowne towary.
CALCULATE on SPRZEDAZ:
    Marza_PLN = Cena_Sprzedazy - Koszt_Zakupu
    Marza_Procent = (Marza_PLN / Cena_Sprzedazy) * 100
AS SPRZEDAZ_Z_MARZA

Funkcje agregujące:

// Co robimy: Wyliczamy całkowitą sprzedaż i średnią marżę.
// Po co: Aby uzyskać podsumowanie wyników sprzedażowych.
CALCULATE on SPRZEDAZ:
    Suma_Sprzedazy = SUM(Kwota)
    Srednia_Marza = AVG(Marza_Procent)
AS PODSUMOWANIE_SPRZEDAZY

7.8. Łączenie Danych (JOIN)

Składnia: JOIN <typ> <DATASET1> WITH <DATASET2> ON <klucz> AS <NOWY_DATASET>

Typy JOIN:

  • INNER - tylko dopasowane rekordy z obu stron
  • LEFT - wszystkie z lewej + dopasowane z prawej
  • RIGHT - wszystkie z prawej + dopasowane z lewej
  • FULL - wszystkie rekordy z obu stron

Domyślny typ: Jeśli nie podano, używany jest INNER.

// Co robimy: Łączymy tabelę sprzedaży z bazą klientów po ID_Klienta.
// Po co: Aby wzbogacić dane transakcyjne o informacje demograficzne (miasto, wiek).
JOIN INNER SPRZEDAZ WITH KLIENCI ON ID_Klienta AS DANE_PELNE
// Co robimy: Łączymy zamówienia z płatnościami, zachowując wszystkie zamówienia.
// Po co: Aby zobaczyć, które zamówienia nie mają jeszcze płatności.
JOIN LEFT ZAMOWIENIA WITH PLATNOSCI ON ID_Zamowienia AS ZAMOWIENIA_Z_PLATNOSCI

7.9. Sterowanie Warunkowe (IF/ELSE)

Składnia:

IF <warunek> THEN
    // instrukcje (z podwójnymi komentarzami)
ELSE IF <warunek> THEN
    // instrukcje
ELSE
    // instrukcje
END IF

Wcięcia: Obowiązkowe 4 spacje dla treści wewnątrz bloków.

// Co robimy: Sprawdzamy, czy po filtracji zostały jakiekolwiek dane do wysyłki.
// Po co: Aby nie wysyłać pustych raportów do zarządu.
IF DANE_PELNE IS EMPTY THEN
    // Co robimy: Kończymy proces w tym miejscu.
    // Po co: Brak danych oznacza brak potrzeby generowania raportu.
    STOP PROCESS (Log: 'Brak danych z dzisiaj, pomijam wysyłkę')
ELSE IF COUNT(DANE_PELNE) < 10 THEN
    // Co robimy: Wysyłamy uproszczony raport.
    // Po co: Dla małej liczby danych pełny raport jest przesadą.
    SEND DANE_PELNE TO API 'https://raport.pl/simple'
ELSE
    // Co robimy: Generujemy i wysyłamy pełny raport.
    // Po co: Duża liczba danych wymaga szczegółowej analizy.
    SEND DANE_PELNE TO API 'https://raport.pl/full'
END IF

Warunki na zmiennych:

IF PROG_VIP > 10000 EUR THEN
    // instrukcje
END IF

7.10. Sztuczna Inteligencja (ASK_AI)

Semantyka: AI wykonuje zadanie dla każdego rekordu osobno (iteracja po wierszach).

Składnia Pełna (Precyzyjna)

ASK_AI on <DATASET>:
    ZADANIE: '<opis zadania z [Nazwa_Kolumny] jako placeholder>'
    ZWROC: <Nazwa_Nowej_Kolumny>
AS <NOWY_DATASET>

Wcięcia: Obowiązkowe 4 spacje dla ZADANIE i ZWROC.

// Co robimy: Prosimy AI o wygenerowanie spersonalizowanej treści maila.
// Po co: Aby komunikacja była dopasowana do klienta, a nie brzmiała jak robot.
ASK_AI on ZALEGLOSCI_DO_WINDYKACJI:
    ZADANIE: 'Napisz krótkie przypomnienie o fakturze [Nr_Faktury] na kwotę [Kwota]. Użyj uprzejmego tonu.'
    ZWROC: Tresc_Maila
AS PRZYGOTOWANE_WYSYLKI

Składnia Uproszczona (Naturalna)

ASK_AI: <opis zadania w naturalnym języku> AS <NOWY_DATASET>

Używaj gdy szczegóły (które kolumny, jak nazywać output) są oczywiste z kontekstu.

// Co robimy: AI generuje uprzejme przypomnienia o płatnościach.
// Po co: Aby komunikacja była dopasowana do klienta.
ASK_AI: napisz uprzejme przypomnienia o fakturach AS PRZYGOTOWANE_WYSYLKI
// Co robimy: AI ocenia sentyment komentarzy klientów.
// Po co: Aby wyłapać niezadowolonych klientów.
ASK_AI: oceń sentyment komentarzy na skali 1-5 AS ANKIETY_OCENIONE

Obsługa błędów (dla obu składni):

ASK_AI on DANE:
    ZADANIE: 'Wyciągnij NIP z tekstu [Body].'
    ZWROC: NIP
AS DANE_Z_NIP
ON ERROR: RETRY 2 TIMES THEN SKIP
ASK_AI: wyciągnij NIP z treści maili AS DANE_Z_NIP
ON ERROR: RETRY 2 TIMES THEN SKIP

Kiedy użyć której składni:

  • Pełna: Gdy precyzyjnie określasz źródłowe kolumny [Nazwa_Kolumny] i nazwę nowej kolumny
  • Uproszczona: Gdy szczegóły są jasne z kontekstu lub dla szybkiego prototypowania

7.11. Pętla Zwrotna z Człowiekiem (AWAIT APPROVAL)

Składnia:

AWAIT APPROVAL FROM '<rola>' ON <DATASET>
    POKAZ: '<kolumna1>', '<kolumna2>', ...
    PYTANIE: '<treść pytania>'
AS <NOWY_DATASET>

Semantyka:

  • Proces zatrzymuje się i czeka na decyzję użytkownika
  • <NOWY_DATASET> zawiera tylko zatwierdzone rekordy
  • Odrzucone rekordy są trwale usuwane z przepływu
  • Użytkownik może edytować wartości w kolumnach przed zatwierdzeniem

Wcięcia: Obowiązkowe 4 spacje dla POKAZ i PYTANIE.

// Co robimy: Wstrzymujemy proces do momentu akceptacji faktury przez menedżera.
// Po co: Zapobieganie automatycznemu opłaceniu błędnych lub zbyt wysokich faktur.
AWAIT APPROVAL FROM 'Menedżer Działu' ON FAKTURY_DO_OPLACENIA
    POKAZ: 'Kontrahent', 'Kwota_Brutto', 'Opis_Uslugi'
    PYTANIE: 'Czy akceptujesz tę fakturę do płatności?'
AS FAKTURY_ZATWIERDZONE

Timeout (opcjonalnie):

AWAIT APPROVAL FROM 'Kierownik Finansów' ON PRZYGOTOWANE_WYSYLKI
    POKAZ: 'Klient', 'Kwota', 'Tresc_Maila'
    PYTANIE: 'Czy wysłać to przypomnienie VIP?'
    TIMEOUT: 2 HOURS THEN SKIP
AS ZATWIERDZONE_VIP

7.12. Akcje Wyjściowe (SEND)

Składnia:

API

SEND <DATASET> TO API '<url>' [parametry]
// Co robimy: Wysyłamy przetworzone leady do systemu Salesforce przez API.
// Po co: Aby dział sprzedaży mógł natychmiast rozpocząć kontakt z nowymi klientami.
SEND GOTOWE_LEADY TO API 'https://salesforce.com/api/leads/bulk' (Method: POST, Headers: {'Authorization': 'Bearer TOKEN_VAR'})
ON ERROR: RETRY 5 TIMES THEN ALERT 'Admin CRM'

Uwaga: TOKEN_VAR to referencja do zmiennej środowiskowej (poza zakresem języka).

Email

SEND EMAIL TO '<recipient>' SUBJECT '<temat>' BODY '<treść>'
// Co robimy: Wysyłamy email z linkiem do raportu.
// Po co: Aby zarząd miał dostęp do wyników z rana.
SEND EMAIL TO 'prezes@firma.pl' SUBJECT 'Raport Dzienny' BODY 'Dostępny pod: https://raport.pl/daily'

Alert

SEND ALERT '<wiadomość>' TO '<kanał>'
// Co robimy: Wysyłamy powiadomienie na komunikator Slack.
// Po co: Aby poinformować zespół operacyjny o wykryciu anomalii w danych.
SEND ALERT 'Uwaga: Wykryto 5 transakcji powyżej 1mln PLN!' TO 'Slack / #finanse-alerty'

Eksport do Pliku

SEND <DATASET> TO FILE '<ścieżka>' FORMAT <CSV|XLSX|JSON>
// Co robimy: Eksportujemy dane do pliku CSV.
// Po co: Aby użytkownik mógł pobrać wyniki do Excela.
SEND RAPORT_KONCOWY TO FILE '/exports/raport_sprzedaz_Q4.csv' FORMAT CSV

7.13. Obsługa Błędów (ON ERROR)

Składnia: ON ERROR: <strategia>

Strategie:

Strategia Znaczenie Kontynuacja procesu
STOP Natychmiastowe zakończenie całego procesu Nie
STOP AND ALERT '<rola>' Zakończenie + powiadomienie Nie
SKIP Pomiń ten krok, kontynuuj dalej Tak
RETRY <n> TIMES THEN SKIP Ponów n razy, potem pomiń Tak
RETRY <n> TIMES THEN STOP Ponów n razy, potem zakończ Warunkowe
RETRY <n> TIMES THEN ALERT '<rola>' Ponów n razy, potem powiadom Tak

Zakres działania: ON ERROR odnosi się do bezpośrednio poprzedzającego polecenia.

// Co robimy: Pobieramy dane z API, które może być niestabilne.
// Po co: Aby uzyskać aktualne kursy walut do przeliczeń.
LOAD API FROM 'https://api.nbp.pl/exchangerates/tables/A/' AS KURSY_WALUT
ON ERROR: RETRY 3 TIMES THEN SKIP

Semantyka SKIP: Proces kontynuuje, ale zmienna KURSY_WALUT będzie NULL. Użytkownik musi obsłużyć ten przypadek:

IF KURSY_WALUT IS NULL THEN
    // Co robimy: Używamy wczorajszych kursów.
    // Po co: Aby proces mógł kontynuować mimo awarii NBP.
    SET KURSY_WALUT = WCZORAJSZE_KURSY
END IF

Semantyka STOP: Cały proces kończy się, żadne kolejne instrukcje nie są wykonywane.


7.14. Zakończenie Procesu

Składnia:

STOP PROCESS [(Log: '<wiadomość>')]
// Co robimy: Kończymy proces przedwcześnie.
// Po co: Brak danych oznacza brak pracy do wykonania.
STOP PROCESS (Log: 'Brak nowych faktur, proces zakończony')

Uwaga: Koniec pliku oznacza naturalny koniec procesu - nie trzeba pisać STOP PROCESS na końcu.


8. Zakres i Mutowanie Zmiennych

8.1. Zmienne Globalne (SET i OVERRIDE)

  • SET: Deklaruje nową zmienną - niemutowalną przez SET (nie można ponownie użyć SET na tej samej nazwie)
  • OVERRIDE: Nadpisuje istniejącą zmienną - mutowalną (można wielokrotnie nadpisywać)
  • Zakres: Globalny (widoczne w całym procesie)
SET COUNTER = 0
OVERRIDE COUNTER = 1  // ✅ OK
OVERRIDE COUNTER = 2  // ✅ OK - można wielokrotnie nadpisywać
SET COUNTER = 3       // ❌ BŁĄD - nie można użyć SET na istniejącej zmiennej

8.2. Datasety (AS)

  • Niemutowalne - każda transformacja tworzy nowy dataset
  • Zakres: Lokalny (widoczne od momentu utworzenia do końca procesu)
  • Nadpisywanie: Dozwolone, ale stary dataset przestaje istnieć
FILTER DATA WHERE x > 10 AS RESULT
FILTER RESULT WHERE y < 5 AS RESULT  // ✅ OK: RESULT zostaje zastąpiony
FILTER DATA WHERE z > 0 AS RESULT    // ✅ OK: RESULT znowu zastąpiony

Dobra praktyka: Używaj unikalnych nazw dla jasności:

FILTER DATA WHERE x > 10 AS DATA_STEP1
FILTER DATA_STEP1 WHERE y < 5 AS DATA_STEP2

9. Model Wykonania

9.1. Sekwencyjność

Wszystkie operacje wykonują się sekwencyjnie (jedna po drugiej) w kolejności zapisania.

Brak równoległości w samym języku - jeśli środowisko wykonawcze obsługuje równoległość (np. przetwarzanie wsadowe), jest to transparentne dla użytkownika.

9.2. Atomowość

Każde polecenie jest atomowe - albo wykonuje się w całości, albo w ogóle (i wywołuje błąd).

Brak częściowych rezultatów: Jeśli LOAD pobierze 500 z 1000 rekordów i padnie, zwrócony zostanie błąd (nie dataset z 500 rekordami).

9.3. Brak Rollbacku

Język nie obsługuje transakcji ani rollbacku. Jeśli proces wykonał 10 kroków i padł na 11., pierwsze 10 zostaje (np. wysłane emaile, zapisane pliki).

Odpowiedzialność użytkownika: Projektuj procesy idempotentne lub używaj zewnętrznych mechanizmów transakcyjnych.


10. Przykłady Pełnych Procesów

10.1. Automatyzacja Przypomnień o Płatnościach

// TRIGGER: SCHEDULE EVERY DAY AT 09:00 CET

// --- Faza 1: Inicjalizacja i Dane ---
// Co robimy: Ustalamy dzisiejszą datę do obliczeń opóźnień.
// Po co: Aby precyzyjnie wyliczyć liczbę dni po terminie.
SET DZISIAJ = CURRENT_DATE()

// Co robimy: Pobieramy z ERP faktury niezapłacone, z terminem płatności < DZISIAJ.
// Po co: Aby zidentyfikować klientów zalegających z płatnościami.
LOAD API FROM 'https://erp.firma.pl/api/invoices?status=unpaid' AS WSZYSTKIE_ZALEGLOSCI
ON ERROR: STOP AND ALERT 'Admin ERP'

// Co robimy: Filtrujemy tylko te przeterminowane o ponad 7 dni.
// Po co: Dajemy klientom tydzień "okresu karencji" zanim zaczniemy windykację.
FILTER WSZYSTKIE_ZALEGLOSCI WHERE Termin_Platnosci <= SUBTRACT_DAYS(DZISIAJ, 7) AS ZALEGLOSCI_DO_WINDYKACJI

// --- Faza 2: AI i Decyzje ---
// Co robimy: Prosimy AI o wygenerowanie spersonalizowanej, grzecznej treści maila dla każdego klienta.
// Po co: Aby komunikacja była dopasowana do klienta, a nie brzmiała jak robot.
ASK_AI on ZALEGLOSCI_DO_WINDYKACJI:
    ZADANIE: 'Napisz krótkie przypomnienie o fakturze [Nr_Faktury] na kwotę [Kwota]. Użyj uprzejmego tonu.'
    ZWROC: Tresc_Maila
AS PRZYGOTOWANE_WYSYLKI

// Co robimy: Dzielimy proces w zależności od kwoty zaległości.
// Po co: Duże kwoty są ryzykowne relacyjnie, chcemy by człowiek rzucił okiem przed wysyłką.
IF PRZYGOTOWANE_WYSYLKI.Kwota > 10000 EUR THEN

    // --- Ścieżka VIP (wymaga akceptacji) ---
    // Co robimy: Wstrzymujemy proces dla tych rekordów i wysyłamy prośbę do Kierownika Finansów.
    // Po co: Uniknięcie pomyłki przy kluczowych klientach.
    AWAIT APPROVAL FROM 'Kierownik Finansów' ON PRZYGOTOWANE_WYSYLKI
        POKAZ: 'Klient', 'Kwota', 'Tresc_Maila'
        PYTANIE: 'Czy wysłać to przypomnienie VIP?'
    AS ZATWIERDZONE_VIP

    // Co robimy: Wysyłamy tylko zatwierdzone maile VIP.
    // Po co: Aby dotrzeć do kluczowych klientów z potwierdzoną komunikacją.
    SEND ZATWIERDZONE_VIP TO API 'https://mail.firma.pl/send'

ELSE
    // --- Ścieżka Standard (automatyczna) ---
    // Co robimy: Wysyłamy maile automatycznie dla mniejszych kwot.
    // Po co: Oszczędność czasu menedżera przy rutynowych przypomnieniach.
    SEND PRZYGOTOWANE_WYSYLKI TO API 'https://mail.firma.pl/send'

END IF

10.2. Raportowanie Sprzedaży z Analizą Marży

// TRIGGER: SCHEDULE EVERY 1st DAY OF MONTH AT 00:00 UTC

// Co robimy: Ustawiamy zmienne czasowe dla poprzedniego miesiąca.
// Po co: Aby raport dotyczył kompletnego miesiąca.
SET DATA_OD = SUBTRACT_DAYS(CURRENT_DATE(), 30)
SET DATA_DO = CURRENT_DATE()

// Co robimy: Pobieramy dane sprzedażowe z bazy produkcyjnej.
// Po co: Aby przeanalizować wyniki sprzedaży za miniony miesiąc.
LOAD SQL FROM 'BazaProdukcyjna' QUERY 'SELECT * FROM sales WHERE sale_date BETWEEN @DATA_OD AND @DATA_DO' AS SPRZEDAZ
ON ERROR: RETRY 3 TIMES THEN STOP AND ALERT 'DBA Team'

// Co robimy: Wyliczamy marżę dla każdej transakcji.
// Po co: Aby zidentyfikować najbardziej i najmniej rentowne produkty.
CALCULATE on SPRZEDAZ:
    Marza_PLN = Cena_Sprzedazy - Koszt_Zakupu
    Marza_Procent = (Marza_PLN / Cena_Sprzedazy) * 100
AS SPRZEDAZ_Z_MARZA

// Co robimy: Filtrujemy transakcje z ujemną marżą.
// Po co: Aby zidentyfikować produkty sprzedawane ze stratą.
FILTER SPRZEDAZ_Z_MARZA WHERE Marza_PLN < 0 AS PRODUKTY_STRATNE

// Co robimy: Sprawdzamy, czy są produkty ze stratą.
// Po co: Aby zdecydować, czy trzeba wysłać alert do zarządu.
IF PRODUKTY_STRATNE IS NOT EMPTY THEN
    // Co robimy: Wysyłamy alert o produktach ze stratą.
    // Po co: Aby zarząd mógł szybko zareagować na problem.
    SEND ALERT 'Uwaga: Wykryto produkty sprzedawane ze stratą!' TO 'Slack / #management-alerts'
    
    // Co robimy: Eksportujemy szczegóły do pliku.
    // Po co: Aby zarząd miał pełne dane do analizy.
    SEND PRODUKTY_STRATNE TO FILE '/reports/produkty_stratne_miesiac.xlsx' FORMAT XLSX
END IF

// Co robimy: Generujemy podsumowanie całościowe.
// Po co: Aby uzyskać kluczowe metryki sprzedażowe miesiąca.
CALCULATE on SPRZEDAZ_Z_MARZA:
    Suma_Sprzedazy = SUM(Cena_Sprzedazy)
    Suma_Marzy = SUM(Marza_PLN)
    Srednia_Marza_Procent = AVG(Marza_Procent)
AS RAPORT_MIESIAC

// Co robimy: Wysyłamy raport miesięczny emailem.
// Po co: Aby dyrektor sprzedaży otrzymał automatyczny raport.
SEND EMAIL TO 'dyrektor.sprzedazy@firma.pl' SUBJECT 'Raport Miesięczny Sprzedaży' BODY 'Suma sprzedaży: [Suma_Sprzedazy], Marża: [Suma_Marzy]'

11. Checklist dla Autorów Procesów

Przed wdrożeniem procesu, sprawdź:

  • Każde polecenie operacyjne ma // Co robimy: i // Po co:
  • Wszystkie zmienne i datasety używają UPPER_SNAKE_CASE
  • Kolumny są w PascalCase lub w apostrofach (jeśli zawierają spacje)
  • Stringi literalne są w pojedynczych apostrofach '...'
  • Wszystkie operacje ryzykowne (LOAD, SEND, ASK_AI) mają ON ERROR
  • Warunki IF używają AND/OR/NOT (nie &&/||/!)
  • Bloki CALCULATE, GROUP i ASK_AI mają wcięcia 4 spacje
  • Każdy JOIN ma określony typ (INNER/LEFT/RIGHT/FULL)
  • Każdy SORT ma określony kierunek (ASC/DESC) dla każdej kolumny
  • AWAIT APPROVAL ma TIMEOUT jeśli proces nie może czekać w nieskończoność
  • Używasz SET do deklaracji, OVERRIDE do nadpisania (nie używaj SET dwukrotnie na tej samej zmiennej)
  • Proces ma jasny TRIGGER na początku
  • Jeśli proces używa zewnętrznych systemów, rozważ dodanie sekcji SYSTEMS
  • Jeśli używasz SKIP w ON ERROR, obsługujesz przypadek NULL
@Przemocny
Copy link
Author

<role>Starszy Analityk BI i Architekt Danych, specjalizujący się w języku LPD-Direct (Wersja Dokumentująca)</role>

<task>Przeprowadź użytkownika przez ustrukturyzowany proces diagnostyczny (Problem -> Diagnoza -> Pogłębienie), aby zebrać wszystkie niezbędne informacje do stworzenia kompletnego skryptu w języku LPD-Direct.</task>



<objective>

    <item>Zrozumienie rzeczywistego problemu biznesowego użytkownika, a nie tylko jego powierzchownego opisu.</item>

    <item>Pełnienie roli konsultanta-diagnosty, który poprzez zadawanie precyzyjnych pytań wydobywa od użytkownika wszystkie wymagania dotyczące danych, logiki i wizualizacji.</item>

    <item>Zebranie 100% informacji o źródłach danych (Faza 1 LPD), wymaganych transformacjach (Faza 2 LPD) i oczekiwanych wizualizacjach (Faza 3 LPD).</item>

    <item>Wygenerowanie kompletnego, zgodnego ze standardami skryptu LPD-Direct jako finalnego rezultatu i "planu wdrożenia" dla użytkownika.</item>

</objective>



<constraints>

    <item>Używaj tylko języka polskiego.</item>

    <item>Bezwzględnie przestrzegaj 3-fazowego procesu rozmowy zdefiniowanego w sekcji <instructions>. Nie przechodź do Fazy 3 (Generowanie) dopóki Faza 2 (Diagnoza) nie jest kompletna.</item>

    <item>Zadawaj pytania jedno po drugim. Czekaj na odpowiedź użytkownika, zanim zadasz kolejne pytanie.</item>

    <item>Jeśli użytkownik nie zna odpowiedzi (np. "nie wiem", "nie znam się na tym"), zastosuj "nakierowanie mentalne": zasugeruj typowe opcje lub podaj przykłady (np. "Czy te dane są w pliku Excel? A może w bazie danych?", "Jakie kolumny tam Pan widzi?", "Czy ten przychód to jest 'cena * sztuki'?")</item>

    <item>Finalny skrypt LPD-Direct musi być w 100% zgodny ze składnią i filozofią opisaną w bazie wiedzy <knowledge_sources>.</item>

    <item>Nie przepraszaj za zadawanie szczegółowych pytań – jest to część Twojej roli jako diagnosty.</item>

</constraints>



<knowledge_sources>

    <source name="LPD-Direct-Specification" description="Kompletna definicja języka LPD-Direct (Wersja Dokumentująca), którego należy użyć do wygenerowania finalnego skryptu.">

        <![CDATA[

        

        --- POCZĄTEK SPECYFIKACJI LPD-DIRECT ---

        

        1. 📘 Oficjalna Instrukcja Języka: LPD-Direct (Wersja Dokumentująca)

        

        1.1. Filozofia i Główne Założenia

        LPD-Direct (Logiczny Przepływ Danych - Wersja Dokumentująca) to język pseudokodu zaprojektowany do planowania i dokumentowania potoków przetwarzania danych (data pipelines) oraz tworzenia dashboardów BI.

        Jego głównym celem jest służenie jako "most" między interesariuszami biznesowymi (którzy rozumieją cel) a zespołami technicznymi (którzy rozumieją implementację).

        Kluczowe założenia:

        - Czytelność przede wszystkim: Składnia jest bliższa językowi naturalnemu niż kodowi.

        - Struktura jest obowiązkowa: Proces jest zawsze podzielony na logiczne Fazy.

        - Samo-dokumentacja: Każda operacja musi mieć uzasadnienie biznesowe (// Po co:). To nie jest opcjonalne.

        - Deklaratywność: Opisujemy co ma być zrobione, a nie jak.

        

        1.2. Struktura Dokumentu

        Każdy skrypt LPD-Direct musi przestrzegać następującej struktury:

        - Start i Koniec: Zawsze zaczyna się od // START: [Tytuł zadania] i kończy // KONIEC: Przepływ zakończony.

        - Fazy: Proces jest podzielony na logiczne Fazy (// --- Faza 1: Gromadzenie Danych ---, // --- Faza 2: Przetwarzanie Danych ---, itd.).

        

        1.3. Kluczowa Zasada: Komentowanie Co? i Po co?

        Każda linia lub logiczny blok pseudokodu musi być poprzedzony dwoma komentarzami:

        - // Co robimy: (Krótki, techniczny opis operacji.)

        - // Po co: (Cel biznesowy tej operacji.)

        

        Przykład:

        // Co robimy: Filtrujemy wiersze, usuwając transakcje testowe i nieudane.

        // Po co: Aby nasza analiza bazowała tylko na realnych, zakończonych sprzedażach.

        FILTER SUROWE_KONWERSJE

        WHERE status is 'Zakończona'

        AND email not contains '@test.com'

        AS CZYSTE_KONWERSJE

        

        1.4. Składnia Poleceń

        - Uchwyty Danych: Zawsze WIELKIMI_LITERAMI (np. SUROWE_DANE, RAPORT_FINALNY).

        - Faza 1: Ładowanie Danych (LOAD)

          LOAD Excel FROM 'ścieżka/plik.xlsx' (arkusz: 'Nazwa') AS NAZWA

          LOAD CSV FROM 'ścieżka/plik.csv' (separator: ';') AS NAZWA

          LOAD API FROM 'https://adres.url/endpoint' AS NAZWA (weź tylko wartość z: 'json.path')

        - Faza 2: Transformacje (FILTER, CALCULATE, JOIN, GROUP BY)

          FILTER NAZWA_WEJŚCIOWA WHERE [warunek] AS NAZWA_WYJŚCIOWA

          CALCULATE on NAZWA_WEJŚCIOWA:

              NowaKolumna = [Wyrażenie]

              InnaKolumna = IF KolumnaA > 10 THEN 'Wysoka' ELSE 'Niska'

          AS NAZWA_WYJŚCIOWA

          JOIN NAZWA_A WITH NAZWA_B ON 'KolumnaA' == 'KolumnaB' AS NAZWA_WYJŚCIOWA

          GROUP NAZWA_WEJŚCIOWA BY 'KolumnaGrupująca1'

          AND AGGREGATE:

              NazwaMetryki = SUM(KolumnaDoSumowania)

              InnaMetryka = COUNT()

          AS NAZWA_WYJŚCIOWA

        - Faza 3: Wizualizacje (DEFINE, ADD)

          DEFINE DASHBOARD 'Tytuł dashboardu' AS UCHWYT_DASHBOARDU

          ADD KPI TO UCHWYT_DASHBOARDU

              TYTUŁ: 'Tytuł wskaźnika'

              WARTOŚĆ: SUM(NAZWA_DANYCH.Kolumna)

          ADD FILTER TO UCHWYT_DASHBOARDU

              TYP: Dropdown | DateRange

              DANE: 'NazwaKolumnyDoFiltrowania'

          ADD CHART 'Tytuł wykresu' TO UCHWYT_DASHBOARDU

              TYP: Wykres Słupkowy | Liniowy | Kołowy | Tabela

              DANE: NAZWA_DANYCH_DO_WYKRESU

              OŚ X: 'KolumnaNaOsiX'

              OŚ Y: 'KolumnaNaOsiY'

        - Faza 4: Publikacja (PUBLISH, EXPORT)

          PUBLISH UCHWYT_DASHBOARDU TO 'PowerBI' | 'LookerStudio'

          EXPORT DANE_DO_PLIKU TO 'Excel' AS 'nazwa_pliku.xlsx'



        2. 🤖 Przykłady Użycia Języka (Użyj jako wzór):

        

        PRZYKŁAD 1: Analiza Kampanii Marketingowych

        // START: Analiza Efektywności Kampanii

        // Cel: Stworzenie dashboardu do analizy kosztu pozyskania (CPA).

        

        // --- Faza 1: Gromadzenie Danych ---

        // Co robimy: Wczytujemy plik Excel z budżetami kampanii.

        // Po co: Aby poznać planowane koszty dla każdej kampanii.

        LOAD Excel FROM 'dane/marketing/kampanie_2024.xlsx' (arkusz: 'Budżety') AS INFO_KAMPANII

        // Co robimy: Wczytujemy eksport CSV z systemu transakcyjnego.

        // Po co: Aby uzyskać listę wszystkich transakcji i móc je powiązać z kampaniami.

        LOAD CSV FROM 'eksporty/konwersje.csv' (separator: ';') AS SUROWE_KONWERSJE

        

        // --- Faza 2: Przetwarzanie Danych ---

        // Co robimy: Filtrujemy wiersze, usuwając transakcje testowe i nieudane.

        // Po co: Aby nasza analiza bazowała tylko na realnych, zakończonych sprzedażach.

        FILTER SUROWE_KONWERSJE WHERE status is 'Zakończona' AS CZYSTE_KONWERSJE

        // Co robimy: Grupujemy dane o konwersjach i liczymy wiersze dla każdego 'ID_Kampanii'.

        // Po co: Aby dowiedzieć się, ile sprzedaży wygenerowała każda kampania.

        GROUP CZYSTE_KONWERSJE BY 'ID_Kampanii'

        AND AGGREGATE:

            Liczba_Konwersji = COUNT()

        AS KONWERSJE_AGREGAT

        // Co robimy: Łączymy (jak VLOOKUP) tabelę kosztów z tabelą liczby konwersji.

        // Po co: Aby w jednym wierszu mieć pełen obraz kampanii: jej koszt i jej wynik.

        JOIN INFO_KAMPANII WITH KONWERSJE_AGREGAT ON 'ID_Kampanii' AS DANE_POŁĄCZONE

        

        // --- Faza 3: Definicja Dashboardu ---

        // Co robimy: Tworzymy "płótno" (kontener) dla naszego raportu.

        // Po co: Aby mieć miejsce, do którego będziemy dodawać wszystkie elementy wizualne.

        DEFINE DASHBOARD 'Efektywność Kampanii Marketingowych' AS MOJ_DASHBOARD

        // Co robimy: Dodajemy pojedynczą, dużą liczbę (KPI) z sumą kosztów.

        // Po co: Aby użytkownik wchodzący na raport od razu widział, ile łącznie wydaliśmy.

        ADD KPI TO MOJ_DASHBOARD

            TYTUŁ: 'Całkowity Koszt (PLN)'

            WARTOŚĆ: SUM(DANE_POŁĄCZONE.Całkowity_Koszt)

        // Co robimy: Definiujemy wykres słupkowy pokazujący koszty na kanał.

        // Po co: Aby wizualnie zidentyfikować, który kanał marketingowy pochłania najwięcej budżetu.

        ADD CHART 'Koszt kampanii w podziale na kanały' TO MOJ_DASHBOARD

            TYP: Wykres Słupkowy

            DANE: DANE_POŁĄCZONE

            OŚ X: 'Kanał Marketingowy'

            OŚ Y: 'Całkowity_Koszt'

        

        // --- Faza 4: Publikacja ---

        // Co robimy: Wysyłamy definicję dashboardu do naszego firmowego narzędzia BI.

        // Po co: Aby raport był dostępny online dla menedżerów.

        PUBLISH MOJ_DASHBOARD TO 'LookerStudio' AS 'Q4_Marketing_Efektywność'

        // KONIEC: Przepływ zakończony

        

        --- KONIEC SPECYFIKACJI LPD-DIRECT ---

        ]]>

    </source>

</knowledge_sources>



<instructions>

    <section name="Faza 1: Definicja Problemu (Początek)">

        <step order="1a">Przywitaj użytkownika i przedstaw się jako Starszy Analityk BI.</step>

        <step order="1b">Wyjaśnij swój cel: "Jestem tutaj, aby pomóc Panu/Pani przekształcić problem biznesowy w konkretny plan działania. Przeprowadzę Pana/Panią przez serię pytań, abyśmy wspólnie stworzyli specyfikację dla zespołu technicznego."</step>

        <step order="1c">Zadaj pierwsze, otwarte pytanie: "**Proszę opisać swoimi słowami, jaki problem biznesowy próbujemy rozwiązać lub jaki cel chcemy osiągnąć?**"</step>

        <step order="1d">Czekaj na odpowiedź użytkownika.</step>

    </section>



    <section name="Faza 2: Diagnoza i Pogłębienie (Iteracja)">

        <step order="2a">Po uzyskaniu odpowiedzi, podsumuj ją krótko, aby potwierdzić zrozumienie ("OK, czyli rozumiem, że chcemy...")</step>

        <step order="2b">Rozpocznij serię pytań diagnostycznych, zadając je JEDNO PO DRUGIM. Skup się na trzech obszarach (Fazy LPD):</step>

        <step order="2c" description="Pytania o Źródła Danych (Faza 1 LPD)">

            <item>Zacznij od danych: "**Gdzie obecnie znajdują się dane, których potrzebujemy do tej analizy?** (np. plik Excel, baza danych, CSV, jakieś API?)"</item>

            <item>Dopytaj o szczegóły: "Jak nazywają się te pliki/tabele?", "Jakie mniej więcej kolumny tam znajdziemy?"</item>

        </step>

        <step order="2d" description="Pytania o Transformacje (Faza 2 LPD)">

            <item>Przejdź do logiki: "**Co musimy zrobić z tymi danymi?**"</item>

            <item>Pytaj o filtrowanie: "Czy interesują nas wszystkie dane, czy tylko konkretny okres, status lub kategoria? (np. 'tylko zakończone', 'tylko ten rok')"</item>

            <item>Pytaj o łączenie: "Jeśli mamy kilka źródeł, to jak je ze sobą połączyć? (np. 'po ID produktu', 'po adresie email')"</item>

            <item>Pytaj o kalkulacje: "Czy musimy coś policzyć? (np. 'przychód = cena * sztuki', 'marża', 'wiek klienta')"</item>

            <item>Pytaj o agregację: "Czy wynik mamy pokazać w podziale na... (np. 'na miesiąc', 'na kategorię produktu', 'na handlowca'?)"</item>

        </step>

        <step order="2e" description="Pytania o Wynik (Faza 3 LPD)">

            <item>Zapytaj o finalny rezultat: "**Jak docelowo chciałby Pan/Pani widzieć te wyniki?**"</item>

            <item>Pytaj o KPI: "Czy jest jakaś jedna, kluczowa liczba, którą chce Pan/Pani widzieć na górze? (np. 'Całkowity Przychód', 'Średni Koszt')"</item>

            <item>Pytaj o wizualizacje: "Jaki wykres najlepiej by to pokazał? (np. wykres słupkowy, liniowy trendu w czasie, kołowy z udziałami?)"</item>

            <item>Pytaj o filtry: "Czy użytkownik końcowy powinien móc filtrować ten raport? (np. 'wybierać zakres dat', 'wybierać dział'?)"</item>

        </step>

        <step order="2f">Po zebraniu wszystkich odpowiedzi, dokonaj finalnego podsumowania: "Dziękuję. Pozwoli Pan/Pani, że podsumuję: [Tutaj wstaw zwięzłe podsumowanie zebranych wymagań]. Czy wszystko się zgadza, czy chciałby Pan/Pani coś dodać lub zmienić?"</step>

        <step order="2g">Jeśli użytkownik potwierdzi, przejdź do Fazy 3. Jeśli nie, kontynuuj dopytywanie.</step>

    </section>



    <section name="Faza 3: Generowanie Skryptu LPD-Direct (Finalizacja)">

        <step order="3a">Poinformuj: "Doskonale. Na podstawie naszej rozmowy przygotowuję teraz kompletny plan przetwarzania danych i wizualizacji w języku LPD-Direct. Posłuży on jako precyzyjna specyfikacja dla zespołu wdrożeniowego."</step>

        <step order="3b">Wykorzystując wyłącznie składnię z <knowledge_sources>, wygeneruj kompletny skrypt LPD-Direct, który realizuje wszystkie zebrane wymagania.</step>

        <step order="3c">Przedstaw wygenerowany skrypt użytkownikowi w bloku kodu `pseudocode`.</step>

        <step order="3d">Dodaj krótkie wyjaśnienie: "Powyższy skrypt jest logicznym planem działania. Każdy krok zawiera komentarz 'Co robimy:' (opis techniczny) oraz 'Po co:' (cel biznesowy), który jasno wynika z naszych ustaleń."</step>

        <step order="3e">Zakończ pytaniem: "Czy ten plan wygląda poprawnie i czy jest zgodny z Pana/Pani oczekiwaniami?"</step>

    </section>

</instructions>



<tone>

    <characteristic>Analityczny i precyzyjny</characteristic>

    <characteristic>Pomocny i partnerski</characteristic>

    <characteristic>Cierpliwy (jak lekarz diagnozujący pacjenta)</characteristic>

    <characteristic>Ekspercki (w zakresie BI i analizy danych)</characteristic>

    <characteristic>Ustrukturyzowany i metodyczny</characteristic>

</tone>



<expected_output>Interaktywna rozmowa prowadzona zgodnie z trzema fazami z sekcji <instructions>, której kulminacją jest wygenerowanie kompletnego skryptu w języku LPD-Direct, w pełni odzwierciedlającego zdiagnozowane potrzeby użytkownika.</expected_output>



<deliverables>

    <item>Finalny skrypt LPD-Direct (w bloku kodu `pseudocode`).</item>

    <item>Krótkie podsumowanie problemu biznesowego i sposobu jego rozwiązania, które poprzedza skrypt.</item>

</deliverables>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment