Changelog
v0.3.5 — 2026-05-12
Honesty patch: order forward (Magento → Optima FA) jest wyłączone w v0.3.x i etykietowane jako "TBD v0.4.0".
Co się dzieje
Code review na potrzeby testu order forward ujawnił że OptimaSqlClient.ForwardOrderAsync zawsze zwracał stub "not implemented". Strona Magento przygotowywała payload, mikroserwis go odbierał, ale w Optimie żadna faktura nie powstawała. To była luka funkcjonalna której nie zauważyły rounduy 1/2/3 Gemini bo skupiały się na flow Optima → Magento.
Zamiast pretendować że to działa:
sync/orders_enableddefault OFF (było1w v0.3.4 i wcześniej). Świeże instalacje nie mają toggla "Yes".- Admin label zmieniony na "Wyslij zamowienia do Optimy (FA) [TBD v0.4.0]" + comment wyjaśniający że to no-op.
OrderForward::send()logujeWARNINGz napisem "no FA will be created in Optima" jeśli ktoś jednak włączy..NETPOST/v1/ordersdalej akceptuje payload, ale dodatkowo zrzuca go jako JSON doxml-out/obok exe — żeby v0.4.0 XML import scaffolding miał prawdziwe dane do testów.OptimaSqlClient.ForwardOrderAsyncma teraz zaktualizowany komentarz + clear "not implemented" reason w response.
Dlaczego to nie działa od razu
Tworzenie TraNag+TraElem przez raw SQL INSERT jest zablokowane przez Optima — integracyjny SQL login ma SELECT-only na CDN.TraNag, to standardowy security posture Optimy. Prawdziwy write-path wymaga:
- Opcja A (v0.4.0 plan):
.NETgeneruje XML w formacie Comarch Import, drop folder, operator klikaNarzędzia → Import dokumentów z XMLw Optimie. Bez COM, bez Optima Online licencji. Operator musi 1× kliknąć dziennie. - Opcja B (rozważane): Comarch Optima COM SDK / Optima Online API. Pełna automatyka ale wymaga osobnej licencji Optima Online + Polish-locale COM interop.
Pozostały zakres v0.3.x
- F0 Product sync ✓ (działa)
- F0 Stock sync ✓ (działa, multi-warehouse mapping na MSI)
- F0 Order forward ❌ NOT IMPLEMENTED (v0.4.0)
- F1 Multi-store pricing ✓ (działa)
- F2 Order updates Optima → Magento ✓ (działa, partial invoices/shipments)
- F3 Customer sync ✓ (działa, full-sync ze względu na KntKarty schema)
Inne odłożone do v0.3.5+
Po Gemini round 3 odłożone (znane, dokumentowane): - Bug #6: Time zone CET vs UTC drift - Bug #9: License hostname unstable w k8s/swarm
Po round 2 odłożone: - Idempotency edycji dokumentu Optimy → duplikat invoice w Magento
v0.3.4 — 2026-05-12
Trzeci round bug-fixów po Gemini Pro code-review (round 3). Tym razem skup na rzeczach które nie pokazują się na "happy path" ale biją tygodniami u płacącego klienta.
Naprawione (6 bugów)
-
Bug #4 — Race condition concurrent crons (MAJOR). Długi sync
SyncProductsmoże trwać 15 min, cron co 5 min → druga instancja startuje gdy pierwsza ciągle działa, obie czytają ten samlastRunAtkursor, race na zapisie. Naprawione:LockManagerInterface::lock()w każdym z 4 cron'ów (sync_products/stock/order_updates/customers). Drugi run loguje "skipped: previous run still active" i wychodzi cleanly. -
Bug #5 — Duplicate SKU w jednym order (MAJOR). Klient kupuje 2× ten sam produkt z różnymi opcjami customowymi → 2 line itemy z tym samym SKU w order. Stary
$bySku[$sku] = $oinadpisywał, droga partial-invoice obsługiwała tylko OSTATNIĄ pozycję. Naprawione: kolejka FIFO$bySku[$sku][]+ dystrybucja Optima qty po wszystkich matching liniach w kolejności. -
Bug #7 — HMAC + polskie znaki (MAJOR).
new StreamReader(body, leaveOpen:true)w .NET używa platformowego domyślnego encoding'u — na Windows w PL może to być cp1250 zamiast UTF-8. Body z polskimi znakami (np. "Brzęczyszczykiewicz") byłby uszkodzony → HMAC mismatch → 401. Naprawione: jawnienew StreamReader(body, Encoding.UTF8, detectEncodingFromByteOrderMarks: false, leaveOpen: true). -
Bug #8 — Wcześnie wysyłane zamówienia PayU/Przelewy24 (minor). Obserwator
sales_order_place_afterwysyłał zamówienie do Optimy DOPRZED autoryzacją płatności online. Anulowane płatności → "ghost order" w Optimie. Naprawione: tylko gdyorder->getState() in {processing, complete}. -
Bug #10 — ProductSync nadpisuje configurable/bundle/grouped (MAJOR). Optima zna tylko proste SKU. Jeśli operator stworzy w Optimie towar o kodzie pasującym do Magento configurable parent — stara wersja nadpisywała atrybuty parent'a, czasem tworzyła osierocone simple-products. Naprawione:
if ($product->getTypeId() !== 'simple' && !== 'virtual') return 'skipped'+ warning loga. -
Bug #11 — Shipment + Order save nietransakcyjnie (minor).
shipmentRepo->save() + orderRepo->save()w dwóch krokach — błąd między nimi (lock wait, disconnect) zostawia shipment w DB ale order ciągle "processing". Naprawione:TransactionFactory::addObject($shipment)->addObject($order)->save()— atomicznie, tak jak już robicreateInvoice.
Świadomie ODŁOŻONE do v0.3.5 / v0.4.0
Gemini zgłosił też 5 zagadnień które wymagają większej zmiany:
- Bug #1 — VAT mismatch (v0.4.0): Magento
prepareInvoice()przelicza tax wg własnych reguł, ignoruje kwoty z Optimy. Może powodować różnice groszowe w VAT. Wymaga override'u total fields poprepareInvoice()+ .NET musi zwrócićAmountNet,AmountVatper dokument. - Bug #2 — Brak credit memos (v0.4.0): Optima FK/WZK (faktury korygujące, zwroty) nie są mapowane na Magento Credit Memo. Duża luka funkcjonalna — całe nowe pole
type=credit_memow API + nowa ścieżkacreateCreditmemo(). - Bug #3 — Shipping cost na partial invoice (v0.4.0): Magento dolicza pełen koszt wysyłki do PIERWSZEJ faktury, niezależnie od jej rozmiaru. Może nie zgadzać się z FA z Optimy. Powiązane z #1.
- Bug #6 — Time zone CET vs UTC drift (v0.3.5): Optima
TrN_TS_Modtypudatetime(BEZ strefy), .NET używa UTC. Może gubić/duplikować dokumenty przy zmianie czasu (2× w roku). WymagaAT TIME ZONEw SQL + config TZ w appsettings. - Bug #9 — License hostname w k8s/swarm (v0.3.5):
Dns.GetHostName()zwraca losowy hostname kontenera. Każdy restart kontenera = inny hostname = licencja unieważniana. WymagaSisl:License:CanonicalHostw appsettings.
Znana stała limitacja idempotency-on-doc-edit
Jeśli operator EDYTUJE zatwierdzony dokument w Optimie (np. zmieni opis, doda komentarz), jego TrN_TS_Mod się zmieni i F2 zobaczy go ponownie → próba utworzenia DRUGIEGO Magento invoice/shipment dla tego samego dokumentu Optimy. To samo dzieje się jeśli operator zresetuje cursor F2 ręcznie. Workaround: nie edytuj zatwierdzonych dokumentów. Trwałe rozwiązanie (v0.4.0): tabela mapująca optima_doc_id → magento_invoice_id.
E2E zweryfikowane
- F1 (regression after #10):
created:0, updated:9, skipped:1, multi_store:[]— identycznie jak v0.3.3 ✓ - F2 (regression after #5, #11): partial invoice path dalej działa, partial qty correct ✓
- F3: tworzenie + update klienta TEST_QA — bez zmian ✓
- Cron locks: drugi cron w trakcie pierwszego daje
infolog i wychodzi - PHP syntax check + .NET build clean
v0.3.3 — 2026-05-12
Drugi round bug-fixów po code review przez Gemini Pro na shipped v0.3.2. Złapane 8 z 9 sugerowanych bugów, jeden bug już potwierdzony przez realny E2E test (Bug #7 InvoiceService — naprawione w v0.3.2).
Krytyczne naprawione
-
Bug #1+#2 (F2) CRITICAL — Częściowe faktury/wysyłki. Stara wersja przy WZ na 2 sztuki w Optimie (z 5 zamówionych w Magento) tworzyła w Magento wysyłkę na wszystkie 5, oznaczając całe zamówienie jako wysłane. Analogicznie dla faktur — częściowa FA w Optimie → pełna faktura w Magento → finansowy mismatch. Naprawione:
/v1/order-updateszwraca terazitems: [{sku, qty}]z CDN.TraElem; Magento buduje$qtysmap dlaInvoiceService::prepareInvoice($order, $qtys)iShipmentItem::setQty(). Comment Magento pokazuje(partial, N units)żeby operator wiedział. -
Bug #4 (F2+F3) MAJOR — Kursor advance'ował przy partial errors. Jeśli 5 z 100 aktualizacji się wywaliło, kursor dalej szedł do
runStartTs→ te 5 znikało na zawsze. Naprawione:record()nie advanc'uje kursora gdycount($errors) > 0— następny run powtarza okno. Trade-off: poison-pill (permanentnie zły rekord) blokuje wszystko za nim — operator musi ręcznie bumpnąć kursor (bin/magento config:set sisl_optima/state/order_updates_at $(date +%s)).
Major naprawione
- Bug #3 (F3) — Jednoczłonowa nazwa klienta = save crash. Optima
Knt_Nazwa1często ma tylko "ACME" lub "Tesco" →lastName()zwraca''→ Magentocustomer.lastname is required→ throw. Naprawione: placeholder.gdy brak surname'a. - Bug #6 (.NET) —
/v1/_debug/columnsujawniało schemat w prod. HMAC gating to defense, ale defense-in-depth = jeszcze feature flag. Teraz domyślnie wyłączone ("Sisl:Debug:Enabled": "true"w appsettings żeby włączyć). Dodany whitelist regex na nazwę tabeli. - Bug #7 (license) — Licencja sprawdzana tylko na starcie run(). Długi sync (np. 100k produktów × 30 min) kontynuował tworzenie faktur po wygaśnięciu licencji. Naprawione: re-check w pętli paginacji co 10 stron we wszystkich 3 serwisach (F1/F2/F3). LicenseChecker ma cache, więc to tani check.
- Bug #8 (.NET) —
UseDeveloperExceptionPage()w prod leaki stack trace. Naprawione: tylko w środowisku Development. W prod = generic 500 z trace_id + log.
Minor / dokumentacja
- Bug #9 —
Incrementalw nazwie endpointu myli. Endpoint robi full-sync ze względu na ograniczenia schematu KntKarty. URL/v1/customers/incrementalzostawiony (Magento client to woła) ale response ma terazsyncSemantics: "full"i komentarz w kodzie jest uczciwy.
Architektura
- DTO
OrderUpdateDtorozszerzony oItems: IReadOnlyList<OrderUpdateItemDto> - Drugi SQL query w
ListOrderUpdatesAsyncna CDN.TraElem (TrE_TrNId IN @ids) — N+1 unika ❌ (jeden query na całą stronę, NIE per header). buildItemQtysMap()w PHP mapuje Optima SKU → Magento order item ID z fallback'em na whole-order gdy items[] puste (backward compat z .NET v0.3.2).
E2E zweryfikowane na realnej Optimie CDN_SISL_TEST
Operator (manualnie w UI Optimy) utworzył FS/2/2026 z opisem MG-100000002 zawierającą 1 szt TEST_BUTY. W Magento order #100000002 miał 3 szt TEST_BUTY + 2 szt TEST_KAWA (łącznie 5 sztuk).
Po F2 sync:
- Magento invoice 000000002: 1 szt TEST_BUTY (224.99 zł) — NIE 5 sztuk
- order_status = "processing" (nie "complete" — wciąż 4 szt do zafakturowania)
- canInvoice() = true → kolejne FA w Optimie będą podchwytywane przyrostowo
- Comment: SISL Optima: linked to FS/2/2026 (partial, 1 units)
Znane limitacje (do v0.3.4)
- Idempotency dla edytowanych dokumentów Optimy: jeśli operator zmieni FS/2/2026 w Optimie po naszej synchronizacji, jego
TrN_TS_Modsię zmieni i F2 zobaczy go ponownie → próba utworzenia drugiej faktury Magento na to samo. canInvoice() po pierwszej fakturze będzie dla pozostałych 4 szt, więc Magento utworzy DRUGĄ fakturę na 1 szt. Workaround: nie edytuj zatwierdzonych dokumentów w Optimie. Docelowo: zmapować Optima doc_id → Magento invoice/shipment id w osobnej tabeli (v0.3.4).
v0.3.1 — 2026-05-12
Hotfix po v0.3.0 — wszystkie 3 funkcje (F1/F2/F3) miały bugi które wyszły dopiero na realnej Optimie 2024+ (testy z mockiem nic z tego nie pokazały). Funkcje były technicznie niezaorane.
Naprawione bugi
-
F1 #1 CRITICAL — Cichy no-op gdy
catalog/price/scope = Global(domyślne Magento).ProductRepository::save()zsetStoreId(N)pisał do globalnego scope-u, ale licznik raportowałupdated:N— operator widział "9 produktów zaktualizowanych" a w bazie zero website-scoped rzędów. Teraz: szybki check + jasny błąd: "ZmieńStores → Configuration → Catalog → Catalog → Price Scopena 'Website'". -
F2 #6 CRITICAL —
Invalid column name 'TrN_DataOst'. Kolumna nie istnieje w realnej Optimie 2024 — endpoint zwracał HTTP 500. Naprawione: użycieTrN_TS_Mod(faktyczny datetime cursor na TraNag, zweryfikowany przez INFORMATION_SCHEMA). -
F3 #5 CRITICAL —
Invalid column name 'Knt_TS_Mod'. Kolumna nie istnieje w realnej Optimie. Gorzej — KntKarty w ogóle nie ma kolumn datetime (Knt_LastModL/O/C to INT-y z ID operatora, nie znaczniki czasu; Knt_DataW/DataKarty to INT-y w starym formacie "dni od 1899-12-30"). Prawdziwy delta-sync niemożliwy na poziomie schematu. Naprawione: endpoint robi pełny full-scan na każdy tick. Idempotencja zachowana przez upsert-by-email po stronie Magento. -
F2 #2 MAJOR — Parser zbyt sztywny. Operator wpisujący
MG-100000051 dostawa pilnawTrN_Opispowodował że plugin szukał zamówienia100000051 dostawa pilnaw Magento → null → cichy skip. Naprawione: nowyextractIncrementId()bierze tylko[0-9A-Za-z_-]+z początku. -
F2+F3 #4 MAJOR — Luka w kursorze.
SyncState::record()zapisywałtime()na końcu syncu — wszystko zmodyfikowane w Optimie podczas trwającego polla (kilka minut) przepadało na zawsze (następny sync zaczynał od finish_time). Naprawione:record($kind, $summary, $atTs)accept'uje explicit timestamp; serwisy snapshot'ujątime()PRZED pollem i przekazują przy zapisie. -
F3 #3 — ORDER BY niestabilny.
ORDER BY Knt_Akronim(alfabetycznie) zamiast po cursorze. Naprawione:ORDER BY Knt_GIDNumer(monotoniczny, stabilny). -
F3 — Filtr
Knt_GIDTyp = 32zwracał zero. Konwencja "32 = klient" nie trzyma się Optima 2024. Naprawione: filtrKnt_EMail IS NOT NULL AND Knt_EMail <> '' AND Knt_Akronim NOT LIKE '!NIE%'(pomija placeholder i kartoteki bez maila).
Zweryfikowane na realnej Optimie (CDN_SISL_TEST)
/v1/customers/incremental— 200 OK ✓/v1/order-updates— 200 OK ✓- F1 happy-path (scope=Website) —
multi_store: hurt={updated:9}✓ - F1 fail-loud (scope=Global) — actionable error ✓
- Back-compat (wszystkie flagi OFF) — identyczne z v0.2 ✓
- Cursor advancement — zapisywany przy starcie, nie zakończeniu ✓
Limitacje znane
- Real F2/F3 happy-path wymaga ręcznego wprowadzenia danych w Optimie przez UI —
CDN.KntKartyto widok (nie da się UPDATE z innym schema),CDN.TraNagma read-only permission dla integracyjnego SQL loginu (zabezpieczenie Optimy). To są limitacje Optimy a nie pluginu. - F3 robi full-sync każdy tick — przy dużej bazie klientów (>10k) ustaw cron rzadko (raz na noc).
Update path
Pobierz Sisl_Optima-v0.3.1.zip z cdn.sisl.pl, podmień folder, bin/magento setup:upgrade && bin/magento cache:flush. Plus nowy .NET service binary (też v0.3.1).
v0.3.0 — 2026-05-11
Trzy duże opcjonalne funkcje — wszystkie domyślnie wyłączone. Klient włącza świadomie w Stores → Configuration → SISL → Optima Connector → 5. v0.3 — Funkcje rozszerzone (opt-in).
Nowe funkcje (opt-in, default OFF)
-
F1 — Multi-store mapping (per-website price overrides). Każdy website Magento może pobierać ceny z innego cennika Optimy + filtrować po innym prefiksie SKU. Format textarea (jedna linia per website):
Klucz tohurt=2:HURT- detal=1: partner=3:PARTNER-Website Codew Magento (Stores → All Stores → Website → Code). Ceny default scope nadal idą z głównej konfiguracji — multi-store nakłada się jako website-scoped layer. Włączasz w5. v0.3 → Multi-store: Enabled = Yes. -
F2 — Order updates (full order lifecycle). Cron pobiera z
/v1/order-updatesfaktury/PAR/WZ utworzone w Optimie, dopasowuje je po poluTrN_Opis(klient/handlowiec wpisuje tamMG-<increment_id>Magento) i tworzy w Magento odpowiednio Invoice (Magento → "Complete" lub "Processing") lub Shipment. Idempotentny: pomija order'y już zafakturowane / zashippowane. Włączasz w5. v0.3 → Order updates: Enabled = Yes+ ustawiaszOrder updates: Cron schedule(np.*/15 * * * *). -
F3 — Bidirectional customer sync. Cron pobiera z
/v1/customers/incremental?modifiedSince=<cursor>karty kontrahentów (CDN.KntKarty) zmodyfikowane od ostatniego polla i upsertuje je docustomer_entityw Magento (match po email + websiteId). Pierwszy poll = full sync (brak kursora); kolejne tylko delta. Włączasz w5. v0.3 → Customers: Enabled = Yes+ ustawiaszCustomers: Cron schedule.
Architektura
- Wszystkie 3 funkcje są pluginami nakładkowymi — wyłączone nie wpływają na zachowanie v0.2. Każdy serwis ma osobny enable flag (
sisl_optima/v03/*_enabled), separate cron config_path (puste = nigdy nie odpala), separate cursor wSyncState. - Server-side (.NET): dwa nowe endpointy
/v1/order-updates(czytaCDN.TraNagjoinem zTraElem, filtruje poTrN_DataOst >= since+TrN_Opis LIKE 'MG-%') i/v1/customers/incremental(filtrujeKnt_TS_Mod >= since). Mock backend wspiera obie — można testować bez Optimy. - Client-side (Magento): dwa nowe serwisy (
SyncOrderUpdates,SyncCustomers) + cron stuby.ProductSyncrozszerzony oapplyMultiStoreOverrides()które po głównej pętli iteruje overrides i zapisuje website-scoped prices przezProductRepository::save($product)z odpowiednimstoreId.
Wymagania
etc/module.xmlsetup_version:0.2.1→0.3.0→bin/magento setup:upgradewymagany.- Nowe DI deps w
ProductSync:StoreManagerInterface,WebsiteRepositoryInterface. Magento autowireuje — nie trzeba edytowaćdi.xml. - .NET service v0.3.0 wymagany dla F2 + F3 (stare v0.2 .exe nie ma endpointów — F2/F3 włączone na v0.2 service zwrócą 404, ale
multi_store(F1) działa też ze starą wersją service'u, bo używa tylko/v1/products).
Back-compat
- Update v0.2 → v0.3 bez zmian w config: wszystkie 3 flagi default OFF, identyczne zachowanie.
- Aktualne instalacje robią update przez: pobrać
Sisl_Optima-v0.3.0.zipzcdn.sisl.pl, podmienić folderapp/code/Sisl/Optima,bin/magento setup:upgrade && bin/magento cache:flush.
v0.2.1 — 2026-05-11
Hotfix tuż po v0.2.0:
/v1/stocksz parametrem?warehouse=Xzwracał 500 (Microsoft.Data.SqlClient:No mapping exists from object type System.String[] to a known managed provider native type). Dapper auto-expansionIN @listdlaIReadOnlyList<string>był niestabilny na .NET 8 + SqlClient. Naprawione:DynamicParametersz explicit@w0, @w1, @w2...parameter naming. Wszystkie 3 mody endpointu (single/multi/all-warehouses) działają na realnej Optimie.
v0.2.0 — 2026-05-11
Pierwsza znacząca funkcja: multi-warehouse → Magento MSI source mapping + naprawienie krytycznego N+1 w sync stanów.
Nowe funkcje
-
Multi-warehouse: jeden klient z N magazynami Optimy może teraz mapować je na różne MSI source-y w Magento. Konfiguracja w
Stores → Configuration → SISL → Optima Connector → 2. Synchronizacja → Multi-warehouse → MSI source mapping. Format jedna linia per magazyn:OPTIMA_SYMBOL=magento_source_code, np.:Puste mapping = stary tryb single-warehouse (back-compat).MAGAZYN=default WAW=wawa_warehouse SLA=slask_warehouse -
/v1/stocksendpoint wspiera trzy tryby: - Bez
warehouseparam → wszystkie magazyny zCDN.Magazyny warehouse=MAGAZYN→ tylko ten jeden (v0.1 back-compat)warehouse=MAGAZYN,WAW→ multi-warehouse, jedna odpowiedź zawiera wszystkie
Performance
-
Naprawiony N+1 query w
OptimaSqlClient.ListStocksAsync— v0.1 robił correlated subqueries (jeden subquery per wiersz dla każdej z 3 wartości: Available, Reserved, OnOrder). Dla 10k produktów × 1 magazyn × 3 wartości to było 30,000 subzapytań → minuty trwało albo timeout. v0.2 używa CTE + LEFT JOIN: pre-agreguje TwrZasoby i TwrIlosci raz per page, CROSS JOIN z magazynami, jeden execution plan. Test na bazie SISL TEST: ~30× szybciej dla 10k SKU. -
Naprawiony N+1 w
StockSync.php— v0.1 robiłStockRegistry::getStockItemBySku()per wiersz (10k SELECTów + 10k SAVEów dla 10k produktów). v0.2 akumuluje całą stronę w pamięci jakoSourceItemInterface[]i zapisuje przezSourceItemsSaveInterface::execute($batch)— jeden DB write per page.
Wymagania
- Magento dependency:
Magento_InventoryApi(zawsze obecne w Magento 2.4+, brak dodatkowych instalacji) etc/module.xmlsetup_version:0.2.0→bin/magento setup:upgradewymagany przy update z v0.1
Back-compat
- Klienci na single-warehouse setup-ie (puste mapping w configu) działają bez zmian
- Stary tryb
/v1/stocks?warehouse=Xzwraca te same rekordy co v0.1
v0.1.0 — 2026-05-11
Pierwszy public release.
Funkcje
- Sync produktów Optima → Magento (kod, nazwa, EAN, JM, cena z wybranego cennika)
- Sync stanów magazynowych z
CDN.TwrZasobyfiltrowanego przezTwZ_TrSIdDost > 0(real PZ) - Forward zamówień Magento → XML import Optimy (faktura/PA przez observer
sales_order_place_after) - Konfigurowalne harmonogramy cron (10 opcji w dropdown: 5min .. codziennie)
- Wykluczenie pojedynczych produktów z sync przez atrybut
sisl_optima_sync_disabled - Bufor magazynowy + próg "out of stock" (zabezpieczenie przed sprzedażą ostatniego kawałka)
- Filtr SKU prefix + flaga "pomijaj usługi"
- Domyślne wartości statusu/widoczności dla nowych produktów
- Konfigurowalna strategia sync cen (włączone / wyłączone)
- Self-diagnostyka: 14 kontroli (licencja, sieć, perms, cron, drift, DB...)
- Dashboard z statusem ostatnich syncs
Bezpieczeństwo
- HMAC-SHA256 na wszystkich requestach Magento ↔ mikrousługa
- Nonce + timestamp drift ≤300s → anti-replay
- Ed25519 asymetryczna weryfikacja licencji (klucz prywatny tylko na license.sisl.pl)
- Manifest hash plików → wykrywanie cracked instally
- Multi-checkpoint license gate w 5 miejscach (PHP) + 1 (microservice)
- Mikrousługa zwraca HTTP 402 jeśli licencja invalid (ochrona nawet jeśli PHP zedytowane)
- Per-product encryption klucza HMAC w Magento
core_config_data
Limitacje znane
- Tylko default store view (multi-store w v0.2)
- Tylko jeden magazyn Optimy → jeden source Magento
- Pull-based sync (zmiany ceny widać po następnym tick'u, nie realtime)
- Karty kontrahentów: tylko klienci z zamówień, nie pełna sync
- Produkty usuwane w Optimie pozostają w Magento jako orphans
Roadmap v0.2
- Multi-store mapping (per-store warehouse + price tier)
- Multi-warehouse → Magento Inventory MSI sources
- Webhook push z mikrousługi przy zmianach (dla realtime)
- Ostrzeżenie + auto-disable produktów oznaczonych nieaktywne w Optimie
- Sync atrybutów rozszerzonych (kategoria, opis, opis krótki)
- 2-way sync klientów (Magento → Optima KntKarty)
- Grid action: bulk exclude/include z sync dla zaznaczonych SKU
- Opcjonalne IonCube wrap dla customerów premium