# ARCHITECTURE ## Zakres - Dokument opisuje aktualna architekture kodu (stan repo: 2026-04-19). - Zrodlem prawdy sa: `src/`, `routes/web.php`, `database/migrations/`. ## Warstwy systemu - `Core`: bootstrap aplikacji, router, request/response, sesja, template, migrator, logger. - `Modules/*Controller`: obsluga requestow HTTP i walidacja wejscia. - `Modules/*Repository`: dostep do danych przez PDO/Medoo (prepared statements). - `Modules/*Service`: logika domenowa i integracje zewnetrzne. - `Cron`: runner, schedulery i handlery jobow okresowych. ## Moduly domenowe - `Auth`: logowanie, wylogowanie, middleware sesyjne. - `Users`: zarzadzanie uzytkownikami panelu. - `Orders`: lista, szczegoly, statusy, platnosci reczne, preview, quick search. - `Shipments`: przygotowanie, tworzenie, status trackingu, etykiety, usuwanie, paczki reczne. - `Accounting`: paragony i eksport ksiegowy. - `Email`: wysylka i preview wiadomosci z resolverem zmiennych i zalacznikow. - `Automation`: reguly event-condition-action, historia wykonan. - `Settings`: konfiguracja statusow, integracji, cron, skrzynek, szablonow, drukowania, mapowan projektow. - `Printing`: API kolejkowania wydruku i klucze API dla klienta desktop. - `Statistics`: raporty i agregacje dzienne zamowien z filtrowaniem po datach, kanalach i grupach statusow. - `Cron`: synchronizacje integracji i zadania utrzymaniowe. - `Info`: endpoint diagnostyczny `/info`. ## Kluczowe klasy i odpowiedzialnosci - `App\Core\Application`: bootstrap, dispatch requestu, opcjonalny web-cron z lockiem DB. - `App\Modules\Cron\CronRunner`: pobiera kolejke jobow z `cron_schedules/cron_jobs` i wykonuje handlery. - `App\Modules\Cron\CronHandlerFactory`: sklada zaleznosci i mapuje `job_type -> handler`. - `App\Modules\Orders\OrdersController`: flow UI zamowien + endpointy AJAX; `buildCustomerRiskInfo/composeCustomerRiskText` skladaja alert klienta ze zwrotami do widoku `orders/show`. - `App\Modules\Orders\OrdersRepository`: query listy/szczegolow zamowien, update statusow, activity log; `customerReturnedCountSubquerySql` generuje correlated subquery dopasowujaca historyczne zamowienia klienta po email/phone/name z paczka `returned` (self-exclusion). - `App\Modules\Shipments\ShipmentController`: flow przesylek i etykiet. - `App\Modules\Shipments\ShipmentPackageRepository`: CRUD paczek + `findReturnedByCustomer(customer, excludeOrderId)` zwraca liste zwroconych paczek klienta dla bannera ryzyka w szczegolach zamowienia. - `App\Modules\Shipments\ShipmentProviderRegistry`: wybor providera wysylki po `provider_code`. - `App\Modules\Printing\PrintApiController`: endpointy kolejki wydruku (session/api-key). - `App\Modules\Automation\AutomationService`: trigger eventow, ewaluacja warunkow, wykonanie akcji. - `App\Modules\Settings\ProjectMappingController`: CRUD mapowania produkt -> skrypt generacji projektu. - `App\Modules\Statistics\OrdersStatisticsController`: endpoint `/statistics/orders`, walidacja filtrow i przygotowanie modelu tabeli. - `App\Modules\Statistics\OrdersStatisticsRepository`: agregacje SQL dzienne (`COUNT`, `SUM total_net`, `SUM total_with_tax`) i mapowanie filtrow kanal/status-group. ## Integracje zewnetrzne - Allegro: OAuth, import zamowien, sync statusow push/pull, mapowania statusow i dostaw. - shopPRO: import zamowien, sync statusow push/pull, sync platnosci, mapowania statusow i dostaw. - Apaczka: konfiguracja API, tworzenie i tracking przesylek. - InPost: konfiguracja API, tworzenie i tracking przesylek. ## Glowny przeplyw HTTP - Request -> `Router` -> middleware (`AuthMiddleware` lub `ApiKeyMiddleware`) -> Controller. - Controller waliduje dane i CSRF, wywoluje Repository/Service. - Response: HTML (widoki) albo JSON (endpointy AJAX/API). ### Przeplyw Statystyk Zamowien - Route: `GET /statistics/orders` (wymaga sesji uzytkownika). - Controller: - parsuje `date_from`, `date_to`, `channels[]`, `status_groups[]`, - ustawia domyslne grupy statusow (wszystkie poza grupa `anulowane`), - pobiera agregaty dzienne z repozytorium, - buduje tabele z dynamicznymi kolumnami kanalow i stopka `Razem`. - Repository: - liczy kanaly jako `allegro` oraz `shoppro:{integration_id}`, - dla statusu efektywnego allegro stosuje mapowanie `allegro_order_status_mappings`, - zwraca zagregowane rekordy dzien/kanal. ## Glowny przeplyw Cron - Trigger: - `GET /cron` (public token) lub web-cron w `Application::maybeRunCronOnWeb`. - `CronRunner::run(limit)` przetwarza aktywne zadania. - Obslugiwane joby: - `allegro_token_refresh` - `allegro_orders_import` - `allegro_status_sync` - `shoppro_orders_import` - `shoppro_order_status_sync` - `shoppro_payment_status_sync` - `shipment_tracking_sync` - `automation_history_cleanup` - `order_status_aged` ## Automatyzacja - Triggerowana z wielu miejsc (m.in. zmiana statusu, przesylki, platnosci, wystawienie paragonu, cron age). - `AutomationService`: - wyszukuje aktywne reguly po `event_type`, - sprawdza warunki, - wykonuje akcje (`send_email`, `issue_receipt`, `update_shipment_status`, `update_order_status`), - zapisuje wynik do `automation_execution_logs`. - Warunek `order_status` czyta status z kontekstu eventu: - `new_status` dla eventow zmianowych (`order.status_changed`), - `current_status` dla eventu czasu w statusie (`order.status_aged`). - Akcja `send_email` ma opcjonalna flage `send_once_per_order`: - konfiguracja trzymana w `automation_actions.action_config`, - deduplikacja oparta o `automation_email_once_deliveries` (`rule_id + action_id + order_id` UNIQUE), - wpis "wyslano raz" zapisywany tylko po udanej wysylce (`EmailSendingService::send(...)->success = true`). ## Shipment tracking — mapowanie statusow kuriera - `ShipmentTrackingHandler` (job `shipment_tracking_sync`) iteruje po aktywnych paczkach i pobiera status z API przewoznika (`Inpost/Apaczka/AllegroTrackingService`). - Serwisy zwracaja `{status, status_raw, description}`, gdzie `status` pochodzi z `DeliveryStatus::normalize($provider, $raw)` (hardcoded PROVIDER_MAPS). - Handler na starcie wczytuje overrides z `delivery_status_mappings` (raz per uruchomienie) i po kazdym wyniku stosuje `DeliveryStatus::normalizeWithOverrides()` — pozwala to przypisac nowe raw statusy kuriera przez UI bez zmian w kodzie. - Strona `/settings/delivery-status-mappings`: - Pokazuje defaulty + overrides + sekcje „Niezmapowane statusy wykryte w systemie" (distinct raw statusy z `shipment_packages` nie wystepujace w defaultach ani overrides). - Bulk form zapisuje do `delivery_status_mappings` (override = normalized inny niz default LUB raw nie ma defaultu). - Badge w sidebar pokazuje sumaryczna liczbe niezmapowanych statusow (`DeliveryStatusMappingRepository::countAllUnmappedForBadge`). - Przy zmianie normalized status (previous != new) handler wywoluje `automation.trigger('shipment.status_changed', ...)`. ## Printing - Panel tworzy job `print_jobs` przez `/api/print/jobs`. - Klient desktop pobiera pending joby przez API key. - Klient pobiera etykiete i zamyka job przez `/complete`. - Konfiguracja i zarzadzanie kluczami: `PrintSettingsController` + `print_api_keys`. ## Projekt generation - `project_mappings` mapuje wzorzec nazwy produktu na `script_name` i `output_dir`. - `order_items.project_generated` i `project_generated_at` trzymaja status wygenerowania artefaktu. - UI konfiguracji: `/settings/project-mappings`. ## Bezpieczenstwo - Session auth dla panelu. - API key auth dla zdalnego klienta druku. - CSRF dla POST w panelu. - Sekrety integracji szyfrowane przez `IntegrationSecretCipher`. ## Zaleznosci miedzy modulami - `Orders` korzysta z `Automation`, `Email`, `Printing`, `Shipments`, `Settings`. - `Shipments` korzysta z `Orders`, `CompanySettings`, `Automation`. - `Cron` spina `Settings`, `Orders`, `Shipments`, `Automation`, `Email`. - `Automation` korzysta z `Orders`, `Email`, `Accounting`, `Shipments`.