Files
orderPRO/.claude/commands/wygeneruj-projekty.md
2026-04-13 00:59:41 +02:00

19 KiB
Raw Blame History

Generowanie projektów graficznych z zamówień

Jesteś silnikiem generowania projektów graficznych dla zamówień w orderPRO. Twoje zadanie to znaleźć zamówienia wymagające generacji, zinterpretować dane klienta i uruchomić odpowiedni skrypt.

Przepływ

1. Połącz się z bazą danych

Wczytaj dane z pliku .env w katalogu projektu:

  • DB_HOST_REMOTE — host bazy (użyj remote, nie localhost)
  • DB_DATABASE, DB_USERNAME, DB_PASSWORD, DB_PORT

Użyj "C:/xampp/mysql/bin/mysql.exe" do zapytań (z flagą --default-character-set=utf8mb4).

2. Pobierz aktywne mapowania

SELECT id, product_name_pattern, script_name, output_dir, requires_photo
FROM project_mappings
WHERE is_active = 1;

Jeśli brak mapowań — poinformuj użytkownika i zakończ.

3. Znajdź zamówienia do generacji (z dopasowaniem do mapowań)

Schemat bazy danych — kluczowe kolumny:

  • orders.status_code — aktualny kod statusu wewnętrznego orderPRO
  • order_statuses.code — kody statusów, wiązanie: orders.status_code = order_statuses.code
  • order_statuses.group_idorder_status_groups.id — grupy statusów
  • order_items.original_name — nazwa produktu
  • order_items.personalization — dane personalizacji (plain text, linie oddzielone \n)
  • order_items.project_generated — 0 = nie wygenerowano, 1 = wygenerowano
  • order_addresses.address_type — typ adresu ('customer', 'delivery', 'invoice')
  • order_addresses.name — pełne imię i nazwisko kupującego

Jedno zapytanie łączy zamówienia z mapowaniami (JOIN eliminuje produkty bez mapowania):

SELECT 
    oi.id AS item_id,
    oi.original_name AS product_name,
    oi.personalization,
    oi.quantity,
    o.id AS order_id,
    o.internal_order_number,
    o.status_code AS status_code,
    oa.name AS buyer_name,
    oa.email AS buyer_email,
    pm.script_name,
    pm.output_dir,
    pm.requires_photo
FROM order_items oi
JOIN orders o ON oi.order_id = o.id
JOIN order_statuses os ON o.status_code = os.code
JOIN order_status_groups osg ON os.group_id = osg.id
JOIN project_mappings pm ON pm.is_active = 1
  AND oi.original_name = pm.product_name_pattern
LEFT JOIN order_addresses oa ON o.id = oa.order_id AND oa.address_type = 'customer'
WHERE osg.id = 2
  AND oi.project_generated = 0
  AND oi.personalization IS NOT NULL
  AND oi.personalization <> ''
ORDER BY o.id;

Jeśli brak wyników — poinformuj użytkownika że nie ma zamówień do generacji pasujących do aktywnych mapowań.

5. Zinterpretuj dane klienta (AI normalizacja)

Dla każdego pasującego produktu:

  • Przeczytaj pole personalization z order_items
  • Zinterpretuj dane kontekstowo. Typowe dane to:
    • Imię żeńskie i męskie — mogą być w formacie "Kasia i Tomek", "Imiona: Kasia, Tomek", "Imię żeńskie: Kasia\nImię męskie: Tomek", "Imiona młodej pary: Kasia i Tomek", itp.
    • Data uroczystości — format DD.MM.YYYY, może być opisana jako "Data: 30.04.2026" lub "Data uroczystości: 30.04.2026" lub po prostu "30.04.2026"
    • Życzenia — opcjonalny tekst (np. "Na zdrowie!", "Dziękujemy!"). Jeśli brak — zostaw domyślne z szablonu
    • Ignoruj pola takie jak "Kolor tekstu", "Zakrętka" — te dotyczą produkcji, nie projektu
  • Nazwa klienta (do nazwy pliku wyjściowego) — z order_addresses.name (pole buyer_name w zapytaniu)

WAŻNE — semantyczny podział pola "Kto składa życzenia" na naglowek + od_kogo:

Pole Kto składa życzenia w personalizacji klienta NIE jest jednoznacznie = --od-kogo. Szablony pudełek chrzest/komunia mają dwa osobne teksty nad i pod życzeniami: naglowek (fraza życzeniowa, np. "Z najlepszymi życzeniami") oraz od_kogo (podpis, np. "Matka Chrzestna"). Klienci często wklejają w jedno pole frazę życzeniową + podpis — trzeba to semantycznie rozdzielić, bazując na znajomości języka polskiego.

Zasady:

  • Czysty podpis (krótki, typu "Twoja chrzestna", "Ciocia Gabi i wujek Filip", "Rodzice Chrzestni") → cały tekst jako --od-kogo, naglowek domyślny z szablonu.
  • Fraza życzeniowa + podpis (np. "Z miłością i modlitwą w dniu Chrztu Świętego Matka Chrzestna z rodziną") → podziel:
    • Część życzeniowa → --naglowek ("Z miłością i modlitwą w dniu Chrztu Świętego")
    • Podpis → --od-kogo ("Matka Chrzestna z rodziną")
  • Rola rodzinna + konkretne osoby (np. "Rodzice Chrzestni - Ciocia Ania i Wujek Wojtek") → zostaw jako całość w --od-kogo. "Rodzice Chrzestni" to rola, nie fraza życzeniowa.

Separatorem może być myślnik (, , -), nowa linia, dwukropek, przecinek, lub nic — decyduj semantycznie, nie mechanicznie.

Heurystyki rozpoznania frazy życzeniowej (→ naglowek):

  • zawiera słowa typu: "z miłością", "z modlitwą", "z najlepszymi życzeniami", "w dniu", "błogosławieństwa", "na pamiątkę"
  • ma charakter uroczysty, długości >20 znaków
  • nie wskazuje konkretnej osoby ani roli rodzinnej

Heurystyki rozpoznania podpisu (→ od_kogo):

  • role rodzinne: Matka/Ojciec Chrzestny, Rodzice Chrzestni, Ciocia, Wujek, Babcia, Dziadek
  • imiona własne, "z rodziną"

W razie wątpliwości — pokaż użytkownikowi obie interpretacje w planie (opcja A/B) i zapytaj, zamiast zgadywać.

WAŻNE — łączenie wielu pozycji jednego zamówienia w jeden plik (prośby o bycie chrzestnym):

Dla produktów mapujących się na skrypt prosba_chrzestny_*.py — szablon ma dwie ścianki (matka + ojciec) i skrypt akceptuje oba zestawy parametrów jednocześnie.

Kluczowa zasada: grupowanie po (order_id, script_name), nie po nazwie produktu. Produkty w bazie mają różne nazwy dla matki i ojca (np. "Akrylowa prośba o zostanie Ojcem Chrzestnym lustrzana złota - Dłonie" i "Akrylowa prośba o zostanie Matką Chrzestną lustrzana złota - Dłonie"), ale mapują się na ten sam skrypt. Dlatego mapowania w project_mappings muszą mieć OSOBNY wpis dla każdej nazwy produktu wskazujący na ten sam script_name.

Algorytm dla skryptów prosba_chrzestny_*:

  1. Po pobraniu listy zamówień pogrupuj pozycje po (order_id, script_name).
  2. Dla każdej grupy (jedno zamówienie + jeden skrypt):
    • Rozpoznaj po nazwie produktu lub treści personalizacji, która pozycja to ojciec, a która matka (słowa-klucze: "Ojcem Chrzestnym", "Wujku", "moim" → ojciec; "Matką Chrzestną", "Ciociu", "moją" → matka).
    • --imie-dziecka jest wspólne — wyciągnij z personalizacji (zwykle jedno imię dziecka powtarza się w obu pozycjach).
    • --matka-wolacz / --ojciec-wolacz — z odpowiadających pozycji.
    • Uruchom skrypt raz z obydwoma parametrami.
  3. Wygenerowany zostanie jeden plik PSD zawierający obie karty na A3.
  4. Oznacz obie pozycje order_items jako project_generated = 1 po sukcesie (update po id IN (item_id_matka, item_id_ojciec)).

Pozostałe przypadki:

  • 1× matka + 1× ojciec → jeden plik z obojgiem.
  • tylko 1× matka → jeden plik z samą matką (DP ukryty).
  • tylko 1× ojciec → jeden plik z samym ojcem (DL ukryty).
  • 2× ta sama strona (np. 2× matka) → jeden plik z matką; quantity decyduje o liczbie wydruków, nie liczba plików PSD; oznacz obie pozycje jako generowane.

Przykład (OP000000385): 2 pozycje — Akrylowa prośba o zostanie Ojcem Chrzestnym... (Wujku Adi, Laura) + Akrylowa prośba o zostanie Matką Chrzestną... (Ciociu Dario, Laura). Wynik: JEDEN plik Natalia Kwapisz.psd z --imie-dziecka "Laura" --ojciec-wolacz "Wujku Adi" --matka-wolacz "Ciociu Dario".

Rozpoznawanie matka/ojciec — po treści personalizacji, NIE po nazwie produktu:

Klienci często mylą się przy wyborze produktu i zamawiają np. 2× "Matką Chrzestną", ale w personalizacji jedna z pozycji ma treść męską ("Wujku..."). Nie sugeruj się nazwą produktu — analizuj treść personalizacji i rozpoznaj:

  • "Wujku [imię]", "Wujek", "moim Ojcem", "Ojcem Chrzestnym"ojciec (--ojciec-wolacz)
  • "Ciociu [imię]", "Ciocia", "moją Matką", "Matką Chrzestną"matka (--matka-wolacz)

Jeśli w jednym zamówieniu klient wybrał 2× ten sam produkt, ale personalizacje wskazują na matkę + ojca — zinterpretuj jako 1 plik z obojgiem chrzestnych.

Normalizacja wołaczy — klient podaje tylko imię w mianowniku:

Szablon oczekuje formy typu "Ciociu Kasiu" / "Wujku Darku" (prefiks roli + wołacz imienia). Jeśli klient podał tylko imię w mianowniku (np. "Imię cioci: Paulina", "Wujek: Dawid", "Ciocia: Julia") — automatycznie przekształć:

  1. Z imienia w mianowniku utwórz wołacz polski (Paulina → Paulino, Dawid → Dawidzie, Julia → Julio, Kasia → Kasiu, Darek → Darku, Michał → Michale, Ola → Olu, itd.).
  2. Dodaj prefiks roli: "Ciociu " dla matki, "Wujku " dla ojca.
  3. Finalny format: "Ciociu Paulino", "Wujku Dawidzie", "Ciociu Julio".

Wyjątek: Jeśli klient wyraźnie pisze że ma być bez zwrotu (np. "bez Ciociu", "tylko imię", "samo imię"), wtedy wstawiaj surowe imię bez prefiksu. W każdym innym przypadku — zawsze dodawaj Ciociu/Wujku.

Jeśli klient już podał pełną formę ("Ciociu Paulino", "Wujku Dawidzie") — zostaw dosłownie, nie modyfikuj.

Te reguły (rozpoznawanie płci po treści + auto-wołacz) są domyślne — NIE pytaj użytkownika za każdym razem, tylko raportuj w planie co zrobiono (oryginał → przekształcenie), żeby mógł zweryfikować.

WAŻNE — zaproszenia akrylowe (skrypt zaproszenie_chrzest_*.py):

Szablon ma 4 ścianki na A3 (DP, DL, GP, GL) — 4 zaproszenia na arkusz. Wspólne dla wszystkich ścianek: imię dziecka, miejsce_data, poczęstunek. Różne: od_kogo (każda ścianka = jedna osoba zapraszana).

Grupowanie wielu pozycji zamówienia (analogicznie do próśb o chrzestnego):

W jednym zamówieniu może być kilka pozycji tego samego (lub mapującego się na ten sam skrypt) produktu zaproszeń. NIE generuj pliku per pozycja. Zasady:

  1. Pogrupuj pozycje po (order_id, script_name).
  2. Dla każdej grupy zbierz wszystkie osoby zapraszane ze wszystkich pozycji (z personalization każdej pozycji, + uwzględnij quantity jeśli klient w jednej pozycji podał wiele osób z quantity > 1).
  3. Połącz w jedną listę od_kogo.
  4. Wspólne dane (imię dziecka, miejsce_data, poczęstunek) — wyciągnij raz, z pierwszej pozycji (powinny być identyczne we wszystkich pozycjach grupy, jeśli nie — zapytaj użytkownika).
  5. Zastosuj batching po 4: podziel listę od_kogo na partie po 4 i wywołaj skrypt N razy z numerowanymi nazwami plików.
  6. Po sukcesie oznacz wszystkie pozycje grupy jako project_generated = 1.

Batching przy quantity > 4: 1 plik PSD = max 4 zaproszenia. Jeśli klient zamawia więcej osób (np. 17 zaproszeń), silnik dzieli listę na partie po 4 i wywołuje skrypt wielokrotnie z numerowanymi nazwami plików:

  • 17 zaproszeń → 5 plików: Klient 01.psd (4), Klient 02.psd (4), Klient 03.psd (4), Klient 04.psd (4), Klient 05.psd (1).
  • 4 zaproszenia → 1 plik Klient.psd (bez numeracji).
  • 6 zaproszeń → 2 pliki: Klient 01.psd (4) + Klient 02.psd (2).

Numerowanie nadawane przez silnik (nie przez skrypt). Zderzenia nazw w _gotowe/ są rozstrzygane normalnym sufiksem.

Interpretacja skrótowej personalizacji klienta:

Klienci wpisują dane skrótowo, trzeba je rozwinąć patrząc na oryginalne placeholdery w szablonie. Przykłady:

Wejście klienta:

Imię dziecka: Teodor Surma
Imię i nazwisko proszonego gościa: Matkę Chrzestną Wiktorię Igras
na Chrzest Święty w Parafia pw. Świętej Jadwigi Śląskiej w Hedwiżynie 45A
Data i godzina: 18 Kwiecień 2026 Godzina 13.00
Miejsce przyjęcia: "Kresovia Biłgoraj - Sala Balowa, Okrągłe 1C, 23-400 Biłgoraj"

Przekształcenie na parametry skryptu:

  • --imie-dziecka "Teodora" (mianownik "Teodor" → dopełniacz, bo szablon: "uroczystość przyjęcia Sakramentu Chrztu Świętego [kogo?] Teodora")
  • --miejsce-data "W dniu 18.04.2026\ro godzinie 13:00\rParafia pw. Świętej Jadwigi Śląskiej\rw Hedwiżynie 45A" (format jak w oryginale: "W dniu DD.MM.RRRR o godzinie HH:MM\rParafia...\rulica")
  • --poczestunek "Po uroczystości serdecznie zapraszamy\rna poczęstunek do Kresovia Biłgoraj - Sala Balowa\rOkrągłe 1C, 23-400 Biłgoraj" (format jak w oryginale)
  • --od-kogo-1 "Matkę Chrzestną Wiktorię Igras" (poprawiam literówki "Chszestną" → "Chrzestną")

Zasady rozwijania danych:

  • Daty: "18 Kwiecień 2026 Godzina 13.00""W dniu 18.04.2026\ro godzinie 13:00" (miesiąc po polsku → numer, "Godzina 13.00" → "o godzinie 13:00", dodany prefiks "W dniu").
  • Parafia: "Parafia pw. X w Y 45A" → zostaw bez zmian, złącz łamaniem linii w logiczne miejsca.
  • Miejsce przyjęcia: osadź w formule "Po uroczystości serdecznie zapraszamy na poczęstunek do [NAZWA]\r[ULICA, KOD MIASTO]".
  • Imię dziecka: zawsze dopełniacz (szablon: "Chrztu Świętego [kogo?]").
  • Literówki klienta ("Chszestną""Chrzestną", "Chszestnego""Chrzestnego") — poprawiaj automatycznie.
  • Nazwisko zapraszanego gościa: zostaw w formie jaką podał klient (nie odmieniaj jeśli nie jesteś pewny).

Jeśli klient nie podał czegoś (np. brak miejsca przyjęcia = brak poczęstunku) → --poczestunek pomiń, warstwa zostanie ukryta.

Formatowanie daty — specyficzne dla szablonu:

Niektóre szablony mają nietypowy format daty (np. "10 | 05 | 2026" z pipe'ami). Skrypt przyjmuje datę dosłownie — silnik /wygeneruj-projekty musi przekształcić standardowy format klienta (DD.MM.RRRR lub DD-MM-RRRR) na format oczekiwany przez szablon, zanim wywoła skrypt.

Obecne wzorce formatów daty per skrypt:

  • pudelko_komunia_kwiaty_wzor2.py → format "DD | MM | RRRR" (np. "10 | 05 | 2026"). Silnik: "10.05.2026""10 | 05 | 2026".
  • pudelko_komunia_golabek_uv.py → format "DD | MM | RRRR" (np. "10 | 05 | 2026"). Silnik: "10.05.2026""10 | 05 | 2026".
  • Wszystkie pozostałe pudelko_komunia_*, pudelko_chrzest_*, buteleczki_slub_* → format "DD.MM.RRRR" (standardowy).

Dodaj nowe wzory tu, gdy będą tworzone nowe skrypty z nietypowymi formatami.

6. Przedstaw plan i generuj

Wyświetl tabelę z planem:

Zamówienie | Produkt | Imię żeńskie | Imię męskie | Data | Życzenia | Klient (nazwa pliku)
OP000123   | Buteleczka... | Kinga | Łukasz | 30.04.2026 | (domyślne) | Kinga Klimczak

Autonomia przy generowaniu:

  • Jeśli wszystkie interpretacje są jasne lub wątpliwości minimalne (rutynowe przekształcenia: dopełniacz imienia, format daty, auto-wołacz, podział naglowek/od_kogo zgodnie z regułami) → generuj od razu po wyświetleniu planu, bez pytania o potwierdzenie. Raportuj w planie co zostało przekształcone, żeby użytkownik mógł zweryfikować po fakcie.
  • Jeśli wątpliwość jest istotna (np. brakujące imię męskie w buteleczkach ślubnych, niejasne przypisanie matka/ojciec przy próśbach, dwuznaczny podział naglowek/od_kogo, dziwny format daty, klient wyraźnie pomylił produkt, treść zawierająca rażące dubluje lub sprzeczność między polami) → zatrzymaj się i zapytaj użytkownika, prezentując opcje.

Kierunkowskaz: "czy jestem pewny że wynik będzie akceptowalny?" Jeśli tak — jedź. Jeśli nie — pytaj.

7. Uruchom generowanie

Przed generowaniem sprawdź czy Photoshop jest uruchomiony:

tasklist //FI "IMAGENAME eq Photoshop.exe" 2>/dev/null | grep -i photoshop

Jeśli Photoshop nie jest uruchomiony — poinformuj użytkownika i poczekaj aż go uruchomi.

Pobranie zdjęcia od klienta (jeśli requires_photo = 1):

Dla mapowań z requires_photo = 1 przed wywołaniem generatora pobierz zdjęcie z poczty klienta:

python tools/generowanie/email_photo_fetcher.py --email "{buyer_email}" --out "C:/tmp/orderpro_photos" --days 365
  • Skrypt zwraca ścieżkę pobranego pliku albo komunikat BRAK (exit code 1).
  • Jeśli zdjęcie się pobrało — przekaż ścieżkę do generatora przez --zdjecie.
  • Jeśli zdjęcia nie znaleziono — generator i tak ma być wywołany bez --zdjecie (wstawi zielony placeholder jako sygnał "klient nie przysłał foto"). NIE blokuj generacji.
  • Zaraportuj w tabeli planu (kolumna "Zdjęcie") status: ścieżka / BRAK (zielony placeholder).

WAŻNE — rozpoznawanie płci dziecka (dla skryptów z parametrem --plec): Niektóre skrypty (np. akrylowe_podziekowanie_matka_chrzestna_wzor2.py) mają dwa warianty szablonu (chłopiec/dziewczynka) i wymagają parametru --plec m lub --plec k. Rozpoznaj płeć na podstawie personalizacji:

  • Imię proste (Fabian, Wojciech, Kacper → m; Blanka, Zosia, Wiktoria → k) — standardowa wiedza o polskich imionach.
  • Imię odmienione (np. "Wojtusia", "Kacpra" → m; "Blanki", "Zosi", "Wiktorii" → k) — rozpoznaj mianownik i z niego określ płeć.
  • Kontekst — jeśli w personalizacji pojawia się "mój Chrześniak", "Drogi Synku", "malutki" → m; "moja Chrześniaczka", "Droga Córeczko", "malutka" → k.
  • W razie wątpliwości — wyświetl surowe dane klientowi i zapytaj.

WAŻNE — łamanie linii w tekstach wielolinijkowych (życzenia, podziękowanie, itp.): Photoshop jako znak łamania linii w warstwach tekstowych rozpoznaje \r (CR), NIE \n (LF). Jeśli przekażesz \n, Photoshop wyświetli go jako śmieciowy kwadrat z literą "n". W bashu użyj ANSI-C quoting: $'linia1\rlinia2\rlinia3' do budowy wartości --zyczenia / --podziekowanie i przekaż ją w cudzysłowach do skryptu.

Dla każdego potwierdzonego produktu:

  1. Sprawdź kolizję nazwy pliku w katalogu wyjściowym. Jeśli plik {klient}.psd (lub inne rozszerzenie używane przez skrypt) już istnieje — dodaj do nazwy klienta sufiks z indeksem 01, 02, ... (np. Anna RakAnna Rak 01, a jeśli i to zajęte → Anna Rak 02). Inkrementuj aż znajdziesz wolną nazwę. Dopiero wtedy przekaż wynik jako --klient.
  2. Uruchom skrypt: python tools/generowanie/{script_name} --klient "Imię Nazwisko" ... (parametry zależne od skryptu — dla buteleczek/pudełek zwykle --imie/--imiona, --data, opcjonalnie --zyczenia/--podziekowanie; dla produktów ze zdjęciem dorzuć --zdjecie /sciezka/do/foto.jpg)
  3. Jeśli mapowanie ma output_dir — skrypt powinien zapisać tam (jeśli obsługuje)

8. Oznacz w bazie

Po udanym generowaniu:

UPDATE order_items 
SET project_generated = 1, project_generated_at = NOW() 
WHERE id = {item_id};

9. Raport końcowy

Wyświetl podsumowanie:

  • Ile projektów wygenerowano
  • Ile pominięto (brak mapowania, brak personalizacji)
  • Ewentualne błędy

Ważne zasady

  • Zawsze pytaj o potwierdzenie przed generowaniem
  • Photoshop musi być uruchomiony — sprawdź przed generowaniem
  • Nie oznaczaj jako wygenerowane jeśli skrypt zwrócił błąd
  • Jeśli nie potrafisz zinterpretować personalizacji — wyświetl surowe dane i zapytaj użytkownika
  • Skrypty generujące znajdują się w tools/generowanie/ w katalogu projektu orderPRO