# Changelog All notable changes to OpenLinker are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) (pre-1.0: **minor** carries new features *and* breaking changes, **patch** carries fixes — see [RELEASING.md](./RELEASING.md)). From `0.2.0` onward this file is generated automatically by [release-please](https://github.com/googleapis/release-please) from Conventional Commits. The `0.1.0` entry below is the hand-curated baseline of what shipped before automated releases began. ## [0.19.0](https://github.com/openlinker-project/openlinker/compare/v0.18.0...v0.19.0) (2026-11-10) ### Features * **api:** every endpoint and domain filter error carries a stable code ([#3864](https://github.com/openlinker-project/openlinker/issues/3864), [#3865](https://github.com/openlinker-project/openlinker/issues/3865), [#3863](https://github.com/openlinker-project/openlinker/issues/3863)) ([#3997](https://github.com/openlinker-project/openlinker/issues/3997)) ([a7f525e](https://github.com/openlinker-project/openlinker/commit/a7f525ea1d7cde11e9e7facb4e40f378dd3431f3)) * **api:** every error response carries a stable code ([#3921](https://github.com/openlinker-project/openlinker/issues/3921)) ([4188fec](https://github.com/openlinker-project/openlinker/commit/4188fec4a1b8847dfc011c081b302ace528c889f)) * **api:** validation errors name each failed field with a code ([#3861](https://github.com/openlinker-project/openlinker/issues/3861)) ([#3922](https://github.com/openlinker-project/openlinker/issues/3922)) ([a27f971](https://github.com/openlinker-project/openlinker/commit/a27f97124defb7d8a63965328dcd5e1a34a266b9)) * codes for stored reasons - webhook dead-letters, sales-document blocks, settings limits, connection tests ([#3866](https://github.com/openlinker-project/openlinker/issues/3866)) ([#4079](https://github.com/openlinker-project/openlinker/issues/4079)) ([6e29e66](https://github.com/openlinker-project/openlinker/commit/6e29e664b0e0b5881f1f47f6e7c32be64453c0a3)) * **inventory:** clearer stock movement history ([#4070](https://github.com/openlinker-project/openlinker/issues/4070)) ([ba4c7bd](https://github.com/openlinker-project/openlinker/commit/ba4c7bd28c02ef8ba69b94b5d6050b30f248fd2d)) * **inventory:** record the sync run and what was sent to each channel ([#4071](https://github.com/openlinker-project/openlinker/issues/4071)) ([5da3efd](https://github.com/openlinker-project/openlinker/commit/5da3efda3ef76a97b164c741b67c5fa1f86a324d)) * **inventory:** show what was sent to each channel in stock history ([#4073](https://github.com/openlinker-project/openlinker/issues/4073)) ([c861786](https://github.com/openlinker-project/openlinker/commit/c861786506261aaedf14f59f2e465a0d48fd978c)) * **listings:** listings page on the orders filter system ([#4046](https://github.com/openlinker-project/openlinker/issues/4046)) ([#4058](https://github.com/openlinker-project/openlinker/issues/4058)) ([c9f2b65](https://github.com/openlinker-project/openlinker/commit/c9f2b6581c82a0548cf4eea67e8118f7ec6217a2)) * **listings:** needs-a-look counts and filters for blocked and selling-deleted listings ([#4045](https://github.com/openlinker-project/openlinker/issues/4045)) ([#4057](https://github.com/openlinker-project/openlinker/issues/4057)) ([c107575](https://github.com/openlinker-project/openlinker/commit/c107575650cffb4bf3cd067aad8eef41a96f8533)) * **listings:** show what attribute rules fill in the offer wizard ([#4009](https://github.com/openlinker-project/openlinker/issues/4009)) ([5a1363e](https://github.com/openlinker-project/openlinker/commit/5a1363ea0472fa305084a5858db982db6a22c791)) * **oms:** bundles and kits, with a gift inside a set ([#3957](https://github.com/openlinker-project/openlinker/issues/3957)) ([46e8f01](https://github.com/openlinker-project/openlinker/commit/46e8f01a0817e86c4ce201fae5c87a27c0e2e3e5)) * **oms:** promotions with free gifts, and gifts on orders, documents and returns ([#4002](https://github.com/openlinker-project/openlinker/issues/4002)) ([ec83552](https://github.com/openlinker-project/openlinker/commit/ec835525fda1b674a67312c47c5d77873bc9c4f7)) * **oms:** set up shipping in OMS setup and show who ships each order ([#3969](https://github.com/openlinker-project/openlinker/issues/3969)) ([2b05dfc](https://github.com/openlinker-project/openlinker/commit/2b05dfc0e9c0768ec5d276339b7fd7a4b3c27890)) * **orders:** mark the shop order paid when the buyer pays after it was created ([#4000](https://github.com/openlinker-project/openlinker/issues/4000)) ([b1f3240](https://github.com/openlinker-project/openlinker/commit/b1f3240a7c567414faa82a0381c76ffd0f88c68b)) * **orders:** sort by placed date and add filter counts to the health summary ([#4047](https://github.com/openlinker-project/openlinker/issues/4047)) ([d611a54](https://github.com/openlinker-project/openlinker/commit/d611a5450359ed5cd2111da42eb7292c44d799fd)) * **sales-documents:** batched sales-document issuing (epic [#3515](https://github.com/openlinker-project/openlinker/issues/3515)) ([#3917](https://github.com/openlinker-project/openlinker/issues/3917)) ([f4fe2f3](https://github.com/openlinker-project/openlinker/commit/f4fe2f3d16e802e95e5b4cf6c71c0359f1a7dae0)) * **shipments:** shipments list on the orders filter system ([#4044](https://github.com/openlinker-project/openlinker/issues/4044)) ([#4056](https://github.com/openlinker-project/openlinker/issues/4056)) ([b346825](https://github.com/openlinker-project/openlinker/commit/b346825fd756672adc8ec94a728d34655a5838d4)) * **shipments:** summary endpoint with status, filter and needs-a-look counts ([#4043](https://github.com/openlinker-project/openlinker/issues/4043)) ([#4055](https://github.com/openlinker-project/openlinker/issues/4055)) ([a9054d1](https://github.com/openlinker-project/openlinker/commit/a9054d1407bbf857398af7630fc02ff1cc28d257)) * **sync:** sync progress page that shows whether each sync runs on time, with its last run and a guided restart ([#4053](https://github.com/openlinker-project/openlinker/issues/4053)) ([e16fe1a](https://github.com/openlinker-project/openlinker/commit/e16fe1afd6357b845e70eb779059fc140e7db2de)) * **web:** content rises in on every page ([#4060](https://github.com/openlinker-project/openlinker/issues/4060)) ([e6cf1fd](https://github.com/openlinker-project/openlinker/commit/e6cf1fd36c7af444396b1dc1a822966ae85c7ab2)) * **web:** describeApiError turns an API error code into translated copy ([#3862](https://github.com/openlinker-project/openlinker/issues/3862)) ([#4011](https://github.com/openlinker-project/openlinker/issues/4011)) ([3f5956a](https://github.com/openlinker-project/openlinker/commit/3f5956a728d3b87e65cf89838613d57235b6197d)) * **web:** every API error the operator reads goes through describeApiError ([#3867](https://github.com/openlinker-project/openlinker/issues/3867)) ([#4072](https://github.com/openlinker-project/openlinker/issues/4072)) ([d73818f](https://github.com/openlinker-project/openlinker/commit/d73818f922f09ea1efc89658aad76f35944a6aa0)) * **web:** explicit buyer-address checkbox on the document email card ([#4067](https://github.com/openlinker-project/openlinker/issues/4067)) ([741725f](https://github.com/openlinker-project/openlinker/commit/741725ff41d2db5dd58a7557a0806574e3a86a5d)), closes [#4066](https://github.com/openlinker-project/openlinker/issues/4066) * **web:** hide sales document technical details behind a disclosure ([#4069](https://github.com/openlinker-project/openlinker/issues/4069)) ([b17804b](https://github.com/openlinker-project/openlinker/commit/b17804bece8f879a3bb5e79877814411af12c484)), closes [#4065](https://github.com/openlinker-project/openlinker/issues/4065) * **web:** i18n extraction 1-18/18 - every operator-visible string moves into locale files (English) ([#3920](https://github.com/openlinker-project/openlinker/issues/3920)) ([1c192ca](https://github.com/openlinker-project/openlinker/commit/1c192ca5c5dfe1a8daad5eb3aea3f2b57fb6da41)) * **web:** invoice, return-decline and order-hold errors read codes, not class names ([#3863](https://github.com/openlinker-project/openlinker/issues/3863)) ([#4012](https://github.com/openlinker-project/openlinker/issues/4012)) ([ebcba43](https://github.com/openlinker-project/openlinker/commit/ebcba4356ecca1546c723d1ea50e27a4f8e4d890)) * **web:** language switch first in the account menu and on the guest card; Insights becomes System health ([#4021](https://github.com/openlinker-project/openlinker/issues/4021)) ([#4022](https://github.com/openlinker-project/openlinker/issues/4022)) ([facdefa](https://github.com/openlinker-project/openlinker/commit/facdefa0d9195bf5a2c624b937afc592fa724264)) * **web:** lock in the translations ([#3891](https://github.com/openlinker-project/openlinker/issues/3891)) ([#4020](https://github.com/openlinker-project/openlinker/issues/4020)) ([e1d129b](https://github.com/openlinker-project/openlinker/commit/e1d129be22e3a775784d8419b0269e37471e34af)) * **web:** login and registration page redesign with an admin login page editor ([#4048](https://github.com/openlinker-project/openlinker/issues/4048)) ([f9194c0](https://github.com/openlinker-project/openlinker/commit/f9194c0a5bbde14405220b408a376ecd56f08cfe)) * **web:** one filter system on the orders list ([#4049](https://github.com/openlinker-project/openlinker/issues/4049)) ([f46d5e6](https://github.com/openlinker-project/openlinker/commit/f46d5e6153ba5ef90bb233d3788650cd22ed40eb)) * **web:** open the interface in the browser's language ([#3890](https://github.com/openlinker-project/openlinker/issues/3890)) ([#4019](https://github.com/openlinker-project/openlinker/issues/4019)) ([d92c81c](https://github.com/openlinker-project/openlinker/commit/d92c81c84252739b18eb7d68c142b9a740b459c4)) * **web:** Polish translation of the admin app, batches A-D ([#3886](https://github.com/openlinker-project/openlinker/issues/3886), [#3887](https://github.com/openlinker-project/openlinker/issues/3887), [#3888](https://github.com/openlinker-project/openlinker/issues/3888), [#3889](https://github.com/openlinker-project/openlinker/issues/3889)) ([#3967](https://github.com/openlinker-project/openlinker/issues/3967)) ([2760a26](https://github.com/openlinker-project/openlinker/commit/2760a2638edaa7089e7b1fbab8dd0e9b5b4845a7)) * **web:** products list on the one filter system ([#4027](https://github.com/openlinker-project/openlinker/issues/4027)) ([#4054](https://github.com/openlinker-project/openlinker/issues/4054)) ([e9dd96d](https://github.com/openlinker-project/openlinker/commit/e9dd96d86c6162ef504062ae75c793928989687a)) * **web:** tidy Connection health, System health and Sync jobs, show connections as chips ([#4018](https://github.com/openlinker-project/openlinker/issues/4018)) ([24e6d97](https://github.com/openlinker-project/openlinker/commit/24e6d974e71c2887018aa8f78befb1506c18b7fc)) ### Bug Fixes * **content:** read and write the product's own master, not the first one ([#4080](https://github.com/openlinker-project/openlinker/issues/4080)) ([839df32](https://github.com/openlinker-project/openlinker/commit/839df3228c0b35611cd69d076db5a786fffbf3ea)) * **fiscalization:** register a refused receipt again as a new attempt ([#3965](https://github.com/openlinker-project/openlinker/issues/3965)) ([a133299](https://github.com/openlinker-project/openlinker/commit/a1332993897a5ff210636025dc0c483a5c1f459a)) * **listings:** a category mapping wins over a barcode match that disagrees with it ([#4008](https://github.com/openlinker-project/openlinker/issues/4008)) ([9836fd9](https://github.com/openlinker-project/openlinker/commit/9836fd93e925be99d61bb10ff3c9f4ee56bdfbac)) * **listings:** name plugin blockers and missing parameters in the bulk editor ([#4005](https://github.com/openlinker-project/openlinker/issues/4005)) ([72cfa19](https://github.com/openlinker-project/openlinker/commit/72cfa19d9a0dc77a5142bfadc1958db871090b60)) * **mappings:** save category mappings under the marketplace they are for ([#4007](https://github.com/openlinker-project/openlinker/issues/4007)) ([8ca1f3c](https://github.com/openlinker-project/openlinker/commit/8ca1f3ce923e859ee7b02ffb71147b85a1e21357)) * **orders:** a shop that is its own only destination still gets its sales document ([#3964](https://github.com/openlinker-project/openlinker/issues/3964)) ([ff362a8](https://github.com/openlinker-project/openlinker/commit/ff362a8f1f945e910449abaadaae6c879acf07c8)) * **orders:** carry a shop-side quantity change into the packing work ([#4001](https://github.com/openlinker-project/openlinker/issues/4001)) ([009f4c4](https://github.com/openlinker-project/openlinker/commit/009f4c4816b8f8f75fd6ae4fb2399bf14ede3db7)) * **web:** show why a shipment cancel failed instead of failing silently ([#4031](https://github.com/openlinker-project/openlinker/issues/4031)) ([1fea50d](https://github.com/openlinker-project/openlinker/commit/1fea50d25f08689dce08a53e045f97e0f519d19d)) ## [0.18.0](https://github.com/openlinker-project/openlinker/compare/v0.17.0...v0.18.0) (2026-11-03) ### Features * **core:** resolvable buyer.name and shipment.tracking automation merge fields ([#3553](https://github.com/openlinker-project/openlinker/issues/3553)) ([#3847](https://github.com/openlinker-project/openlinker/issues/3847)) ([7dff721](https://github.com/openlinker-project/openlinker/commit/7dff721b52fe1a47facd6fb839288d87917f95cd)) * **fiscalization:** show the provider's error code, printer code and document id on a failed receipt ([#3848](https://github.com/openlinker-project/openlinker/issues/3848)) ([20f0d48](https://github.com/openlinker-project/openlinker/commit/20f0d48b45327d5c826fb6e8256032a33060e280)) * **fulfillment:** reap routing decisions stranded live past a TTL ([#2731](https://github.com/openlinker-project/openlinker/issues/2731)) ([#3836](https://github.com/openlinker-project/openlinker/issues/3836)) ([76a40e2](https://github.com/openlinker-project/openlinker/commit/76a40e2800ff7d016db7101d1be968aec77721a6)) * **inventory:** stock view, manual corrections and stock history for operators ([#3854](https://github.com/openlinker-project/openlinker/issues/3854)) ([4fc467d](https://github.com/openlinker-project/openlinker/commit/4fc467d59d5516f31dba6e5d28f3b7e331810254)) * **invoicing:** one answer to what can be attached for an issued document ([#3548](https://github.com/openlinker-project/openlinker/issues/3548)) ([#3832](https://github.com/openlinker-project/openlinker/issues/3832)) ([f4d619d](https://github.com/openlinker-project/openlinker/commit/f4d619d14a610404aee400a4efc98d9121848c42)) * **ksef:** render the FA(3) invoice as a PDF with KOD I and persist its hash ([#3620](https://github.com/openlinker-project/openlinker/issues/3620)) ([#3831](https://github.com/openlinker-project/openlinker/issues/3831)) ([e847862](https://github.com/openlinker-project/openlinker/commit/e847862bee4643779160ab47c1a3d71643176f6f)) * **orders:** attach an issued invoice to its marketplace order ([#3549](https://github.com/openlinker-project/openlinker/issues/3549)) ([#3833](https://github.com/openlinker-project/openlinker/issues/3833)) ([7b02489](https://github.com/openlinker-project/openlinker/commit/7b0248944ccf8e46dfc0e3a2152cf5dc81e5043e)) * **orders:** bulk cancel, tag removal and buyer-note read with per-row results ([#3826](https://github.com/openlinker-project/openlinker/issues/3826)) ([32ba83e](https://github.com/openlinker-project/openlinker/commit/32ba83e050da6e3b03e807d838cffbdefeeb1749)) * **orders:** buyer checkout note, shipping and billing country and repeat-buyer count on orders ([#3818](https://github.com/openlinker-project/openlinker/issues/3818)) ([4336842](https://github.com/openlinker-project/openlinker/commit/43368426973d388e69ebe061640470ae88ac5694)) * **orders:** buyer email notifications, opt-in per connection ([#3554](https://github.com/openlinker-project/openlinker/issues/3554)) ([#3852](https://github.com/openlinker-project/openlinker/issues/3852)) ([c5eb342](https://github.com/openlinker-project/openlinker/commit/c5eb342972d751693bfd87d7c80f8762b12546f5)) * **orders:** cancel an order from OpenLinker - void the label, tell the sales channel and correct the invoice ([#3820](https://github.com/openlinker-project/openlinker/issues/3820)) ([99e7288](https://github.com/openlinker-project/openlinker/commit/99e7288c327d1a336e439007ca66ad829bc5d42e)) * **orders:** edit an order's address, quantities and delivery method after import ([#3822](https://github.com/openlinker-project/openlinker/issues/3822)) ([b37505a](https://github.com/openlinker-project/openlinker/commit/b37505a3bf23127b922fa91bec63aaaa00c2c390)) * **orders:** email any sales document to the buyer, for every provider ([#3550](https://github.com/openlinker-project/openlinker/issues/3550)) ([#3844](https://github.com/openlinker-project/openlinker/issues/3844)) ([3a8bb7f](https://github.com/openlinker-project/openlinker/commit/3a8bb7f7e06a4aece7cd5fd3709f1f9bd797fa89)) * **orders:** give a discount on an imported order, with the refund and invoice correction it needs ([#3823](https://github.com/openlinker-project/openlinker/issues/3823)) ([0de65d7](https://github.com/openlinker-project/openlinker/commit/0de65d7a6646e599249c3f8823976519b1f64014)) * **orders:** re-route a held order on a stock change and on an operator retry ([#3558](https://github.com/openlinker-project/openlinker/issues/3558)) ([#3837](https://github.com/openlinker-project/openlinker/issues/3837)) ([2cf292e](https://github.com/openlinker-project/openlinker/commit/2cf292e3f945d4ffaf403a45b9b078a90462df84)) * **products,analytics:** variant pictures, cost price, margin and CSV export ([#3516](https://github.com/openlinker-project/openlinker/issues/3516)) ([#3850](https://github.com/openlinker-project/openlinker/issues/3850)) ([b008faf](https://github.com/openlinker-project/openlinker/commit/b008faf16be7228ac101c6dd7874a6afbd5bb2d7)) * **sales-documents:** delivery line per buyer country, one receipt name per VAT rate ([#3914](https://github.com/openlinker-project/openlinker/issues/3914)) ([d9336d5](https://github.com/openlinker-project/openlinker/commit/d9336d55a0f0912e472a7efc910fb9f2157a7a34)) * **web:** add the i18n core - locale switching, typed copy files, language resolution ([#3893](https://github.com/openlinker-project/openlinker/issues/3893)) ([a476525](https://github.com/openlinker-project/openlinker/commit/a476525181da0e23dbd5221a1b1572daefce86b6)) * **web:** add the i18n safety net - pinned test language, copy checks, lint, pseudo-locale ([#3896](https://github.com/openlinker-project/openlinker/issues/3896)) ([47cf6ca](https://github.com/openlinker-project/openlinker/commit/47cf6ca96c318fff5e21cd69c3da7c2bb0f5b4ef)) * **web:** add the language switch and translate the shared UI primitives ([#3895](https://github.com/openlinker-project/openlinker/issues/3895)) ([1d6b3dc](https://github.com/openlinker-project/openlinker/commit/1d6b3dc4133b42d5ce03852c0c2b8de80aa15b3f)) * **web:** bulk cancel, tags and mark message read on the orders list ([#3827](https://github.com/openlinker-project/openlinker/issues/3827)) ([a23ba3e](https://github.com/openlinker-project/openlinker/commit/a23ba3e0b3818d9e8aa6e2ef04a0fcbea8d7ade4)) * **web:** buyer email settings, template editor and order states ([#3555](https://github.com/openlinker-project/openlinker/issues/3555)) ([#3853](https://github.com/openlinker-project/openlinker/issues/3853)) ([c690f51](https://github.com/openlinker-project/openlinker/commit/c690f51808e52b1a24b0c3b483bb8086aab36713)) * **web:** cancel an order and confirm the refund from order detail ([#3821](https://github.com/openlinker-project/openlinker/issues/3821)) ([7bcec54](https://github.com/openlinker-project/openlinker/commit/7bcec54c94c24cc12fa4512a458b7c66f7f74fae)) * **web:** edit an order's address, quantities, delivery and discount from order detail ([#3825](https://github.com/openlinker-project/openlinker/issues/3825)) ([6c46d0f](https://github.com/openlinker-project/openlinker/commit/6c46d0f5e7c43b86d184d16590322c4abb88c018)) * **web:** format numbers, dates and plurals in the operator's language ([#3894](https://github.com/openlinker-project/openlinker/issues/3894)) ([15ff1f8](https://github.com/openlinker-project/openlinker/commit/15ff1f8acbc090eb6b111fde49a57ade5fcc8d20)) * **web:** shorten the dev environment badge to "Dev" ([#3899](https://github.com/openlinker-project/openlinker/issues/3899)) ([49c8f11](https://github.com/openlinker-project/openlinker/commit/49c8f11dff8879ee953bf29d98bf6fbfc78aee46)) * **web:** show a routing decision stranded live, read only ([#3557](https://github.com/openlinker-project/openlinker/issues/3557)) ([#3841](https://github.com/openlinker-project/openlinker/issues/3841)) ([55efd93](https://github.com/openlinker-project/openlinker/commit/55efd930a1a403af6ecb336fc8d1cda4294f4569)) * **web:** show the buyer note on order detail, the orders list and the pack bench ([#3819](https://github.com/openlinker-project/openlinker/issues/3819)) ([1c63a75](https://github.com/openlinker-project/openlinker/commit/1c63a757c39d9d1a9e7746b9db7d5216256fcad1)) * **web:** show whether an issued document reached the marketplace order ([#3549](https://github.com/openlinker-project/openlinker/issues/3549)) ([#3834](https://github.com/openlinker-project/openlinker/issues/3834)) ([996d382](https://github.com/openlinker-project/openlinker/commit/996d3821ddbfb4a5c4dafda1242e43c44d57551a)) * **web:** universal send-by-email control for every sales document ([#3551](https://github.com/openlinker-project/openlinker/issues/3551)) ([#3845](https://github.com/openlinker-project/openlinker/issues/3845)) ([673901d](https://github.com/openlinker-project/openlinker/commit/673901dbea197e444ab49ec55185994ece864413)) ### Bug Fixes * **core:** bind the mailer in the worker so automation emails send there ([#3552](https://github.com/openlinker-project/openlinker/issues/3552)) ([#3846](https://github.com/openlinker-project/openlinker/issues/3846)) ([23dc52a](https://github.com/openlinker-project/openlinker/commit/23dc52a810bd829aa0010519b8ce9bb232d3ef70)) * **listings:** bulk offer wizard keeps edits, clears stale chips, refuses empty and unsynced listings ([#3903](https://github.com/openlinker-project/openlinker/issues/3903)) ([5ba76e4](https://github.com/openlinker-project/openlinker/commit/5ba76e47f190f760c69ed71dfda7a146640e46a0)) * **orders:** a retried correction confirm no longer issues a second document with the invoicing provider ([#3919](https://github.com/openlinker-project/openlinker/issues/3919)) ([9e35aec](https://github.com/openlinker-project/openlinker/commit/9e35aec9df6d4108e9f9dbfaa02d6e60ba3f17d5)) * **orders:** refuse refunds that exceed what the order was worth ([#3817](https://github.com/openlinker-project/openlinker/issues/3817)) ([d317555](https://github.com/openlinker-project/openlinker/commit/d317555e3d06145a60717c0856de553507e16701)) ## [0.17.0](https://github.com/openlinker-project/openlinker/compare/v0.16.1...v0.17.0) (2026-10-27) ### Features * **api:** serve robots.txt that disallows crawling ([#3788](https://github.com/openlinker-project/openlinker/issues/3788)) ([2d1dc3e](https://github.com/openlinker-project/openlinker/commit/2d1dc3e16a66f2d65a78f7328617d328f5345990)), closes [#3787](https://github.com/openlinker-project/openlinker/issues/3787) * **ksef:** land KSeF legal completeness ([#1578](https://github.com/openlinker-project/openlinker/issues/1578)) on main, with fixes for 39 defects ([#3793](https://github.com/openlinker-project/openlinker/issues/3793)) ([e211f2e](https://github.com/openlinker-project/openlinker/commit/e211f2ee49cf1f4ec9364ed4b73d2f6896fd1279)) * **ksef:** restore KOD I verification QR on the invoice preview ([#3547](https://github.com/openlinker-project/openlinker/issues/3547)) ([#3783](https://github.com/openlinker-project/openlinker/issues/3783)) ([bd0ac84](https://github.com/openlinker-project/openlinker/commit/bd0ac84f9beb9bfa09aa4b1dc10215d8bc02dcc5)) * **oms:** dry-run the fulfilment router on an order or basket ([#2954](https://github.com/openlinker-project/openlinker/issues/2954)) ([#3778](https://github.com/openlinker-project/openlinker/issues/3778)) ([49923e0](https://github.com/openlinker-project/openlinker/commit/49923e055bf195b7e27439b217586d8782fe693c)) * **orders:** show an order handled in OpenLinker on /orders ([#3797](https://github.com/openlinker-project/openlinker/issues/3797)) ([3757680](https://github.com/openlinker-project/openlinker/commit/3757680a86d83b134907898b4759219c92f16f5b)) * **orders:** waiting and pack-bench filters, health after shipping, packer names ([#3799](https://github.com/openlinker-project/openlinker/issues/3799)) ([3ac5a1f](https://github.com/openlinker-project/openlinker/commit/3ac5a1f8a5edb4617a8361208da919070551b4dc)) * **products:** store the shop's category path and show it on the product page ([#3796](https://github.com/openlinker-project/openlinker/issues/3796)) ([84cb0a8](https://github.com/openlinker-project/openlinker/commit/84cb0a838b66d783c561aff006c4a743abbac36d)) * **shoper:** complete the capability map with pickers, order read-back, signed webhooks, a shared rate limit and GPSR ([#3811](https://github.com/openlinker-project/openlinker/issues/3811)) ([7e59fde](https://github.com/openlinker-project/openlinker/commit/7e59fde41b34933cef5b38df17bc8fc3299504fd)) * **web:** noindex admin SPA by default, build-time opt-in for the public demo ([#3792](https://github.com/openlinker-project/openlinker/issues/3792)) ([02f9827](https://github.com/openlinker-project/openlinker/commit/02f9827811874582917fa563590db17360074ce8)) * **web:** scan every feature slice in check-ui-vocabulary by default ([#2737](https://github.com/openlinker-project/openlinker/issues/2737)) ([#3776](https://github.com/openlinker-project/openlinker/issues/3776)) ([d69d055](https://github.com/openlinker-project/openlinker/commit/d69d055e78701167dc4e78f766f4ba48aec68d2f)) ### Bug Fixes * **dx:** make the pre-commit hook prove which worktree it validates ([#2767](https://github.com/openlinker-project/openlinker/issues/2767)) ([#3777](https://github.com/openlinker-project/openlinker/issues/3777)) ([fab14a0](https://github.com/openlinker-project/openlinker/commit/fab14a0634050a19bc0c0f6a63503f812f3c0b56)) * **inventory:** reconcile sweep for a lost inventory.saleDecrement enqueue ([#3629](https://github.com/openlinker-project/openlinker/issues/3629)) ([#3779](https://github.com/openlinker-project/openlinker/issues/3779)) ([784f98c](https://github.com/openlinker-project/openlinker/commit/784f98cefc1247d74c745a01b8ec257885a7980a)) * **invoicing:** explain provider refusals and let a corrected retry reach the provider ([#3812](https://github.com/openlinker-project/openlinker/issues/3812)) ([936937b](https://github.com/openlinker-project/openlinker/commit/936937bdf496fe6fb7f2cfe59236a9550f53beb3)) * **listings:** carry Shoper variant pictures to Allegro and fix the bulk offer wizard ([#3813](https://github.com/openlinker-project/openlinker/issues/3813)) ([1110c46](https://github.com/openlinker-project/openlinker/commit/1110c464bdfbe6dbb5fed8dbb4db814ee74402f9)) * **oms:** do not route stock OpenLinker has already promised ([#3475](https://github.com/openlinker-project/openlinker/issues/3475)) ([#3780](https://github.com/openlinker-project/openlinker/issues/3780)) ([ed0e546](https://github.com/openlinker-project/openlinker/commit/ed0e546344ab07be1eb22ff852b8f560f104c2ce)) * **orders:** book Shoper variant stock, ignore failed payments and restore stock on cancellation ([#3814](https://github.com/openlinker-project/openlinker/issues/3814)) ([54fba43](https://github.com/openlinker-project/openlinker/commit/54fba436f283833ae815d7dd2b3c97ddfe73f048)) * **orders:** persist why a routing decision narrowed the destination fan-out ([#3014](https://github.com/openlinker-project/openlinker/issues/3014)) ([b493bd2](https://github.com/openlinker-project/openlinker/commit/b493bd2b5f0754e041e01837af42fa18aba9d821)) * **shoper:** count only real variants, inherit their price, and import the whole gallery ([#3795](https://github.com/openlinker-project/openlinker/issues/3795)) ([56fe87c](https://github.com/openlinker-project/openlinker/commit/56fe87c4f90ff1804bb57c8a515bb7f01f814ca7)) * **web:** connection wizards stop on review, webhook URLs use the API address, tax rate on every product view ([#3794](https://github.com/openlinker-project/openlinker/issues/3794)) ([e7406e5](https://github.com/openlinker-project/openlinker/commit/e7406e5de31aae44810fffece81b5f6fd8cc9458)) ## [0.16.1](https://github.com/openlinker-project/openlinker/compare/v0.16.0...v0.16.1) (2026-10-22) ### Bug Fixes * **infra:** patch the Node.js 2026-10-21 security release ([#3782](https://github.com/openlinker-project/openlinker/issues/3782)) ([7eefd32](https://github.com/openlinker-project/openlinker/commit/7eefd3284dafa18f65c313427aa9b3e9fefb5149)) ## [0.16.0](https://github.com/openlinker-project/openlinker/compare/v0.15.0...v0.16.0) (2026-10-19) ### Features * **fulfillment:** replace the "Handshake" field with a pack-bench warning ([#3768](https://github.com/openlinker-project/openlinker/issues/3768)) ([9d05663](https://github.com/openlinker-project/openlinker/commit/9d05663e81cda5acf730431c665a32c1930bd607)) * **lint:** check parenthesis balance in the stylesheet structure guard ([#2677](https://github.com/openlinker-project/openlinker/issues/2677)) ([#3745](https://github.com/openlinker-project/openlinker/issues/3745)) ([6999154](https://github.com/openlinker-project/openlinker/commit/6999154450d7ea55f90437b7ad253050852f182b)) * **orders:** neutral payment method on orders, and the COD amount from every source ([#3294](https://github.com/openlinker-project/openlinker/issues/3294)) ([#3756](https://github.com/openlinker-project/openlinker/issues/3756)) ([897421b](https://github.com/openlinker-project/openlinker/commit/897421b5e5815406e694d73cd6ef8826072a4196)) * **orders:** write the payment method to destinations and invoices, and show it in the UI ([#3294](https://github.com/openlinker-project/openlinker/issues/3294)) ([#3758](https://github.com/openlinker-project/openlinker/issues/3758)) ([a96fb58](https://github.com/openlinker-project/openlinker/commit/a96fb58805aa33ecd2f227d36905ec476d47c4ee)) * **shipping:** default parcel dimensions for auto-dispatch labels ([#3571](https://github.com/openlinker-project/openlinker/issues/3571)) ([#3742](https://github.com/openlinker-project/openlinker/issues/3742)) ([7122ed0](https://github.com/openlinker-project/openlinker/commit/7122ed0ee31c6dd4dfa7a1b11fdbe2c6f623e476)) * **web:** calmer sales document panel - one notice for an unconfirmed invoice ([#3770](https://github.com/openlinker-project/openlinker/issues/3770)) ([ea4f75a](https://github.com/openlinker-project/openlinker/commit/ea4f75a952c007eda60ed4954f34a1f50aa18822)) ### Bug Fixes * **fulfillment:** never route to a holder that cannot execute, and re-drive stranded work ([#3476](https://github.com/openlinker-project/openlinker/issues/3476)) ([#3744](https://github.com/openlinker-project/openlinker/issues/3744)) ([a4d8434](https://github.com/openlinker-project/openlinker/commit/a4d8434f09ecf920e5995fa11bc24d98f46c6d66)) * **invoicing:** show a refusal for a missing connection setting where it can be fixed ([#3773](https://github.com/openlinker-project/openlinker/issues/3773)) ([9790137](https://github.com/openlinker-project/openlinker/commit/979013719d3269adb0f046308e2329f8c48099bc)) * **orders:** do not route an order the source ships itself ([#3636](https://github.com/openlinker-project/openlinker/issues/3636)) ([#3743](https://github.com/openlinker-project/openlinker/issues/3743)) ([2f83029](https://github.com/openlinker-project/openlinker/commit/2f83029c5284d27f12e3b321f15b04814d43affa)) * **prestashop:** honour the configured payment mapping when creating an order ([#3474](https://github.com/openlinker-project/openlinker/issues/3474)) ([#3754](https://github.com/openlinker-project/openlinker/issues/3754)) ([fe48990](https://github.com/openlinker-project/openlinker/commit/fe48990d5617ca80551cd8e2e3a46a5c80d2e3eb)) * **web:** classify the motion tokens and make the form-field-row column count private ([#2436](https://github.com/openlinker-project/openlinker/issues/2436)) ([#3753](https://github.com/openlinker-project/openlinker/issues/3753)) ([42d3b73](https://github.com/openlinker-project/openlinker/commit/42d3b73d9fe9df5c0eef6305c4d80327b70947cf)) * **web:** drop the duplicate "both" option from the sales-documents kind filter ([#3762](https://github.com/openlinker-project/openlinker/issues/3762)) ([0151c5a](https://github.com/openlinker-project/openlinker/commit/0151c5a7d03adb9287d860b6cdcf0d3b11f0ef9d)), closes [#3761](https://github.com/openlinker-project/openlinker/issues/3761) * **web:** let FormField compose with fragments, arrays and multi-control rows ([#2435](https://github.com/openlinker-project/openlinker/issues/2435)) ([#3748](https://github.com/openlinker-project/openlinker/issues/3748)) ([bae2bbb](https://github.com/openlinker-project/openlinker/commit/bae2bbb7a54b2984e9117c90c544f7b6480e0ade)) * **web:** let the eparagony.pl setup choose its documents and ask for the seller an invoice needs ([#3771](https://github.com/openlinker-project/openlinker/issues/3771)) ([d5e923a](https://github.com/openlinker-project/openlinker/commit/d5e923a2a0dbb4998ff85b8c8b19d35af4d63459)) * **web:** paint the error border for a standalone Input invalid ([#2415](https://github.com/openlinker-project/openlinker/issues/2415)) ([#3747](https://github.com/openlinker-project/openlinker/issues/3747)) ([e6b2589](https://github.com/openlinker-project/openlinker/commit/e6b25894b6ba298c49e875750cc41a1a41481edd)) * **web:** report every failed Edit connection save with a toast ([#3767](https://github.com/openlinker-project/openlinker/issues/3767)) ([e00b843](https://github.com/openlinker-project/openlinker/commit/e00b843ac6c55e0bb3c1f4b15153c2861a7992ee)) * **web:** stop InvoiceConnectionLock breaking one word per line in a narrow container ([#3484](https://github.com/openlinker-project/openlinker/issues/3484)) ([#3751](https://github.com/openlinker-project/openlinker/issues/3751)) ([d6b910f](https://github.com/openlinker-project/openlinker/commit/d6b910fb23c75f195332be8c058a61d9eeb5905e)) ## [0.15.0](https://github.com/openlinker-project/openlinker/compare/v0.14.0...v0.15.0) (2026-10-12) ### Features * **bench:** read-only pack bench preview for the viewer role ([#3734](https://github.com/openlinker-project/openlinker/issues/3734)) ([#3735](https://github.com/openlinker-project/openlinker/issues/3735)) ([5750380](https://github.com/openlinker-project/openlinker/commit/5750380ba0ffac54d51b71cf68a5811f935ca9fd)) * **fulfillment:** read-only board and task detail for the viewer role ([#3736](https://github.com/openlinker-project/openlinker/issues/3736)) ([#3738](https://github.com/openlinker-project/openlinker/issues/3738)) ([2802aaf](https://github.com/openlinker-project/openlinker/commit/2802aafdb5981bc56dfbbff24d912034f2a73fa3)) * **shoper:** CategoryProvisioner - ensure a category path exists before publishing ([#3713](https://github.com/openlinker-project/openlinker/issues/3713)) ([#3719](https://github.com/openlinker-project/openlinker/issues/3719)) ([67766db](https://github.com/openlinker-project/openlinker/commit/67766db7ddbd83a6d3bfa7518fbaa70ac307ffee)) * **shoper:** connection skeleton - adapter registration, connection test, shape validators ([#3674](https://github.com/openlinker-project/openlinker/issues/3674)) ([7860ffb](https://github.com/openlinker-project/openlinker/commit/7860ffbcd5b2262f3843cdca9d26715b95182575)) * **shoper:** fulfillment writeback - record a dispatch as a Shoper parcel ([#3643](https://github.com/openlinker-project/openlinker/issues/3643)) ([#3704](https://github.com/openlinker-project/openlinker/issues/3704)) ([a077f00](https://github.com/openlinker-project/openlinker/commit/a077f00f0078b18e09dd3c5bc4688f81920532df)) * **shoper:** InventoryMaster - stock read and adjust ([#3641](https://github.com/openlinker-project/openlinker/issues/3641)) ([#3691](https://github.com/openlinker-project/openlinker/issues/3691)) ([128ddba](https://github.com/openlinker-project/openlinker/commit/128ddbadc6e0a6a4373c5f34f01c4a606bcf1231)) * **shoper:** map variant options to ProductVariant.attributes ([#3706](https://github.com/openlinker-project/openlinker/issues/3706)) ([#3707](https://github.com/openlinker-project/openlinker/issues/3707)) ([46ad87b](https://github.com/openlinker-project/openlinker/commit/46ad87b648c3f76a6af45d0805a4a06aee4f8b01)) * **shoper:** OrderProcessorManager - push orders, real price, idempotency ([#3642](https://github.com/openlinker-project/openlinker/issues/3642)) ([#3701](https://github.com/openlinker-project/openlinker/issues/3701)) ([21284b2](https://github.com/openlinker-project/openlinker/commit/21284b24bc01c2d189c4acfc4db9c252acee1393)) * **shoper:** OrderSource - carry the order's pickup point ([#3720](https://github.com/openlinker-project/openlinker/issues/3720)) ([#3721](https://github.com/openlinker-project/openlinker/issues/3721)) ([bf88e36](https://github.com/openlinker-project/openlinker/commit/bf88e366565d217b76e5421e12561b41f9abf146)) * **shoper:** OrderSource - ingest orders placed in the shop ([#3711](https://github.com/openlinker-project/openlinker/issues/3711)) ([#3714](https://github.com/openlinker-project/openlinker/issues/3714)) ([a5ee8c0](https://github.com/openlinker-project/openlinker/commit/a5ee8c08ab52411953e9415ade34290b4e7ce898)) * **shoper:** ProductMaster - catalogue read, categories, tax rate, deletion detection ([#3640](https://github.com/openlinker-project/openlinker/issues/3640)) ([#3684](https://github.com/openlinker-project/openlinker/issues/3684)) ([664e8b4](https://github.com/openlinker-project/openlinker/commit/664e8b483e545f37fbe8c8982f0d762e2b4d40ec)) * **shoper:** ProductPublisher - publish a product to the shop ([#3712](https://github.com/openlinker-project/openlinker/issues/3712)) ([#3718](https://github.com/openlinker-project/openlinker/issues/3718)) ([b4c0d94](https://github.com/openlinker-project/openlinker/commit/b4c0d9420374ed44212df1dcd1e4eb4aedf6275c)) * **shoper:** webhooks - decoder, translator, provisioner, UI ([#3644](https://github.com/openlinker-project/openlinker/issues/3644)) ([#3716](https://github.com/openlinker-project/openlinker/issues/3716)) ([b23c187](https://github.com/openlinker-project/openlinker/commit/b23c187bb5cba692e2378f00572a417b3a58a84d)) * **web:** Shoper guided connection setup ([#3702](https://github.com/openlinker-project/openlinker/issues/3702)) ([#3703](https://github.com/openlinker-project/openlinker/issues/3703)) ([bcbb9fd](https://github.com/openlinker-project/openlinker/commit/bcbb9fdd78f1004317898b929c66b4603d4ef6ff)) ### Bug Fixes * **allegro:** send GPSR fields on card-linked offers ([#3715](https://github.com/openlinker-project/openlinker/issues/3715)) ([ce6f2aa](https://github.com/openlinker-project/openlinker/commit/ce6f2aaee820a8a9c4eca79851cbd997b0056622)) * **bench:** stop reporting KSeF invoices as printable and offer the KOD I link ([#3648](https://github.com/openlinker-project/openlinker/issues/3648)) ([#3722](https://github.com/openlinker-project/openlinker/issues/3722)) ([7000b24](https://github.com/openlinker-project/openlinker/commit/7000b24d8c999387c35358a02499a7a8bd9c4e04)) * **orders:** carry OrderItem.name through the destination allowlist ([#3710](https://github.com/openlinker-project/openlinker/issues/3710)) ([#3717](https://github.com/openlinker-project/openlinker/issues/3717)) ([61afd7c](https://github.com/openlinker-project/openlinker/commit/61afd7cc2510678577ebe5baca020b4d934a51fa)) * **pricing:** catalogue prices are gross - what the buyer pays ([#3740](https://github.com/openlinker-project/openlinker/issues/3740)) ([7b61d52](https://github.com/openlinker-project/openlinker/commit/7b61d525a51c1b535c7150667367e3a88cfd7e05)) * **web:** bench offers the authority's invoice link instead of Print when nothing can render ([#3649](https://github.com/openlinker-project/openlinker/issues/3649)) ([#3723](https://github.com/openlinker-project/openlinker/issues/3723)) ([af894af](https://github.com/openlinker-project/openlinker/commit/af894af77355f36fa95096a42c8a603730e329b2)) * **web:** keep Publish products modal actions reachable with many destinations ([#3726](https://github.com/openlinker-project/openlinker/issues/3726)) ([8a84511](https://github.com/openlinker-project/openlinker/commit/8a845118d7a012715cbaec90aa0c8b7f47a2922f)) * **web:** Pricing & sync page no longer crashes when a connection has no pricing rule ([#3727](https://github.com/openlinker-project/openlinker/issues/3727)) ([#3728](https://github.com/openlinker-project/openlinker/issues/3728)) ([b249877](https://github.com/openlinker-project/openlinker/commit/b2498776b33e648736cbf7e3a54cf8027d951f18)) * **web:** Pricing & sync reads the real per-source override flags ([#3729](https://github.com/openlinker-project/openlinker/issues/3729)) ([#3730](https://github.com/openlinker-project/openlinker/issues/3730)) ([b859a42](https://github.com/openlinker-project/openlinker/commit/b859a4253b6f3f9ebfaf67d08bb7b1846814d9db)) * **web:** send a packer owing a password change from /bench to /change-password ([#3732](https://github.com/openlinker-project/openlinker/issues/3732)) ([#3733](https://github.com/openlinker-project/openlinker/issues/3733)) ([b605c6c](https://github.com/openlinker-project/openlinker/commit/b605c6c36cc48826cc55b6936382386b43bf4ecb)) ## [0.14.0](https://github.com/openlinker-project/openlinker/compare/v0.13.0...v0.14.0) (2026-10-06) ### Features * **bench:** 'Change size' on the pack bench label card ([#3664](https://github.com/openlinker-project/openlinker/issues/3664)) ([d858c0f](https://github.com/openlinker-project/openlinker/commit/d858c0f8b6a926364abe1f19edf5c1dcff2e55c9)) * **bench:** packers can change the parcel size and replace the label ([#3663](https://github.com/openlinker-project/openlinker/issues/3663)) ([343b1e5](https://github.com/openlinker-project/openlinker/commit/343b1e58c4729625fb7a6d5f5bf0c3e70ead6c19)) * **bench:** the pack bench uses the application topbar ([#3658](https://github.com/openlinker-project/openlinker/issues/3658)) ([9a4ae69](https://github.com/openlinker-project/openlinker/commit/9a4ae694f63c62112ef6c3ba7aaea1f17b2635ca)) * **connections:** archive and restore a disabled connection ([#3665](https://github.com/openlinker-project/openlinker/issues/3665)) ([4639b29](https://github.com/openlinker-project/openlinker/commit/4639b291271fdf3358982cd76a584449d152fe9d)) * **connections:** flag a destination that packs and ships orders itself ([#2118](https://github.com/openlinker-project/openlinker/issues/2118)) ([#3672](https://github.com/openlinker-project/openlinker/issues/3672)) ([1a8ccce](https://github.com/openlinker-project/openlinker/commit/1a8ccce2dc0fa62067150a17ab05f92006050a48)) * **fulfillment:** closing a parcel tells the sales channel it shipped, with the tracking number ([#3627](https://github.com/openlinker-project/openlinker/issues/3627)) ([7c0be13](https://github.com/openlinker-project/openlinker/commit/7c0be1310d3766216372feee0e620ee335f8117a)) * **fulfillment:** fulfilment work detail page ([#3096](https://github.com/openlinker-project/openlinker/issues/3096)) ([#3632](https://github.com/openlinker-project/openlinker/issues/3632)) ([e710b59](https://github.com/openlinker-project/openlinker/commit/e710b59ef477c3c18017b7d3e87784adcc4d60ff)) * **orders:** order search, internal notes, tags, column presets and CSV/XLSX export ([#3633](https://github.com/openlinker-project/openlinker/issues/3633)) ([edce7dd](https://github.com/openlinker-project/openlinker/commit/edce7dd16ae9b38bad2af150b187f747e4749960)) * **platform:** migrations run on an empty database, sync job retention, dead-lettered stream entries and nightly backups ([#3631](https://github.com/openlinker-project/openlinker/issues/3631)) ([17aeb21](https://github.com/openlinker-project/openlinker/commit/17aeb21f461723a04290b84774f931991c373cd3)) * **products:** fill empty variant weight and dimensions from the shop on master sync ([#3660](https://github.com/openlinker-project/openlinker/issues/3660)) ([3b97389](https://github.com/openlinker-project/openlinker/commit/3b97389fb7faffaca2aa775c596231106bbf80a5)) * **shipping:** parcel profile per delivery method for automatic labels ([#3661](https://github.com/openlinker-project/openlinker/issues/3661)) ([9b062d0](https://github.com/openlinker-project/openlinker/commit/9b062d0c9b57b4ecc9bd491c893aedc0ef38b974)) * **users:** admin creates an account with a one-time password ([#3456](https://github.com/openlinker-project/openlinker/issues/3456)) ([#3504](https://github.com/openlinker-project/openlinker/issues/3504)) ([10af9a3](https://github.com/openlinker-project/openlinker/commit/10af9a3ceec969bc90ec195e6d4a0c41caf00cfa)) * **web,api:** OMS onboarding wizard - turn OpenLinker packing on from the UI ([#3457](https://github.com/openlinker-project/openlinker/issues/3457)) ([#3628](https://github.com/openlinker-project/openlinker/issues/3628)) ([3e4fd70](https://github.com/openlinker-project/openlinker/commit/3e4fd70d8f4ff11d8a48af749e13ec50903e6d61)) * **web:** make the connection channel pill one clickable chip ([#3673](https://github.com/openlinker-project/openlinker/issues/3673)) ([2dbe581](https://github.com/openlinker-project/openlinker/commit/2dbe581c7359a430e8565dd0cbd3781fe9104fe1)) * **web:** OMS setup wizard as seven steps, continuation of [#3457](https://github.com/openlinker-project/openlinker/issues/3457) ([#3668](https://github.com/openlinker-project/openlinker/issues/3668)) ([3c92c0d](https://github.com/openlinker-project/openlinker/commit/3c92c0d3d4b45663dc0d7fe41cebc3ef9533aa7b)) * **web:** rename Document routing to Sales documents routing and link to it from /sales-documents ([#3659](https://github.com/openlinker-project/openlinker/issues/3659)) ([28facad](https://github.com/openlinker-project/openlinker/commit/28facad64a783b63ed0ce1d2ace8ae7ebc8445b0)) * **web:** set a default parcel per delivery method and prefill label forms from it ([#3662](https://github.com/openlinker-project/openlinker/issues/3662)) ([762aa24](https://github.com/openlinker-project/openlinker/commit/762aa2468f25595c8b6bf2fc020528dbe7fb823f)) ### Bug Fixes * **bench:** name the order's sales document in every status, receipts included ([#3666](https://github.com/openlinker-project/openlinker/issues/3666)) ([dd390f8](https://github.com/openlinker-project/openlinker/commit/dd390f86750b48afc42e56d8c657375e3e915e27)) * **bench:** show the order's receipt or invoice in every status on the pack bench ([#3667](https://github.com/openlinker-project/openlinker/issues/3667)) ([2f4f549](https://github.com/openlinker-project/openlinker/commit/2f4f549394d7a18e9535f738664c344369a46dc6)) * **eparagony:** declare EparagonyInvoicingAdapter a DocumentNumberConsumer ([#3501](https://github.com/openlinker-project/openlinker/issues/3501)) ([146e60c](https://github.com/openlinker-project/openlinker/commit/146e60c8329f99f08752f60fe9c75d1206dc8a9f)) * **integrations:** no duplicate labels, offers or orders when a write is retried; correct WooCommerce and PrestaShop order creation ([#3630](https://github.com/openlinker-project/openlinker/issues/3630)) ([64f91a8](https://github.com/openlinker-project/openlinker/commit/64f91a89c04b5e0242bee36c50156a04686bbbb8)) * **inventory:** count a routed order's reserved units exactly once ([#3480](https://github.com/openlinker-project/openlinker/issues/3480)) ([#3491](https://github.com/openlinker-project/openlinker/issues/3491)) ([c5bce15](https://github.com/openlinker-project/openlinker/commit/c5bce15d6c6568382d7b2fb362c7396074690301)) * **inventory:** give stock back to the product master on routed-order cancellation ([#3479](https://github.com/openlinker-project/openlinker/issues/3479)) ([#3493](https://github.com/openlinker-project/openlinker/issues/3493)) ([15c57b8](https://github.com/openlinker-project/openlinker/commit/15c57b82b1a7a1791ee530ccf6ee92eb42c9b276)) * **inventory:** lower product-master stock once per routed order line ([#3453](https://github.com/openlinker-project/openlinker/issues/3453)) ([#3489](https://github.com/openlinker-project/openlinker/issues/3489)) ([a678d56](https://github.com/openlinker-project/openlinker/commit/a678d5608697e7218724a52252e61eeadac422b8)) * **listings:** readiness/submit-gate drift + operator override for checksum-invalid EAN ([#3495](https://github.com/openlinker-project/openlinker/issues/3495)) ([a652d8a](https://github.com/openlinker-project/openlinker/commit/a652d8adfe6cdc76505a6339df14618445e4846f)) * **oms:** route on live stock only, never on stale inventory rows ([#3481](https://github.com/openlinker-project/openlinker/issues/3481)) ([#3499](https://github.com/openlinker-project/openlinker/issues/3499)) ([cc6607c](https://github.com/openlinker-project/openlinker/commit/cc6607ca7e5ded7aee780cca5235e4963721c028)) * **orders:** do not route an order the product master already had ([#3455](https://github.com/openlinker-project/openlinker/issues/3455)) ([#3497](https://github.com/openlinker-project/openlinker/issues/3497)) ([c73bc9d](https://github.com/openlinker-project/openlinker/commit/c73bc9d232e04b535b2dfbdda9e575af914a29e6)) * **orders:** do not route orders another system has been told to ship ([#3488](https://github.com/openlinker-project/openlinker/issues/3488)) ([#3496](https://github.com/openlinker-project/openlinker/issues/3496)) ([f61ce22](https://github.com/openlinker-project/openlinker/commit/f61ce2260afa9da2def71f2fe1907e1379e9befb)) * **orders:** do not route orders placed in the operator's own shop ([#3487](https://github.com/openlinker-project/openlinker/issues/3487)) ([#3490](https://github.com/openlinker-project/openlinker/issues/3490)) ([ec53478](https://github.com/openlinker-project/openlinker/commit/ec53478e8995ce50a45884ab3377929e707632b5)) * **orders:** hold an order the OMS router cannot place instead of mirroring it ([#3485](https://github.com/openlinker-project/openlinker/issues/3485)) ([#3503](https://github.com/openlinker-project/openlinker/issues/3503)) ([0018bfa](https://github.com/openlinker-project/openlinker/commit/0018bfad6738bac7c9ebe2a8a6c627d3f98762f6)) * **returns:** restock a returned line in the master that owns it ([#3486](https://github.com/openlinker-project/openlinker/issues/3486)) ([#3498](https://github.com/openlinker-project/openlinker/issues/3498)) ([01db5c6](https://github.com/openlinker-project/openlinker/commit/01db5c6d7ba8e70cb4b44a9d04ca5d68cb5d72ad)) ## [0.13.0](https://github.com/openlinker-project/openlinker/compare/v0.12.0...v0.13.0) (2026-09-29) ### Features * **bench,fulfillment:** mockup-parity Interface layer — widened projections, activity log, self-claim, packed-today, masked buyer name ([#3401](https://github.com/openlinker-project/openlinker/issues/3401)) ([#3438](https://github.com/openlinker-project/openlinker/issues/3438)) ([3acef84](https://github.com/openlinker-project/openlinker/commit/3acef8476e1442f468c8c3fb35db8633daed6394)) * **bench:** add the C keyboard shortcut (scope narrowed after auditing the real feature) ([#3363](https://github.com/openlinker-project/openlinker/issues/3363)) ([91a746c](https://github.com/openlinker-project/openlinker/commit/91a746cb72afce737dee013b9650e3329abeed47)) * **bench:** render the assigned/unassigned/assignment-only rail distinction ([#3374](https://github.com/openlinker-project/openlinker/issues/3374)) ([b18f4c3](https://github.com/openlinker-project/openlinker/commit/b18f4c3761ccd4d674c94ee5df312c3e6ca7548f)) * **connections:** add stock-location override field to connection form ([#3326](https://github.com/openlinker-project/openlinker/issues/3326)) ([b18033d](https://github.com/openlinker-project/openlinker/commit/b18033dc87da298dda59cac6b874c9c7cddcec68)) * **core:** mockup-parity CORE schema — bin location, weight/dims, undo-scan, presence ([#3401](https://github.com/openlinker-project/openlinker/issues/3401)) ([#3435](https://github.com/openlinker-project/openlinker/issues/3435)) ([99f5c20](https://github.com/openlinker-project/openlinker/commit/99f5c203d0e999b183a17af965bc11b89a595aab)) * **eparagony:** issue corrective invoices ([#3332](https://github.com/openlinker-project/openlinker/issues/3332)) ([b418ffa](https://github.com/openlinker-project/openlinker/commit/b418ffaa70de5d08e5d5b86d2a7d152d6471ec59)) * **fulfillment:** add FulfillmentWork assignment columns + repository writers (ADR-074) ([#3360](https://github.com/openlinker-project/openlinker/issues/3360)) ([f196564](https://github.com/openlinker-project/openlinker/commit/f19656429b6f2ed6c1d0eb8f07d2009b1f8bf6fc)) * **fulfillment:** Assign Packing Work operator screen ([#3368](https://github.com/openlinker-project/openlinker/issues/3368)) ([a1bd4a7](https://github.com/openlinker-project/openlinker/commit/a1bd4a797e587613daa7a2a3d4fd3d3efed39543)) * **fulfillment:** assignment endpoint, worklist projection, server-side claim guard ([#3361](https://github.com/openlinker-project/openlinker/issues/3361)) ([78009bb](https://github.com/openlinker-project/openlinker/commit/78009bb9e03f5fc16207b0767a41661a51437b90)) * **fulfillment:** pack-bench mockup parity + one merged /fulfillment screen ([#3401](https://github.com/openlinker-project/openlinker/issues/3401)) ([#3439](https://github.com/openlinker-project/openlinker/issues/3439)) ([fbae25c](https://github.com/openlinker-project/openlinker/commit/fbae25c1bb1770ae175d5611a4b33df30444cc31)) * **listings:** replace CHIP_COUNTS_LIMIT with a real counts-by-connection endpoint ([#3387](https://github.com/openlinker-project/openlinker/issues/3387)) ([5510f6a](https://github.com/openlinker-project/openlinker/commit/5510f6ae407625bacceba49e04f29e91d60a1a23)), closes [#3325](https://github.com/openlinker-project/openlinker/issues/3325) * **listings:** resolve a destination's real currency for price-change detection ([#3328](https://github.com/openlinker-project/openlinker/issues/3328)) ([b1ab2eb](https://github.com/openlinker-project/openlinker/commit/b1ab2eb17c7a066d3831219cc8997737ee72e77b)) * **returns:** correction-proposal entry point + orphan placeholder ([#3379](https://github.com/openlinker-project/openlinker/issues/3379)) ([015837a](https://github.com/openlinker-project/openlinker/commit/015837abed860d09aacd0a93aab97052897eb637)) * **returns:** correction-proposal headline + breakdown panel ([#3376](https://github.com/openlinker-project/openlinker/issues/3376)) ([131f0a6](https://github.com/openlinker-project/openlinker/commit/131f0a66829aa7c02f3c485a5be73ec46e6577ad)) * **returns:** correction-proposal record API client ([#3088](https://github.com/openlinker-project/openlinker/issues/3088)) ([#3301](https://github.com/openlinker-project/openlinker/issues/3301)) ([b869c39](https://github.com/openlinker-project/openlinker/commit/b869c399af082fee6ae9a2f2c141b980b2a63797)) * **returns:** correction-proposal record mutation hook ([#3375](https://github.com/openlinker-project/openlinker/issues/3375)) ([653f930](https://github.com/openlinker-project/openlinker/commit/653f93088aa78e86a41b79db6ac1a86ba58ebf9c)) * **returns:** distinct badges + a real remedy link for the 4 non-proposing correction-proposal outcomes ([#3093](https://github.com/openlinker-project/openlinker/issues/3093)) ([#3378](https://github.com/openlinker-project/openlinker/issues/3378)) ([45f7b18](https://github.com/openlinker-project/openlinker/commit/45f7b1811591b174b17204b6496345f878b51be7)) * **returns:** narrow the correction matcher onto ReturnLine.resolvedOrderLineId ([#3313](https://github.com/openlinker-project/openlinker/issues/3313)) ([6dc871f](https://github.com/openlinker-project/openlinker/commit/6dc871fa9e1cb1035889dbe87f673d4605fed829)) * **returns:** record-for-review action + recorded state ([#3092](https://github.com/openlinker-project/openlinker/issues/3092)) ([#3377](https://github.com/openlinker-project/openlinker/issues/3377)) ([85ce338](https://github.com/openlinker-project/openlinker/commit/85ce3381f3c68db4cf31672e53cc2de9b6eca878)) * **sales-documents:** invoice clearance filters, rule dry-run, and dual-role connections ([#3320](https://github.com/openlinker-project/openlinker/issues/3320)) ([a6069dd](https://github.com/openlinker-project/openlinker/commit/a6069dd0e11f50c9c473333ec6b05ceedc56f379)) * **subiekt:** crash-recovery locator, payment status read, bridgeBaseUrl uniqueness guard ([#3398](https://github.com/openlinker-project/openlinker/issues/3398)) ([9315b8d](https://github.com/openlinker-project/openlinker/commit/9315b8db5f6ed44f686c162e653eec473d7108ac)) * **subiekt:** Subiekt GT as product master, inventory master, order source, order destination and invoicing provider ([#3365](https://github.com/openlinker-project/openlinker/issues/3365)) ([31854b9](https://github.com/openlinker-project/openlinker/commit/31854b990eb78970aa86079c78fb155a1787cef4)) * **web:** give DataTable per-row identity, migrate the price-changes queue onto it ([#3327](https://github.com/openlinker-project/openlinker/issues/3327)) ([bd5a2c4](https://github.com/openlinker-project/openlinker/commit/bd5a2c4e02152d6f75a55316dabdc142f7ab369d)) * **web:** hide OMS routing UI behind VITE_OL_OMS_ROUTING_UI_ENABLED ([#3634](https://github.com/openlinker-project/openlinker/issues/3634)) ([#3635](https://github.com/openlinker-project/openlinker/issues/3635)) ([f7c09eb](https://github.com/openlinker-project/openlinker/commit/f7c09eb232a847d6b96910bfde9589a841808bdb)) * **web:** pack bench reachable from the app chrome for the packer role ([#3244](https://github.com/openlinker-project/openlinker/issues/3244)) ([f13b534](https://github.com/openlinker-project/openlinker/commit/f13b534056d384bde8f1715906db03632d4628b7)) ### Bug Fixes * **eparagony:** memoize HTTP client per connection to cut redundant /auth/token calls ([#3383](https://github.com/openlinker-project/openlinker/issues/3383)) ([5d470b9](https://github.com/openlinker-project/openlinker/commit/5d470b97eb304f748b9153d797d1915e9814c408)), closes [#3382](https://github.com/openlinker-project/openlinker/issues/3382) * **price-changes:** scope toast-copy assertions to avoid Radix announcer duplicate ([#3315](https://github.com/openlinker-project/openlinker/issues/3315)) ([bc7bd61](https://github.com/openlinker-project/openlinker/commit/bc7bd618ec5a7ea86643640c1583abb6dece4f3b)) * **returns:** refuse a second restock dispose while one is already blocked ([#3477](https://github.com/openlinker-project/openlinker/issues/3477)) ([c3dccc1](https://github.com/openlinker-project/openlinker/commit/c3dccc180bb84f57f9bb46b963fc032158d66382)) * **returns:** resolve restock target via resolvedOrderLineId, fall back to sku ([#3451](https://github.com/openlinker-project/openlinker/issues/3451)) ([113d192](https://github.com/openlinker-project/openlinker/commit/113d19262bb33b4a9162495731d1a1cf3715146a)) * **sales-documents:** warn at pick time instead of converging the destination predicate ([#3324](https://github.com/openlinker-project/openlinker/issues/3324)) ([803dd53](https://github.com/openlinker-project/openlinker/commit/803dd53bb45dac330be9ac982e7a3bbda71dbc42)) * **web:** eparagony.pl unrecognised-select can now be fixed by re-selecting its own recommended option ([#3318](https://github.com/openlinker-project/openlinker/issues/3318)) ([81333c9](https://github.com/openlinker-project/openlinker/commit/81333c9adac197fd129be2cffb28db8d0231d586)) * **woocommerce:** resolve store currency for ProductMaster reads ([#3317](https://github.com/openlinker-project/openlinker/issues/3317)) ([3868e0f](https://github.com/openlinker-project/openlinker/commit/3868e0fc39c2e37c78ec36358b68b7830dec8e67)) ## [0.12.0](https://github.com/openlinker-project/openlinker/compare/v0.11.0...v0.12.0) (2026-09-21) ### Features * **eparagony:** eparagony issues invoices through the Invoicing capability ([#3304](https://github.com/openlinker-project/openlinker/issues/3304)) ([0281245](https://github.com/openlinker-project/openlinker/commit/028124508803bd1224b3a12550933f5050c0342c)) * **inventory:** close mockup-parity gaps on the duplicate-positions page ([#3264](https://github.com/openlinker-project/openlinker/issues/3264)) ([a0d1997](https://github.com/openlinker-project/openlinker/commit/a0d199702929bc682ab9a16f167eff60a395273a)) * **inventory:** duplicate-positions API client + query hook ([#3251](https://github.com/openlinker-project/openlinker/issues/3251)) ([df940b6](https://github.com/openlinker-project/openlinker/commit/df940b6414e4cfdbab38b083e8fd03cbbe31ec8b)) * **inventory:** duplicate-positions page with readiness KPI strip ([#3252](https://github.com/openlinker-project/openlinker/issues/3252)) ([4ffb39d](https://github.com/openlinker-project/openlinker/commit/4ffb39d7df1408f71037b13935684e627d02e0e8)) * **inventory:** enrich duplicate-positions response with product/variant/connection/location display names ([#3249](https://github.com/openlinker-project/openlinker/issues/3249)) ([9f0e02f](https://github.com/openlinker-project/openlinker/commit/9f0e02f04c9f7f0ac6a6adb3107de13ce5abc80b)) * **inventory:** expandable grouped table (per-row inventory_items detail) ([#3255](https://github.com/openlinker-project/openlinker/issues/3255)) ([c36ee2b](https://github.com/openlinker-project/openlinker/commit/c36ee2ba253b559b16286df72db51a79b5701cc7)) * **inventory:** expose [#2317](https://github.com/openlinker-project/openlinker/issues/2317) provenance-backfill completion state for the duplicate-positions readiness gate ([#3250](https://github.com/openlinker-project/openlinker/issues/3250)) ([fc9ddd4](https://github.com/openlinker-project/openlinker/commit/fc9ddd42d83ca17ea8c6d79e0bf2e3f7b9d361d1)) * **inventory:** nav entry under Diagnostics ([#3261](https://github.com/openlinker-project/openlinker/issues/3261)) ([9b7f2a5](https://github.com/openlinker-project/openlinker/commit/9b7f2a5606a8d63f222cf27e93a7bbcba5e9984a)) * **inventory:** truncated-report banner state ([#3256](https://github.com/openlinker-project/openlinker/issues/3256)) ([ddeb4ef](https://github.com/openlinker-project/openlinker/commit/ddeb4efb4724840ecc7ca4c7d722312ce42712aa)) * **orders,api:** merge invoices and fiscal receipts into GET /sales-documents ([#3308](https://github.com/openlinker-project/openlinker/issues/3308)) ([a7500ba](https://github.com/openlinker-project/openlinker/commit/a7500ba63d5b85104f8585a1d3bed8f095e34528)) * **returns:** approve dialog for operator-authored returns ([#3283](https://github.com/openlinker-project/openlinker/issues/3283)) ([86e3657](https://github.com/openlinker-project/openlinker/commit/86e3657d3e6b7ccaa4f0f7be895168f816417b36)) * **returns:** entry point from the returns list/detail ([#3285](https://github.com/openlinker-project/openlinker/issues/3285)) ([9c90a33](https://github.com/openlinker-project/openlinker/commit/9c90a33b71c3c0771304e30b7905cf42cbf8e84d)) * **returns:** match-to-order dialog + unknown-order/already-attributed handling ([#3281](https://github.com/openlinker-project/openlinker/issues/3281)) ([476c705](https://github.com/openlinker-project/openlinker/commit/476c7057eca7b8db6dbb2dbd3265a0f3ae461b53)) * **returns:** mutation hooks + cache invalidation ([#3080](https://github.com/openlinker-project/openlinker/issues/3080)) ([#3279](https://github.com/openlinker-project/openlinker/issues/3279)) ([26635f2](https://github.com/openlinker-project/openlinker/commit/26635f29389ca5ffe546f6e5c8b9f7f7abb72d30)) * **returns:** orphan-returns worklist (needs-order / needs-approval groups) ([#3280](https://github.com/openlinker-project/openlinker/issues/3280)) ([a89a59f](https://github.com/openlinker-project/openlinker/commit/a89a59fbfe41bf9dbcb78f8f98c229a08722b189)) * **returns:** record-a-return-by-hand dialog ([#3284](https://github.com/openlinker-project/openlinker/issues/3284)) ([978a621](https://github.com/openlinker-project/openlinker/commit/978a621675cbbb9e8271f6031ce100552cca815a)) * **returns:** write API client (record, authorize, match-order) ([#3278](https://github.com/openlinker-project/openlinker/issues/3278)) ([366d302](https://github.com/openlinker-project/openlinker/commit/366d302a28e44629dc2827d8a245840a76207759)) * **sales-documents:** merge invoices and fiscal receipts into one operator list ([#3309](https://github.com/openlinker-project/openlinker/issues/3309)) ([f226976](https://github.com/openlinker-project/openlinker/commit/f226976903ab7a2a0bc516f58526359d21c54c3b)) * **sales-documents:** refuse a colliding rule in the composer, before the save ([#3253](https://github.com/openlinker-project/openlinker/issues/3253)) ([3da1c3a](https://github.com/openlinker-project/openlinker/commit/3da1c3afe99cb537273c6db14753f962b51276e1)) * **web:** give the eparagony.pl connection config real form fields ([#3268](https://github.com/openlinker-project/openlinker/issues/3268)) ([f81d746](https://github.com/openlinker-project/openlinker/commit/f81d7464f383639e522606052b73b8765ce8c2db)) * **web:** show release version instead of static "DEV" text in top-left badge ([#3288](https://github.com/openlinker-project/openlinker/issues/3288)) ([e1ae0ae](https://github.com/openlinker-project/openlinker/commit/e1ae0aecece5b6e0105b91be52b8cb0706c7bcc8)) ### Bug Fixes * **invariants:** floor the scanned-file/root/phrase count on six check-* guards so a path or wording change fails loudly ([#3303](https://github.com/openlinker-project/openlinker/issues/3303)) ([1e4e628](https://github.com/openlinker-project/openlinker/commit/1e4e628de86d2e230b2e1d3e631f8c04db0f5134)) * **invariants:** stop the mirror-guard array parser truncating on a bracket inside a comment ([#3305](https://github.com/openlinker-project/openlinker/issues/3305)) ([4486f3e](https://github.com/openlinker-project/openlinker/commit/4486f3e3e34295d35f60376709905a2de10d7217)), closes [#3002](https://github.com/openlinker-project/openlinker/issues/3002) ### Performance Improvements * **ci:** three fixes for the Integration Tests job - per-worker databases, duplicate type-checking, and an oversized worker count (about 3x faster) ([#3276](https://github.com/openlinker-project/openlinker/issues/3276)) ([c3db337](https://github.com/openlinker-project/openlinker/commit/c3db3378a0b0e8292a689ac22366575dbeeef9b0)) * **ci:** three fixes for the Test job (unit tests) - cache, queueing, and a starved frontend (about 4x faster) ([#3275](https://github.com/openlinker-project/openlinker/issues/3275)) ([b89bf7c](https://github.com/openlinker-project/openlinker/commit/b89bf7c06d6a4cbb37ba18b5a58552c3cd0f4550)) ## [0.11.0](https://github.com/openlinker-project/openlinker/compare/v0.10.0...v0.11.0) (2026-09-15) ### Features * **api:** connection pricing & sync settings endpoints ([#3163](https://github.com/openlinker-project/openlinker/issues/3163)) ([b700499](https://github.com/openlinker-project/openlinker/commit/b7004996ff569dd15cff5b45596de8979b1ca3c1)) * **api:** price-changes queue endpoints (list, accept, ignore, edit) ([#3162](https://github.com/openlinker-project/openlinker/issues/3162)) ([6d0d7f3](https://github.com/openlinker-project/openlinker/commit/6d0d7f313b7f5f3fe8510b97961b341024d773d4)) * **dx:** enforce unique ADR numbers via check:invariants ([#3036](https://github.com/openlinker-project/openlinker/issues/3036)) ([93432c8](https://github.com/openlinker-project/openlinker/commit/93432c80641cc0d9bc131016e17c9e8c7e6844b2)) * **fiscalization:** send the buyer tax number on a fiscal receipt ([#3220](https://github.com/openlinker-project/openlinker/issues/3220)) ([05acf27](https://github.com/openlinker-project/openlinker/commit/05acf279b253173e750f50b7971c24f284990ede)) * **fulfillment:** reap dispatches whose holder never answered ([#2712](https://github.com/openlinker-project/openlinker/issues/2712)) ([#3012](https://github.com/openlinker-project/openlinker/issues/3012)) ([6e0f8f0](https://github.com/openlinker-project/openlinker/commit/6e0f8f0c693e657204f80cc5174d35a9924b3aa9)) * **fulfillment:** reconcile a shipped work whose dispatch relay never landed ([#2728](https://github.com/openlinker-project/openlinker/issues/2728)) ([#3018](https://github.com/openlinker-project/openlinker/issues/3018)) ([42cc86d](https://github.com/openlinker-project/openlinker/commit/42cc86dded9e75d0edec4a1340cba11356c805c8)) * **infakt:** add per-connection defaultSaleType for non-PL invoice issuance, with a diagnosis hint for the missing-config case ([#2995](https://github.com/openlinker-project/openlinker/issues/2995)) ([a5a6ef4](https://github.com/openlinker-project/openlinker/commit/a5a6ef4047f4a98f2835a92dad221283f4ec3f89)) * **inventory:** locations CRUD UI — full operator-facing management for inventory_locations ([#3198](https://github.com/openlinker-project/openlinker/issues/3198)) ([de638ea](https://github.com/openlinker-project/openlinker/commit/de638ea06b1edda8bb184f72f2a0f4c9ba18f579)) * **inventory:** per-connection stock-location override for masters that never report one ([#3208](https://github.com/openlinker-project/openlinker/issues/3208)) ([8f7c2d4](https://github.com/openlinker-project/openlinker/commit/8f7c2d41e2d894cd45588ce877ef4cc76c62198f)) * **listings:** price-change detection + currency-mismatch blocking ([#3159](https://github.com/openlinker-project/openlinker/issues/3159)) ([de04cf0](https://github.com/openlinker-project/openlinker/commit/de04cf0114d871fe77351e3fd3ab5a4e7c8c5ff1)) * **listings:** price-change episode schema + per-source pricing rule model ([#3158](https://github.com/openlinker-project/openlinker/issues/3158)) ([846fcd1](https://github.com/openlinker-project/openlinker/commit/846fcd1f9c74ae57aa93555fd90dd014e6a7a575)) * **listings:** refuse a disproportionate manual price override server-side ([#3236](https://github.com/openlinker-project/openlinker/issues/3236)) ([667310c](https://github.com/openlinker-project/openlinker/commit/667310c67a872abe660b731364737385b6a28f97)), closes [#3222](https://github.com/openlinker-project/openlinker/issues/3222) * **oms:** sourcing rules admin UI - view, author and order the router's ruleset ([#3243](https://github.com/openlinker-project/openlinker/issues/3243)) ([9788f1d](https://github.com/openlinker-project/openlinker/commit/9788f1d71ec62b666465c6c900e00c6baf52351d)) * **returns:** resolve a return line to its order line at ingestion ([#3172](https://github.com/openlinker-project/openlinker/issues/3172)) ([84870ac](https://github.com/openlinker-project/openlinker/commit/84870ac95921f7fde81b9d548bfd5bb700be2b38)) * **sales-documents:** inline amount and currency on a rule condition ([#3241](https://github.com/openlinker-project/openlinker/issues/3241)) ([e3a8a66](https://github.com/openlinker-project/openlinker/commit/e3a8a661a87b09875e2e8b3a7d45f9d0e910dc88)), closes [#3189](https://github.com/openlinker-project/openlinker/issues/3189) * **sales-documents:** record and surface the matched routing rule ([#3219](https://github.com/openlinker-project/openlinker/issues/3219)) ([542b551](https://github.com/openlinker-project/openlinker/commit/542b55164cb0ce95be7c922d9c9dde970554b063)) * **shipping:** surface a repeatedly-failing waybill relay instead of logging it forever ([#3013](https://github.com/openlinker-project/openlinker/issues/3013)) ([3af5833](https://github.com/openlinker-project/openlinker/commit/3af583340f861c636c598641652ffe972cea62f3)), closes [#2073](https://github.com/openlinker-project/openlinker/issues/2073) * **web:** accept/edit dialogs + bulk apply with live progress ([#3165](https://github.com/openlinker-project/openlinker/issues/3165)) ([4146290](https://github.com/openlinker-project/openlinker/commit/41462906dd1778724aa7bee9e581927701426671)), closes [#3148](https://github.com/openlinker-project/openlinker/issues/3148) * **web:** connection Pricing & sync settings page ([#3166](https://github.com/openlinker-project/openlinker/issues/3166)) ([69bd74b](https://github.com/openlinker-project/openlinker/commit/69bd74bcab3213eb31f15418ec840d7c8dc1d762)), closes [#3149](https://github.com/openlinker-project/openlinker/issues/3149) * **web:** mobile card view for the price-changes queue ([#3238](https://github.com/openlinker-project/openlinker/issues/3238)) ([b801853](https://github.com/openlinker-project/openlinker/commit/b8018538c2dc3cc17bd0296619bad9c0ea081ef1)), closes [#3223](https://github.com/openlinker-project/openlinker/issues/3223) * **web:** Price changes tab + review queue table ([#3164](https://github.com/openlinker-project/openlinker/issues/3164)) ([558ed8c](https://github.com/openlinker-project/openlinker/commit/558ed8cb0c11c2c3f27698462c3c8ae04b5c80d1)) * **web:** recently-applied-automatically note + dialog ([#3168](https://github.com/openlinker-project/openlinker/issues/3168)) ([6d72276](https://github.com/openlinker-project/openlinker/commit/6d722764d713332f3d4ccc41656d81c696e1bc54)), closes [#3151](https://github.com/openlinker-project/openlinker/issues/3151) * **web:** show the buyer tax ID on the order ([#3211](https://github.com/openlinker-project/openlinker/issues/3211)) ([b334376](https://github.com/openlinker-project/openlinker/commit/b3343761b762810c5474987596e8c792ecee919b)) * **web:** source connection pricing rollup + pricing-rules picker ([#3167](https://github.com/openlinker-project/openlinker/issues/3167)) ([45fd98d](https://github.com/openlinker-project/openlinker/commit/45fd98db7a562c2243afb8e6c2d9ec53009e0d72)), closes [#3150](https://github.com/openlinker-project/openlinker/issues/3150) * **web:** warn when a sales-document rule's destination issues nothing ([#3209](https://github.com/openlinker-project/openlinker/issues/3209)) ([de3bea7](https://github.com/openlinker-project/openlinker/commit/de3bea7b2b7b14a32cac752aa493a79c707b50fa)) ### Bug Fixes * **auth:** stop leaking username/email existence via registration errors ([#3157](https://github.com/openlinker-project/openlinker/issues/3157)) ([63048bd](https://github.com/openlinker-project/openlinker/commit/63048bd32ffa6ce7308132052b71c0b34345c56b)) * **connections:** count document registrations in connection health ([#3212](https://github.com/openlinker-project/openlinker/issues/3212)) ([5430f09](https://github.com/openlinker-project/openlinker/commit/5430f09a97ff97132edac0d576854193d01d1f9d)) * **infakt:** normalize baseUrl override to include /api/v3 and log probe failures ([#2994](https://github.com/openlinker-project/openlinker/issues/2994)) ([2f2875e](https://github.com/openlinker-project/openlinker/commit/2f2875e4aaaf678a15a585e56886d63ceda778de)) * **infakt:** refuse a bare-host baseUrl override missing /api/v3 at save time ([#3128](https://github.com/openlinker-project/openlinker/issues/3128)) ([2d43176](https://github.com/openlinker-project/openlinker/commit/2d431761112e64e7b41c50461810cbe1c9a8aa0b)) * **inventory:** take the position lock FOR NO KEY UPDATE and re-script the reservation repository spec ([#3245](https://github.com/openlinker-project/openlinker/issues/3245)) ([#3246](https://github.com/openlinker-project/openlinker/issues/3246)) ([edfd601](https://github.com/openlinker-project/openlinker/commit/edfd601dd358993f4483b1ca564ebfb9a7b91a40)) * **listings:** taxonomy reads report connection-not-found/disabled as 404/409, not 422 ([#3038](https://github.com/openlinker-project/openlinker/issues/3038)) ([7892923](https://github.com/openlinker-project/openlinker/commit/78929235151ade0b0f26cf99967e1a4f2fe27ea9)) * **migrations:** renumber price-change-apply migration to 1881000000000 ([6d0d7f3](https://github.com/openlinker-project/openlinker/commit/6d0d7f313b7f5f3fe8510b97961b341024d773d4)) * **migrations:** renumber price-change-apply migration to 1881000000000 ([de04cf0](https://github.com/openlinker-project/openlinker/commit/de04cf0114d871fe77351e3fd3ab5a4e7c8c5ff1)) * **orders:** persist a durable early-cancellation signal ([#2069](https://github.com/openlinker-project/openlinker/issues/2069)) ([#3035](https://github.com/openlinker-project/openlinker/issues/3035)) ([8703bd9](https://github.com/openlinker-project/openlinker/commit/8703bd92d78576cd565c5e33171e427a32acc8c8)) * **sales-documents:** unify country default to one row per country ([#3210](https://github.com/openlinker-project/openlinker/issues/3210)) ([d3db650](https://github.com/openlinker-project/openlinker/commit/d3db6502ed2b03f7de0d306f8889430e4ba8aa1a)) * **web/analytics:** confirm before turning on tax-rate-inclusion toggle ([#2993](https://github.com/openlinker-project/openlinker/issues/2993)) ([84300dd](https://github.com/openlinker-project/openlinker/commit/84300dd4573274c4218ff6ef12dae56ae0eabb67)) * **worker:** resolve AI suggestion channel from the connection, not the literal 'allegro' ([#3027](https://github.com/openlinker-project/openlinker/issues/3027)) ([5b6dc70](https://github.com/openlinker-project/openlinker/commit/5b6dc70eb4f60e4dfceb42e0a568d9fbd73d3aa3)) ### Performance Improvements * **orders:** bound tax coverage candidate fetch ([#3000](https://github.com/openlinker-project/openlinker/issues/3000)) ([b9d7847](https://github.com/openlinker-project/openlinker/commit/b9d78474ffc39e26d75bb6587b887ad7dfcc3ed4)) * the paginated total becomes a second stage ([#2943](https://github.com/openlinker-project/openlinker/issues/2943)) ([#2957](https://github.com/openlinker-project/openlinker/issues/2957)) ([9c6440f](https://github.com/openlinker-project/openlinker/commit/9c6440f1ba2b88ce4ffd726ac46e161a066d2c21)) ## [0.10.0](https://github.com/openlinker-project/openlinker/compare/v0.9.0...v0.10.0) (2026-09-07) ### ⚠ BREAKING CHANGES * **sales-documents:** POST /fiscal-registrations now answers 202 Accepted with AcceptedFiscalRegistrationResponseDto instead of 200 with FiscalRegistrationResponseDto. Callers must poll the registration-status read to learn the outcome. * **oms:** the `locationId` propagation skip is retired ([#2324](https://github.com/openlinker-project/openlinker/issues/2324)). An inventory write naming a `locationId` now propagates to marketplaces; previously it logged `inventory_write_propagation_skipped_non_default_location` and enqueued nothing, so the channel kept whatever a pooled write last sent. No adapter in this repository is affected — WooCommerce and PrestaShop both emit `locationId: undefined`. Only an in-house or out-of-tree `InventoryMaster` adapter returning a real `locationId` changes behaviour; such connections have had their channel stock silently frozen, and their next write publishes the true aggregate, possibly as a large single-step correction in either direction. Opt out per adapter by returning `locationId: undefined`. Full procedure and the detection query: `docs/operations/inventory-location-propagation.md`. * **web:** POST /fiscal-registrations now answers 202 Accepted with AcceptedFiscalRegistrationResponseDto instead of 200 with FiscalRegistrationResponseDto. The endpoint's own Swagger description previously told callers to read `status`/`failureMode` from the response body to learn the registration outcome - those fields no longer exist on the response. Callers must instead poll the registration-status read (GET .../registration-status) to learn the outcome. ### Features * **analytics:** the analytics page now shows shipping-excluded GMV, a full order cohort for Units Sold/AOV/Median, a shipping-excluded net-of-VAT Cancelled Value, a trend chart that follows the selected date range, and a page-level Net/Gross VAT-basis toggle wired end to end (including the headline Revenue card and channel table units), plus a display-currency picker, a Data Coverage panel with real remediation actions, and exclusion annotations across the KPI strip and channel/product tables — verified live against real order data via two independent full accuracy re-reviews, with sections reordered to sync -> needs attention -> data coverage and the metrics spec updated to document the toggle ([#2452](https://github.com/openlinker-project/openlinker/issues/2452), [#2457](https://github.com/openlinker-project/openlinker/issues/2457), [#2463](https://github.com/openlinker-project/openlinker/issues/2463), [#2467](https://github.com/openlinker-project/openlinker/issues/2467), [#2479](https://github.com/openlinker-project/openlinker/issues/2479), [#2892](https://github.com/openlinker-project/openlinker/issues/2892), [#2893](https://github.com/openlinker-project/openlinker/issues/2893), [#2894](https://github.com/openlinker-project/openlinker/issues/2894), [#2895](https://github.com/openlinker-project/openlinker/issues/2895), [#2899](https://github.com/openlinker-project/openlinker/issues/2899), [#2903](https://github.com/openlinker-project/openlinker/issues/2903), [#2906](https://github.com/openlinker-project/openlinker/issues/2906), [#2907](https://github.com/openlinker-project/openlinker/issues/2907), [#2908](https://github.com/openlinker-project/openlinker/issues/2908), [#2909](https://github.com/openlinker-project/openlinker/issues/2909), [#2910](https://github.com/openlinker-project/openlinker/issues/2910)) ([#2668](https://github.com/openlinker-project/openlinker/issues/2668)) ([a707e16](https://github.com/openlinker-project/openlinker/commit/a707e1651feeda2fa28a9e9bf09e75de85df9241)) * **fulfillment:** enqueue fulfillment.work.dispatch for routed work ([#2955](https://github.com/openlinker-project/openlinker/issues/2955)) ([#2974](https://github.com/openlinker-project/openlinker/issues/2974)) ([0906ceb](https://github.com/openlinker-project/openlinker/commit/0906ceb4166be410cd4faac0508e0d3d180ac9c3)) * **fulfillment:** wire the fulfilment router through one resolver port ([#2958](https://github.com/openlinker-project/openlinker/issues/2958)) ([ad6c2d1](https://github.com/openlinker-project/openlinker/commit/ad6c2d1ec2372b7e32ecc5613d0d7811cb6a152a)), closes [#2942](https://github.com/openlinker-project/openlinker/issues/2942) [#2869](https://github.com/openlinker-project/openlinker/issues/2869) * **oms:** sourcing-rules admin API for the router's ordered ruleset ([#2953](https://github.com/openlinker-project/openlinker/issues/2953)) ([#2973](https://github.com/openlinker-project/openlinker/issues/2973)) ([2048c2a](https://github.com/openlinker-project/openlinker/commit/2048c2aa4fbb8f235fc6f2bd47227a14a47e798c)) * **oms:** the OMS programme — Waves 0–3a ([#2675](https://github.com/openlinker-project/openlinker/issues/2675)) ([ee9fe6f](https://github.com/openlinker-project/openlinker/commit/ee9fe6fe45585bff6cae4ebb0a33b52cc23a48d2)), closes [#2282](https://github.com/openlinker-project/openlinker/issues/2282) [#2283](https://github.com/openlinker-project/openlinker/issues/2283) [#2284](https://github.com/openlinker-project/openlinker/issues/2284) [#2285](https://github.com/openlinker-project/openlinker/issues/2285) [#2286](https://github.com/openlinker-project/openlinker/issues/2286) [#2287](https://github.com/openlinker-project/openlinker/issues/2287) [#2288](https://github.com/openlinker-project/openlinker/issues/2288) [#2289](https://github.com/openlinker-project/openlinker/issues/2289) [#2298](https://github.com/openlinker-project/openlinker/issues/2298) [#2304](https://github.com/openlinker-project/openlinker/issues/2304) [#2305](https://github.com/openlinker-project/openlinker/issues/2305) [#2306](https://github.com/openlinker-project/openlinker/issues/2306) [#2307](https://github.com/openlinker-project/openlinker/issues/2307) [#2308](https://github.com/openlinker-project/openlinker/issues/2308) [#2309](https://github.com/openlinker-project/openlinker/issues/2309) [#2310](https://github.com/openlinker-project/openlinker/issues/2310) [#2311](https://github.com/openlinker-project/openlinker/issues/2311) [#2313](https://github.com/openlinker-project/openlinker/issues/2313) [#2314](https://github.com/openlinker-project/openlinker/issues/2314) [#2315](https://github.com/openlinker-project/openlinker/issues/2315) [#2316](https://github.com/openlinker-project/openlinker/issues/2316) [#2317](https://github.com/openlinker-project/openlinker/issues/2317) [#2319](https://github.com/openlinker-project/openlinker/issues/2319) [#2320](https://github.com/openlinker-project/openlinker/issues/2320) [#2321](https://github.com/openlinker-project/openlinker/issues/2321) [#2322](https://github.com/openlinker-project/openlinker/issues/2322) [#2323](https://github.com/openlinker-project/openlinker/issues/2323) [#2324](https://github.com/openlinker-project/openlinker/issues/2324) [#2327](https://github.com/openlinker-project/openlinker/issues/2327) [#2328](https://github.com/openlinker-project/openlinker/issues/2328) [#2329](https://github.com/openlinker-project/openlinker/issues/2329) [#2330](https://github.com/openlinker-project/openlinker/issues/2330) [#2332](https://github.com/openlinker-project/openlinker/issues/2332) [#2333](https://github.com/openlinker-project/openlinker/issues/2333) [#2334](https://github.com/openlinker-project/openlinker/issues/2334) [#2335](https://github.com/openlinker-project/openlinker/issues/2335) [#2336](https://github.com/openlinker-project/openlinker/issues/2336) [#2338](https://github.com/openlinker-project/openlinker/issues/2338) [#2339](https://github.com/openlinker-project/openlinker/issues/2339) [#2340](https://github.com/openlinker-project/openlinker/issues/2340) [#2341](https://github.com/openlinker-project/openlinker/issues/2341) [#2342](https://github.com/openlinker-project/openlinker/issues/2342) [#2343](https://github.com/openlinker-project/openlinker/issues/2343) [#2344](https://github.com/openlinker-project/openlinker/issues/2344) [#2345](https://github.com/openlinker-project/openlinker/issues/2345) [#2346](https://github.com/openlinker-project/openlinker/issues/2346) [#2347](https://github.com/openlinker-project/openlinker/issues/2347) [#2348](https://github.com/openlinker-project/openlinker/issues/2348) [#2349](https://github.com/openlinker-project/openlinker/issues/2349) [#2350](https://github.com/openlinker-project/openlinker/issues/2350) [#2351](https://github.com/openlinker-project/openlinker/issues/2351) [#2352](https://github.com/openlinker-project/openlinker/issues/2352) [#2353](https://github.com/openlinker-project/openlinker/issues/2353) [#2354](https://github.com/openlinker-project/openlinker/issues/2354) [#2355](https://github.com/openlinker-project/openlinker/issues/2355) [#2356](https://github.com/openlinker-project/openlinker/issues/2356) [#2357](https://github.com/openlinker-project/openlinker/issues/2357) [#2358](https://github.com/openlinker-project/openlinker/issues/2358) [#2359](https://github.com/openlinker-project/openlinker/issues/2359) [#2360](https://github.com/openlinker-project/openlinker/issues/2360) [#2361](https://github.com/openlinker-project/openlinker/issues/2361) [#2362](https://github.com/openlinker-project/openlinker/issues/2362) [#2363](https://github.com/openlinker-project/openlinker/issues/2363) [#2365](https://github.com/openlinker-project/openlinker/issues/2365) [#2366](https://github.com/openlinker-project/openlinker/issues/2366) [#2367](https://github.com/openlinker-project/openlinker/issues/2367) [#2368](https://github.com/openlinker-project/openlinker/issues/2368) [#2370](https://github.com/openlinker-project/openlinker/issues/2370) [#2371](https://github.com/openlinker-project/openlinker/issues/2371) [#2373](https://github.com/openlinker-project/openlinker/issues/2373) [#2374](https://github.com/openlinker-project/openlinker/issues/2374) [#2375](https://github.com/openlinker-project/openlinker/issues/2375) [#2376](https://github.com/openlinker-project/openlinker/issues/2376) [#2377](https://github.com/openlinker-project/openlinker/issues/2377) [#2378](https://github.com/openlinker-project/openlinker/issues/2378) [#2380](https://github.com/openlinker-project/openlinker/issues/2380) [#2381](https://github.com/openlinker-project/openlinker/issues/2381) [#2382](https://github.com/openlinker-project/openlinker/issues/2382) [#2383](https://github.com/openlinker-project/openlinker/issues/2383) [#2384](https://github.com/openlinker-project/openlinker/issues/2384) [#2388](https://github.com/openlinker-project/openlinker/issues/2388) [#2390](https://github.com/openlinker-project/openlinker/issues/2390) [#2391](https://github.com/openlinker-project/openlinker/issues/2391) [#2392](https://github.com/openlinker-project/openlinker/issues/2392) [#2393](https://github.com/openlinker-project/openlinker/issues/2393) [#2394](https://github.com/openlinker-project/openlinker/issues/2394) [#2395](https://github.com/openlinker-project/openlinker/issues/2395) [#2396](https://github.com/openlinker-project/openlinker/issues/2396) [#2397](https://github.com/openlinker-project/openlinker/issues/2397) [#2398](https://github.com/openlinker-project/openlinker/issues/2398) [#2399](https://github.com/openlinker-project/openlinker/issues/2399) [#2400](https://github.com/openlinker-project/openlinker/issues/2400) [#2401](https://github.com/openlinker-project/openlinker/issues/2401) [#2402](https://github.com/openlinker-project/openlinker/issues/2402) [#2403](https://github.com/openlinker-project/openlinker/issues/2403) [#2404](https://github.com/openlinker-project/openlinker/issues/2404) [#2405](https://github.com/openlinker-project/openlinker/issues/2405) [#2406](https://github.com/openlinker-project/openlinker/issues/2406) [#2407](https://github.com/openlinker-project/openlinker/issues/2407) [#2408](https://github.com/openlinker-project/openlinker/issues/2408) [#2409](https://github.com/openlinker-project/openlinker/issues/2409) [#2410](https://github.com/openlinker-project/openlinker/issues/2410) [#2411](https://github.com/openlinker-project/openlinker/issues/2411) [#2666](https://github.com/openlinker-project/openlinker/issues/2666) [#2673](https://github.com/openlinker-project/openlinker/issues/2673) [#2674](https://github.com/openlinker-project/openlinker/issues/2674) * **oms:** Wave 3b — the pack bench ([#2905](https://github.com/openlinker-project/openlinker/issues/2905)) ([c1e4090](https://github.com/openlinker-project/openlinker/commit/c1e4090ee9e1123675d85a30487f3b5f4632ebd7)) * **orders:** wire buyer tax-ID onto Allegro, WooCommerce, and Erli orders ([#2824](https://github.com/openlinker-project/openlinker/issues/2824)) ([fe222ff](https://github.com/openlinker-project/openlinker/commit/fe222ffa43869e14675921cff9d83d4249775fab)) * **perf:** stand bootstrap for the measurement programme ([#2872](https://github.com/openlinker-project/openlinker/issues/2872)) ([608813d](https://github.com/openlinker-project/openlinker/commit/608813dc63b4f58d1e9a59f9d87037df9068f3e0)) * **returns:** order-detail returns panel and the return activity timeline ([#2960](https://github.com/openlinker-project/openlinker/issues/2960)) ([d5fbd36](https://github.com/openlinker-project/openlinker/commit/d5fbd3697d2d622f782d02ea758fa48b17873f47)) * **sales-documents:** routing-first market table, rebuilt order-detail panel, and e2e coverage for all three surfaces ([#2809](https://github.com/openlinker-project/openlinker/issues/2809)) ([f85e177](https://github.com/openlinker-project/openlinker/commit/f85e1775a28938b1f05a91cfff050e3c9c3dbae8)), closes [#2563](https://github.com/openlinker-project/openlinker/issues/2563) [#2806](https://github.com/openlinker-project/openlinker/issues/2806) [#2807](https://github.com/openlinker-project/openlinker/issues/2807) * **shipping:** `shipment_lines` — line-grain shipment records ([#2727](https://github.com/openlinker-project/openlinker/issues/2727)) ([#2959](https://github.com/openlinker-project/openlinker/issues/2959)) ([e3d9604](https://github.com/openlinker-project/openlinker/commit/e3d9604edfa687ca0a84b5347777a4e07fdb51ff)) * **web:** make Analytics the landing page, rename Dashboard to Insights ([#2742](https://github.com/openlinker-project/openlinker/issues/2742)) ([5ab31e4](https://github.com/openlinker-project/openlinker/commit/5ab31e4a6d75ca0de44f3ddc9cc3d24e7e7311ee)) * **web:** order detail shows invoice and fiscal-receipt lifecycle, not just a badge ([#2763](https://github.com/openlinker-project/openlinker/issues/2763)) ([df46c64](https://github.com/openlinker-project/openlinker/commit/df46c641093ad549ac5de6c43cb0d3e8a93ebb96)) * **web:** sales-document settings page shows which markets issue documents automatically ([#2746](https://github.com/openlinker-project/openlinker/issues/2746)) ([0bce4a8](https://github.com/openlinker-project/openlinker/commit/0bce4a8fe58e0f1085d5e84ec4a6563cb59159a3)) * **web:** show each order's invoice or receipt status in the orders list ([#2761](https://github.com/openlinker-project/openlinker/issues/2761)) ([0470542](https://github.com/openlinker-project/openlinker/commit/0470542e036b130b8e85d1863f4d1ab218b251f1)) ### Bug Fixes * **ci:** close both integration-test flakes - Testcontainers network prune and the live SyncJobRunner ([#2828](https://github.com/openlinker-project/openlinker/issues/2828)) ([58d9b7e](https://github.com/openlinker-project/openlinker/commit/58d9b7ebc3b8a8946aba4a0de01319c5f1a4e453)) * **integrations-inpost:** fall back to ShipX error code as providerCode when details is empty ([#2805](https://github.com/openlinker-project/openlinker/issues/2805)) ([178538c](https://github.com/openlinker-project/openlinker/commit/178538ca304f46487b59ad78f6a2b05282f781ec)) * **integrations-prestashop:** fall back to id-ordered order feed when a shop refuses date_upd sort/filter ([#2884](https://github.com/openlinker-project/openlinker/issues/2884)) ([88425e6](https://github.com/openlinker-project/openlinker/commit/88425e6ef06f8e0fc8c22274b2233fb81355757b)) * **invoicing,fiscalization:** name the actual constraint when refusing a net-priced order ([#2837](https://github.com/openlinker-project/openlinker/issues/2837)) ([1ee9539](https://github.com/openlinker-project/openlinker/commit/1ee9539df85ed83643bd74dd26ebc75f70df637a)) * **orders:** let a PrestaShop order's total be evaluated by an orderTotalGross sales-document rule ([#2832](https://github.com/openlinker-project/openlinker/issues/2832)) ([b3db4c1](https://github.com/openlinker-project/openlinker/commit/b3db4c10e80d2ad7d70db13632c743433f227f4f)) * **sales-documents:** say delivered to, not billed to, in market copy ([#2749](https://github.com/openlinker-project/openlinker/issues/2749)) ([cf0d887](https://github.com/openlinker-project/openlinker/commit/cf0d8870cbe259f3619b65299dd239eaa415c41e)), closes [#2748](https://github.com/openlinker-project/openlinker/issues/2748) * **web/connections:** render system-owned sync jobs as "System", not "Unknown" ([#2747](https://github.com/openlinker-project/openlinker/issues/2747)) ([7994410](https://github.com/openlinker-project/openlinker/commit/799441070241682670b095a1b0bf20d280f9c6e6)) * **web:** correct sales-document settings copy against the shipped routing evaluator ([#2756](https://github.com/openlinker-project/openlinker/issues/2756)) ([5abcc57](https://github.com/openlinker-project/openlinker/commit/5abcc57c8214a6dda1c8f811362c92e87bda75d1)) * **web:** expand Top Products detail inline instead of navigating away ([#2766](https://github.com/openlinker-project/openlinker/issues/2766)) ([a9c6a46](https://github.com/openlinker-project/openlinker/commit/a9c6a46844cb6c1f797943a7d1b063554d3baf10)) * **web:** key shipment triage on an EXACT providerCode, not merely a non-null one ([#2874](https://github.com/openlinker-project/openlinker/issues/2874)) ([1e46e8b](https://github.com/openlinker-project/openlinker/commit/1e46e8b5c23c8988b3d59b5c34a6c158e6548021)) * **woocommerce:** let a WooCommerce order's total be evaluated by an orderTotalGross sales-document rule ([#2838](https://github.com/openlinker-project/openlinker/issues/2838)) ([6adcb70](https://github.com/openlinker-project/openlinker/commit/6adcb7088b9fc3b62791cca3e45dbf93aa409205)) ## [0.9.0](https://github.com/openlinker-project/openlinker/compare/v0.8.0...v0.9.0) (2026-08-31) ### ⚠ BREAKING CHANGES * **orders,fiscalization,sales-documents,web:** POST /fiscal-registrations now answers 202 Accepted with AcceptedFiscalRegistrationResponseDto instead of 200 with FiscalRegistrationResponseDto. The endpoint's own Swagger description previously told callers to read `status`/`failureMode` from the response body to learn the registration outcome - those fields no longer exist on the response. Callers must instead poll the registration-status read (GET .../registration-status) to learn the outcome. ### Features * **orders,fiscalization,sales-documents,web:** sales-document read model, fiscal lifecycle honesty, async registration, routing config, FE primitives ([#2710](https://github.com/openlinker-project/openlinker/issues/2710)) ([6e9dc8e](https://github.com/openlinker-project/openlinker/commit/6e9dc8e387fe568e9a4bdca8b450d378528b8ecb)) * **prestashop:** cut catalogue sync 137x (7.96 to 0.058 requests per SKU), closing [#2489](https://github.com/openlinker-project/openlinker/issues/2489) with adapter work and measurement, not a module (epic [#2590](https://github.com/openlinker-project/openlinker/issues/2590)) ([#2627](https://github.com/openlinker-project/openlinker/issues/2627)) ([e568e91](https://github.com/openlinker-project/openlinker/commit/e568e91a56017c12251bcb6206006bac01e28c44)) * measured 7.96 to 0.058 requests per SKU on a 100,000-product catalogue (~137x reduction) * fan the catalogue sweep out per page ([#2593](https://github.com/openlinker-project/openlinker/issues/2593)) and batch the master stock sweep ([#2655](https://github.com/openlinker-project/openlinker/issues/2655)), instead of one request per product * page every list read instead of silently truncating at 100, and stop probing every product for pack availability ([#2598](https://github.com/openlinker-project/openlinker/issues/2598)) * fix order-feed cursor loss ([#2605](https://github.com/openlinker-project/openlinker/issues/2605)), order-status mapping ([#2607](https://github.com/openlinker-project/openlinker/issues/2607)), and line pricing on cash-on-delivery orders ([#2597](https://github.com/openlinker-project/openlinker/issues/2597), [#2600](https://github.com/openlinker-project/openlinker/issues/2600)) * harden the retry/outbox layer: split 429 from 503 and reset backoff with jitter ([#2614](https://github.com/openlinker-project/openlinker/issues/2614)), bounded outbox retention ([#2603](https://github.com/openlinker-project/openlinker/issues/2603), [#2604](https://github.com/openlinker-project/openlinker/issues/2604)) * emit a product-deletion webhook so listings pause immediately instead of on the next sweep ([#2654](https://github.com/openlinker-project/openlinker/issues/2654)) * add operator controls for sync pacing ([#2660](https://github.com/openlinker-project/openlinker/issues/2660)), sweep budgets ([#2659](https://github.com/openlinker-project/openlinker/issues/2659)), and per-connection backlog status * **products:** flag deleted-at-source products on the /products list ([#2451](https://github.com/openlinker-project/openlinker/issues/2451)) ([022703a](https://github.com/openlinker-project/openlinker/commit/022703a7562d129aa32b36ab185f1c3dc8774f75)) * **web/nav:** put Analytics at the top of the sidebar ([#2495](https://github.com/openlinker-project/openlinker/issues/2495)) ([d3ab5c9](https://github.com/openlinker-project/openlinker/commit/d3ab5c94a484263544ceddc43f43aaffc8f65fe2)) ### Bug Fixes * **products:** surface isStale/staleAt on variant response DTOs ([#2449](https://github.com/openlinker-project/openlinker/issues/2449)) ([9b56d7a](https://github.com/openlinker-project/openlinker/commit/9b56d7a708d437da06dcf72ea5dad327f41d16fb)), closes [#2446](https://github.com/openlinker-project/openlinker/issues/2446) * **shipments:** distinguish label-download failure classes instead of one generic toast ([#2700](https://github.com/openlinker-project/openlinker/issues/2700)) ([abe0f94](https://github.com/openlinker-project/openlinker/commit/abe0f9445b7e07579a20e8603c62bd71b5df2796)) * **sync:** make RedisSyncLockService.acquire self-recognizing on NX failure ([#2717](https://github.com/openlinker-project/openlinker/issues/2717)) ([bfc204d](https://github.com/openlinker-project/openlinker/commit/bfc204d63e60be8561946375c6557a72d52d122b)) * **web,analytics:** move Data coverage and Needs attention sections to the bottom of /analytics ([#2490](https://github.com/openlinker-project/openlinker/issues/2490)) ([57e174e](https://github.com/openlinker-project/openlinker/commit/57e174edcdba1165374b49c3a3882dd18c9faeb4)) * **web,listings:** tighten dead gap under lifecycle tab bar ([#2450](https://github.com/openlinker-project/openlinker/issues/2450)) ([014395f](https://github.com/openlinker-project/openlinker/commit/014395f5f40758e119b591f9e94a983b95d5722d)) * **web/orders:** widen bulk-dispatch dims/weight fields, wrap the id in chunks ([#2699](https://github.com/openlinker-project/openlinker/issues/2699)) ([7213acd](https://github.com/openlinker-project/openlinker/commit/7213acdaf820139c44c92636be27cbc17b534e40)) ## [0.8.0](https://github.com/openlinker-project/openlinker/compare/v0.7.0...v0.8.0) (2026-08-24) ### ⚠ BREAKING CHANGES * **core:** `SYNC_JOBS_EVENT_STREAM` is no longer exported from `@openlinker/core/sync`. The `events.sync.jobs` stream it named is a ghost - nothing reads it, verified as having no remaining in-tree consumers - and the upgrade deletes it. Separately, Redis now runs with `maxmemory` set together with `maxmemory-policy noeviction`, so an existing deployment already holding more data than the new limit will reject every `denyoom` command, including `XADD`, until the previously-unbounded streams are trimmed. `XTRIM` is not a `denyoom` command, so it stays available and is the way out. Run, in order: `DEL events.sync.jobs`; `XTRIM events.inbound.webhooks MAXLEN ~ 50000`; `XTRIM events.inbound.webhooks.dead MAXLEN ~ 10000`; `XTRIM jobs.sync MINID ~ {epoch_ms_14_days_ago}`; `XTRIM events.master.deletion.dead MINID ~ {epoch_ms_30_days_ago}`. Then confirm with `CONFIG GET maxmemory`, `CONFIG GET maxmemory-policy` and `INFO memory`. Full procedure, sizing guidance for `REDIS_MAXMEMORY`, and the rationale for `noeviction`: docs/operations/redis-stream-retention.md (refs #2163, #2223, #2226) ### Features * adapter-declared description format (DescriptionFormat contract + WYSIWYG editor) ([#2204](https://github.com/openlinker-project/openlinker/issues/2204)) ([8021570](https://github.com/openlinker-project/openlinker/commit/8021570ad53972949d44ec6436a386bd4c264933)) * **core,currency,orders:** order-time FX rate snapshot + reporting-currency stamping ([#2135](https://github.com/openlinker-project/openlinker/issues/2135)) ([c6c1e4f](https://github.com/openlinker-project/openlinker/commit/c6c1e4f54b51ff2685f452894c40efcd9af24024)) * **core,worker,api,web:** report the master capability rung + reconcile recency per connection ([#2290](https://github.com/openlinker-project/openlinker/issues/2290)) ([6a335fd](https://github.com/openlinker-project/openlinker/commit/6a335fddd189b83ccb9f175575a1f7f100fb04b5)) * **core,worker:** concurrency lanes — per-lane caps in the job runner (ADR-050) ([#2294](https://github.com/openlinker-project/openlinker/issues/2294)) ([e913866](https://github.com/openlinker-project/openlinker/commit/e9138663f52f8cd7a1f24776f3868ba83d3f0bd1)) * **core/products:** master capability ladder — modified-since rung + PrestaShop watermark spike ([#2232](https://github.com/openlinker-project/openlinker/issues/2232)) ([e30c18e](https://github.com/openlinker-project/openlinker/commit/e30c18e7bbfe70197cd8bff05dfa49861e5ebf85)) * **dx:** make the ADR reversal gates executable in check:invariants ([#2291](https://github.com/openlinker-project/openlinker/issues/2291)) ([a46c1b4](https://github.com/openlinker-project/openlinker/commit/a46c1b48d99c0acb430f5059daf63219eb6da061)) * **fiscalization:** Polish fiscal e-receipts via a neutral fiscalization capability ([#1902](https://github.com/openlinker-project/openlinker/issues/1902)) ([#2137](https://github.com/openlinker-project/openlinker/issues/2137)) ([04b0ece](https://github.com/openlinker-project/openlinker/commit/04b0ece8fb79667c1728c9f163dc43769c0a15a4)) * **infakt:** replace free-text baseUrl with Sandbox/Production dropdown ([#2179](https://github.com/openlinker-project/openlinker/issues/2179)) ([e38d63c](https://github.com/openlinker-project/openlinker/commit/e38d63cdcc1ff0f325f37f1b757a2acebf8c5167)) * **listings,connections:** make the category-resolve in-flight ceiling operator-visible ([#2238](https://github.com/openlinker-project/openlinker/issues/2238)) ([6468944](https://github.com/openlinker-project/openlinker/commit/64689446d34e32db208315226b94f7f7336522cb)) * **listings,web:** pre-submit offer validation in the bulk wizard ([#2244](https://github.com/openlinker-project/openlinker/issues/2244)) ([6ec95e5](https://github.com/openlinker-project/openlinker/commit/6ec95e5c6fc3ad2987ddc4f9391f4b8c785e7a16)) * **listings:** recover a failed bulk batch without starting over ([#2237](https://github.com/openlinker-project/openlinker/issues/2237)) ([b32d3ad](https://github.com/openlinker-project/openlinker/commit/b32d3ad452c265a4f75f75af4e60c211c7e6cdcd)), closes [#2234](https://github.com/openlinker-project/openlinker/issues/2234) * **listings:** streamed per-variant progress for the bulk publish Resolve step ([#2214](https://github.com/openlinker-project/openlinker/issues/2214)) ([bb1d455](https://github.com/openlinker-project/openlinker/commit/bb1d45593eabf145ce15e7c22ce8ca6b08ad1d23)) * **orders,analytics:** order analytics read model + sales/channel/top-products endpoints + per-line tax rate + net tax basis ([#2014](https://github.com/openlinker-project/openlinker/issues/2014)) ([fd44889](https://github.com/openlinker-project/openlinker/commit/fd4488996118b0105665f39899f88b3203bdae2f)) * **sales-documents,invoicing,fiscalization,web:** sales-document routing policy (ADR-041) ([#2154](https://github.com/openlinker-project/openlinker/issues/2154)) ([#2161](https://github.com/openlinker-project/openlinker/issues/2161)) ([e089363](https://github.com/openlinker-project/openlinker/commit/e08936377a15cdeb3eca685d6e6c47973aafb752)) * **web/listings:** product-tier category, honest blocker copy, seller-details preflight ([#2241](https://github.com/openlinker-project/openlinker/issues/2241)) ([84153a6](https://github.com/openlinker-project/openlinker/commit/84153a68be6572a4b92099faf43074fe194260ac)) * **web:** add Open Graph / Twitter Card meta tags with demo-prefix support ([#2175](https://github.com/openlinker-project/openlinker/issues/2175)) ([be37bff](https://github.com/openlinker-project/openlinker/commit/be37bff274600901bbd74c1435edd16f115ed9e1)) * **webhooks,worker,sync:** durable webhook spine + worker roles (ADR-049 D1, ADR-051) ([#2295](https://github.com/openlinker-project/openlinker/issues/2295)) ([25111eb](https://github.com/openlinker-project/openlinker/commit/25111eb9371ee117149d48d5d0e8a5c481123929)) * **web:** show the destination integration + step-1 config on every bulk wizard step ([#2239](https://github.com/openlinker-project/openlinker/issues/2239)) ([e533bc0](https://github.com/openlinker-project/openlinker/commit/e533bc0f254ee9377d08d0221c61ce983641e54a)) * **worker,identifier-mapping:** bound and resume the master sweeps ([#2218](https://github.com/openlinker-project/openlinker/issues/2218), [#2219](https://github.com/openlinker-project/openlinker/issues/2219)) ([#2228](https://github.com/openlinker-project/openlinker/issues/2228)) ([9099a73](https://github.com/openlinker-project/openlinker/commit/9099a7339c5e38b2b5f5268116fc32a46caf2e16)) ### Bug Fixes * **ci:** make the docs-only path gate actually fire (predicate-quantifier) ([#2297](https://github.com/openlinker-project/openlinker/issues/2297)) ([31270cf](https://github.com/openlinker-project/openlinker/commit/31270cf9611e28ab04ab280815c6524ec38de59c)) * **core:** bound every Redis stream and declare the memory policy ([#2163](https://github.com/openlinker-project/openlinker/issues/2163)) ([#2226](https://github.com/openlinker-project/openlinker/issues/2226)) ([94ba20e](https://github.com/openlinker-project/openlinker/commit/94ba20e6a4500d6c61ce0f95dc3efd53fff7a318)) * **core:** reconciliation as the deletion authority — deleted products stop selling ([#2242](https://github.com/openlinker-project/openlinker/issues/2242)) ([d392f1c](https://github.com/openlinker-project/openlinker/commit/d392f1c02573c2ca49ead2da8a2b269473c04299)) * **core:** recover Redis stream messages stranded between read and ACK + ADR-049 durability spine ([#2223](https://github.com/openlinker-project/openlinker/issues/2223)) ([66bbb89](https://github.com/openlinker-project/openlinker/commit/66bbb895690708991283c2eb7548b6550ca733f5)) * **dx:** unbreak main — register the sales-document routing knob, retire the superseded one ([#2292](https://github.com/openlinker-project/openlinker/issues/2292)) ([b29359f](https://github.com/openlinker-project/openlinker/commit/b29359fdbeeb741059c9a5cdcfc4738d629dee10)) * **erli,core,web:** surface why an Erli offer cannot sell instead of showing Draft ([#2236](https://github.com/openlinker-project/openlinker/issues/2236)) ([8fdbedd](https://github.com/openlinker-project/openlinker/commit/8fdbeddcfaee9a21bd1b8ea17c31037340e4ecc4)) * **erli:** default the offer-status sync scheduler task ON ([#2235](https://github.com/openlinker-project/openlinker/issues/2235)) ([2177a7a](https://github.com/openlinker-project/openlinker/commit/2177a7a32f89769763f1e4ce299eb2f10c61e127)), closes [#2230](https://github.com/openlinker-project/openlinker/issues/2230) * **ksef:** surface session-crypto failures on Test connection instead of a generic message ([#2444](https://github.com/openlinker-project/openlinker/issues/2444)) ([9adf2ac](https://github.com/openlinker-project/openlinker/commit/9adf2acc58e725df885c29f1c2e34fd267fb746f)), closes [#2443](https://github.com/openlinker-project/openlinker/issues/2443) * **listings,connections:** address review on the resolve-concurrency ceiling ([#2274](https://github.com/openlinker-project/openlinker/issues/2274)) ([a4ea0bc](https://github.com/openlinker-project/openlinker/commit/a4ea0bc243f5bc76bc2d962b5d2384177655ba4c)), closes [#2229](https://github.com/openlinker-project/openlinker/issues/2229) * **prestashop:** read the order's real currency instead of hardcoding EUR ([#2439](https://github.com/openlinker-project/openlinker/issues/2439)) ([fb3e070](https://github.com/openlinker-project/openlinker/commit/fb3e07031bc6c2ed3b2270069af579d34249b419)) * **web/orders:** stop claiming nothing has synced when a filter is simply narrow ([#2149](https://github.com/openlinker-project/openlinker/issues/2149)) ([54e73a2](https://github.com/openlinker-project/openlinker/commit/54e73a2ba52b11157e48cef275f0be652fa5e8de)) * **web:** add the favicon set the app never had ([#2183](https://github.com/openlinker-project/openlinker/issues/2183)) ([58d832c](https://github.com/openlinker-project/openlinker/commit/58d832cb55c555865b1cb2d77d0b0403afef10a2)) ### Miscellaneous Chores * **core:** declare the Redis stream retention upgrade as breaking ([#2163](https://github.com/openlinker-project/openlinker/issues/2163)) ([#2259](https://github.com/openlinker-project/openlinker/issues/2259)) ([3598ff6](https://github.com/openlinker-project/openlinker/commit/3598ff65a92f2e21f3c020bd0035d6a28f1c76e2)) ## [0.7.0](https://github.com/openlinker-project/openlinker/compare/v0.6.0...v0.7.0) (2026-08-18) ### Features * **analytics-trust,sync:** add analytics data-trust reads ([#2037](https://github.com/openlinker-project/openlinker/issues/2037)) ([cf0beac](https://github.com/openlinker-project/openlinker/commit/cf0beac644218cef8e964bb1639ce027c56785b6)) * **invoicing,orders,web:** persist and surface the auto-issue block reason ([#2100](https://github.com/openlinker-project/openlinker/issues/2100)) ([#2129](https://github.com/openlinker-project/openlinker/issues/2129)) ([c9231c9](https://github.com/openlinker-project/openlinker/commit/c9231c9ba3d994eae2015d68800518a1b843fd69)) * **listings,api:** repoint marketplace category reads at the taxonomy projection ([#2117](https://github.com/openlinker-project/openlinker/issues/2117)) ([ab2c963](https://github.com/openlinker-project/openlinker/commit/ab2c96369661d91b80598071d1fbbd185b79fd2f)), closes [#2074](https://github.com/openlinker-project/openlinker/issues/2074) * **listings,integrations:** bootstrap destination taxonomy on connect, delegate shop browse to the projection ([#2145](https://github.com/openlinker-project/openlinker/issues/2145)) ([6956d29](https://github.com/openlinker-project/openlinker/commit/6956d29ac24a135e745b85211d2a3828aac0bff6)), closes [#2084](https://github.com/openlinker-project/openlinker/issues/2084) [#2085](https://github.com/openlinker-project/openlinker/issues/2085) * **listings,orders,analytics:** needs-attention aggregates ([#2045](https://github.com/openlinker-project/openlinker/issues/2045)) ([b849933](https://github.com/openlinker-project/openlinker/commit/b8499333d3ab4403c6c30c896ba521bac2f92e1f)) * **listings,sync:** derive the taxonomy sync frontier from the projection ([#2067](https://github.com/openlinker-project/openlinker/issues/2067)) ([07fa171](https://github.com/openlinker-project/openlinker/commit/07fa1711ee35bfe566f84b4bcd306439d58d2169)) * **listings,sync:** neutral destination-taxonomy read model (browse + search + sync) ([#2062](https://github.com/openlinker-project/openlinker/issues/2062)) ([59fe748](https://github.com/openlinker-project/openlinker/commit/59fe748db00f4646a41b68d4a64e8b12d7ccb346)) * **orders:** capture order cancellation as first-class record state ([#2022](https://github.com/openlinker-project/openlinker/issues/2022)) ([5e1443c](https://github.com/openlinker-project/openlinker/commit/5e1443c35f4d9932baaefaec94fa92b9676c7cec)) * **orders:** capture return/refund/withdrawal as a first-class record ([#2046](https://github.com/openlinker-project/openlinker/issues/2046)) ([e4fe656](https://github.com/openlinker-project/openlinker/commit/e4fe656ae4e6ea0599bfabcde22b45f85c8693e0)) * **shared,plugin-sdk:** Redis-backed cross-process rate limiter ([#2019](https://github.com/openlinker-project/openlinker/issues/2019)) ([d5e8104](https://github.com/openlinker-project/openlinker/commit/d5e8104d7a57312655290839232d5d1c4484edbf)) * **web/listings,mappings:** whole-tree category search in the pickers ([#2133](https://github.com/openlinker-project/openlinker/issues/2133)) ([bc59f43](https://github.com/openlinker-project/openlinker/commit/bc59f43ec7defc8283bc1e23d2653e9ef477b956)) * **web/listings:** redesign /listings with lifecycle tabs and channel-side commercial data ([#2032](https://github.com/openlinker-project/openlinker/issues/2032)) ([805e29c](https://github.com/openlinker-project/openlinker/commit/805e29ca34a66c22ab2dbf2be68754243bf97951)) * **web:** unify the Order identity and Connection cells across the remaining five lists ([#2086](https://github.com/openlinker-project/openlinker/issues/2086)) ([#2150](https://github.com/openlinker-project/openlinker/issues/2150)) ([14bfc6e](https://github.com/openlinker-project/openlinker/commit/14bfc6e60dc2c5c51b0c8459511fb83aa0f8b6dd)) ### Bug Fixes * **core/orders:** stop the order upsert resetting fulfillmentState to NULL ([#2107](https://github.com/openlinker-project/openlinker/issues/2107)) ([b3e1506](https://github.com/openlinker-project/openlinker/commit/b3e1506399d9b938747e9b6dbedb3e72397b5c84)) * **core/orders:** stop the order upsert wiping syncStatus and syncAttempts ([#2141](https://github.com/openlinker-project/openlinker/issues/2141)) ([5bbb63e](https://github.com/openlinker-project/openlinker/commit/5bbb63e1f2c820928cbded7b05a9319e4028e5c4)) * **dx:** resolve the WooCommerce dev-stack container through Compose ([#2112](https://github.com/openlinker-project/openlinker/issues/2112)) ([3df1b54](https://github.com/openlinker-project/openlinker/commit/3df1b54a65d1aace13a241d6f5be7438e25d7a30)) * **infakt:** stamp the invoice currency instead of booking in the account default ([#2108](https://github.com/openlinker-project/openlinker/issues/2108)) ([a65981b](https://github.com/openlinker-project/openlinker/commit/a65981b103f760936dab10d99f694a9ac43929da)) * **invoicing,web:** lock an order to one invoicing connection ([#2047](https://github.com/openlinker-project/openlinker/issues/2047)) ([#2060](https://github.com/openlinker-project/openlinker/issues/2060)) ([0788a5f](https://github.com/openlinker-project/openlinker/commit/0788a5f3ef85c87721f4eb9f63d47e9830f1a433)) * **invoicing:** let operators pick the correction line instead of typing it ([#2132](https://github.com/openlinker-project/openlinker/issues/2132)) ([c481678](https://github.com/openlinker-project/openlinker/commit/c481678f6b021d700cae25193ba54d5e92863c45)) * **listings,allegro:** taxonomy identity is declared, not inferred from platformType ([#2065](https://github.com/openlinker-project/openlinker/issues/2065)) ([8c64e32](https://github.com/openlinker-project/openlinker/commit/8c64e3252c5cc971a2fb4033e4acfe29de70707c)) * **listings:** write the status snapshot a create already knows, and make its reconcile reachable ([#2039](https://github.com/openlinker-project/openlinker/issues/2039)) ([#2044](https://github.com/openlinker-project/openlinker/issues/2044)) ([bded91b](https://github.com/openlinker-project/openlinker/commit/bded91be1c9de107f32cc5ffa9a85fbd3deeef2f)) * **prestashop:** refuse an unresolvable order currency instead of defaulting to id 1 ([#2142](https://github.com/openlinker-project/openlinker/issues/2142)) ([4b1bd67](https://github.com/openlinker-project/openlinker/commit/4b1bd675ba3575f3853c8f544c3e47f54b142888)) * **prestashop:** tell an unknown tax rate apart from a resolved zero ([#2057](https://github.com/openlinker-project/openlinker/issues/2057)) ([351c78d](https://github.com/openlinker-project/openlinker/commit/351c78d314d61cc93331552c746620b0cd9866ec)) * **prestashop:** use the real order_details id as the line id ([#2134](https://github.com/openlinker-project/openlinker/issues/2134)) ([7401126](https://github.com/openlinker-project/openlinker/commit/74011260bd2780dc664c76f8c47ec6bd3b7c0600)) * **web:** persist explicit config.rateLimit: null on revert-to-default ([#2016](https://github.com/openlinker-project/openlinker/issues/2016)) ([#2017](https://github.com/openlinker-project/openlinker/issues/2017)) ([3a35ff8](https://github.com/openlinker-project/openlinker/commit/3a35ff8a3fb334a67a47fae3f8e2844c4451a875)) * **woocommerce:** map placedAt from date_created_gmt on order source ([#2114](https://github.com/openlinker-project/openlinker/issues/2114)) ([bd642a0](https://github.com/openlinker-project/openlinker/commit/bd642a070fabbc456d67c2efd6f6a464e06295c8)) ## [0.6.0](https://github.com/openlinker-project/openlinker/compare/v0.5.0...v0.6.0) (2026-08-10) ### Features * **allegro,shared:** Allegro adopts the connection-bound rate-limit transport ([#1977](https://github.com/openlinker-project/openlinker/issues/1977)) ([ee4ba43](https://github.com/openlinker-project/openlinker/commit/ee4ba43050e09b0a192431a735a08b18fb49ec18)) * **dpd-polska,shared:** DPD Polska adopts the connection-bound rate-limit transport ([#2005](https://github.com/openlinker-project/openlinker/issues/2005)) ([2204ad1](https://github.com/openlinker-project/openlinker/commit/2204ad1df96cb58931abd3c90bd7d2fe69323188)) * **erli,shared:** Erli adopts the connection-bound rate-limit transport ([#1978](https://github.com/openlinker-project/openlinker/issues/1978)) ([fc15324](https://github.com/openlinker-project/openlinker/commit/fc153247c9f24926938505e1fdbf6c4ff8ec6874)) * **infakt,shared:** Infakt adopts the connection-bound rate-limit transport ([#1997](https://github.com/openlinker-project/openlinker/issues/1997)) ([570d396](https://github.com/openlinker-project/openlinker/commit/570d39699e495b869bbcafce90b9265aeef633f4)) * **inpost,shared:** InPost adopts the connection-bound rate-limit transport ([#1981](https://github.com/openlinker-project/openlinker/issues/1981)) ([1e143a1](https://github.com/openlinker-project/openlinker/commit/1e143a1b6bbcb06e37b282609700b5eb6ee1df94)) * **ksef,shared:** KSeF adopts the connection-bound rate-limit transport ([#2004](https://github.com/openlinker-project/openlinker/issues/2004)) ([b62c351](https://github.com/openlinker-project/openlinker/commit/b62c35165ce0e2b6046e62ba582510dd65614591)) * **orders,shipping,invoicing:** orderSummary projection for shipments/invoices lists ([#2012](https://github.com/openlinker-project/openlinker/issues/2012)) ([a90645d](https://github.com/openlinker-project/openlinker/commit/a90645dc635172e380293c78ca0248702f000022)) * **prestashop,api,web:** rate-limit observability for PrestaShop connections ([#1941](https://github.com/openlinker-project/openlinker/issues/1941)) ([93d04f8](https://github.com/openlinker-project/openlinker/commit/93d04f80aa2855b38a34bcd4df3b0efb6fa0533a)) * **subiekt,shared:** Subiekt nexo adopts the connection-bound rate-limit transport ([#2006](https://github.com/openlinker-project/openlinker/issues/2006)) ([7bfb46e](https://github.com/openlinker-project/openlinker/commit/7bfb46e6e625276b1167178162eb76bc0fb1aac1)) * **web:** add shared AccessGate primitive and gate the MCP capabilities hint ([#1994](https://github.com/openlinker-project/openlinker/issues/1994)) ([1d24560](https://github.com/openlinker-project/openlinker/commit/1d245605664c5c08b4ce0001af0f7860a6007efd)) * **woocommerce,shared:** WooCommerce adopts the connection-bound rate-limit transport ([#1980](https://github.com/openlinker-project/openlinker/issues/1980)) ([73546c0](https://github.com/openlinker-project/openlinker/commit/73546c0cb25ce40caea4fb484ed682c1a3f64ad6)) ### Bug Fixes * **api/auth:** clear stale host-only ol_refresh/ol_csrf duplicates on set/clear ([#2000](https://github.com/openlinker-project/openlinker/issues/2000)) ([18fc501](https://github.com/openlinker-project/openlinker/commit/18fc5012600bffb25dfb36eacbf122ce3806c8a1)) * **worker,core:** heartbeat running sync jobs to survive the stuck-job reclaim sweep ([#1957](https://github.com/openlinker-project/openlinker/issues/1957)) ([7a4d393](https://github.com/openlinker-project/openlinker/commit/7a4d393d2e0570cd842e1ca3f06da4fca8fef91e)) ## [0.5.0](https://github.com/openlinker-project/openlinker/compare/v0.4.0...v0.5.0) (2026-08-03) ### Features * **api,web/demo:** require session-recording consent to use the demo ([#1938](https://github.com/openlinker-project/openlinker/issues/1938)) ([#1945](https://github.com/openlinker-project/openlinker/issues/1945)) ([d081195](https://github.com/openlinker-project/openlinker/commit/d081195c7c294cf61310971c29e05d26e0977bcf)) * **core,api,web/shipments:** persist providerCode on Shipment, re-key failure triage grouping ([#1918](https://github.com/openlinker-project/openlinker/issues/1918)) ([#1925](https://github.com/openlinker-project/openlinker/issues/1925)) ([f654b22](https://github.com/openlinker-project/openlinker/commit/f654b22d2a575ef3bf3fcb42e9e39fdbc3ccad42)) * **demo:** disclose marketing-UTM tracking on /login and /register ([#1895](https://github.com/openlinker-project/openlinker/issues/1895)) ([7af84a5](https://github.com/openlinker-project/openlinker/commit/7af84a5cfeca94babd5d23823fbc50380ca83e9d)) * **demo:** PostHog analytics framework, settings panel, and full viewer-event instrumentation ([#1817](https://github.com/openlinker-project/openlinker/issues/1817)) ([a524242](https://github.com/openlinker-project/openlinker/commit/a524242c15360a7df2b9cabde8c19c21e88a75bb)) * **e2e:** apps/e2e Playwright framework + golden paths S1-S4 (unattended) and S0-S9 (attended, all 6 systems) ([#1480](https://github.com/openlinker-project/openlinker/issues/1480)) ([525dfb1](https://github.com/openlinker-project/openlinker/commit/525dfb1ea9e4098418801f8f19ff11f0cd827d83)) * **listings:** category per family and per variant in bulk offer creation ([#1930](https://github.com/openlinker-project/openlinker/issues/1930)) ([f228325](https://github.com/openlinker-project/openlinker/commit/f22832513e1c2c97442888d3c0c81638f4604543)) * **mcp:** mapping assistant tools + per-tool scope and role enforcement ([#1488](https://github.com/openlinker-project/openlinker/issues/1488)) ([#1967](https://github.com/openlinker-project/openlinker/issues/1967)) ([5a181a3](https://github.com/openlinker-project/openlinker/commit/5a181a35069af0303e1cb8fa58c960c586de650d)) * **mcp:** read-only domain tools with capability-gated dynamic tools/list ([#1931](https://github.com/openlinker-project/openlinker/issues/1931)) ([8907082](https://github.com/openlinker-project/openlinker/commit/89070821fb02e3d46e3a443ab74c0739f17493ec)) * **mcp:** Resource-Server auth via user-issued Personal Access Tokens ([#1486](https://github.com/openlinker-project/openlinker/issues/1486)) ([#1912](https://github.com/openlinker-project/openlinker/issues/1912)) ([46fea4a](https://github.com/openlinker-project/openlinker/commit/46fea4af1bfd2eb3a963d746581db388000c2372)) * **shipments:** inline retry from a failed row + carrier-message role visibility ([#1905](https://github.com/openlinker-project/openlinker/issues/1905)) ([b70b071](https://github.com/openlinker-project/openlinker/commit/b70b071ba5a35f8a583ec49e1a0275ee7e8b6e1f)) * **web/connections:** surface the MCP reconnect hint where capabilities change ([#1951](https://github.com/openlinker-project/openlinker/issues/1951)) ([0b8c130](https://github.com/openlinker-project/openlinker/commit/0b8c130308dd0d43b22471b374384cc3fc859c49)), closes [#1949](https://github.com/openlinker-project/openlinker/issues/1949) ### Bug Fixes * **ci:** add workflow_dispatch to CD and PAT for release-please tag push ([#1894](https://github.com/openlinker-project/openlinker/issues/1894)) ([f6da62b](https://github.com/openlinker-project/openlinker/commit/f6da62bc6e37366f1df7a7b85469897458e69148)) * **core,inventory:** handle full master deletion in inventory sync ([#1903](https://github.com/openlinker-project/openlinker/issues/1903)) ([83c7ca6](https://github.com/openlinker-project/openlinker/commit/83c7ca674d04deee28f88d4b2583f7f7f3504304)) * **core,worker:** guard master staleness prunes against rival master connections ([#1914](https://github.com/openlinker-project/openlinker/issues/1914)) ([e8b4c58](https://github.com/openlinker-project/openlinker/commit/e8b4c588a7d46e85bf176f32dd4ef7f5277e32c4)) * **core/webhooks:** resolve webhook_deliveries.status by lifecycle rank on upsert ([#1919](https://github.com/openlinker-project/openlinker/issues/1919)) ([bb86874](https://github.com/openlinker-project/openlinker/commit/bb86874a95f5b185e20b0c90d853080bd63a692a)), closes [#1916](https://github.com/openlinker-project/openlinker/issues/1916) * **infakt:** issue corrections via the documented async endpoint ([#1899](https://github.com/openlinker-project/openlinker/issues/1899)) ([8498c45](https://github.com/openlinker-project/openlinker/commit/8498c45bb3e42c07894e3dfd83ce899ebfa1799a)) * **infakt:** read the real v3 list envelope and resolve clients by an actual NIP filter ([#1927](https://github.com/openlinker-project/openlinker/issues/1927)) ([21a7722](https://github.com/openlinker-project/openlinker/commit/21a77223101f105f285ee02ae1f66d14278578b8)) * **infra:** align demo Dockerfiles/compose with SysOps container standards ([#1915](https://github.com/openlinker-project/openlinker/issues/1915)) ([3a990f8](https://github.com/openlinker-project/openlinker/commit/3a990f83aa31058ff31639074ae9a1e263a6cc2f)) * **listings:** close ten bulk-wizard preflight-vs-backend divergences ([#1939](https://github.com/openlinker-project/openlinker/issues/1939)) ([2bd07c9](https://github.com/openlinker-project/openlinker/commit/2bd07c93f8ddffa40c6df9bef96ec090dbf76668)) * **listings:** distinguish all-duplicate/partial-duplicate bulk submit outcomes ([#1935](https://github.com/openlinker-project/openlinker/issues/1935)) ([c950f8c](https://github.com/openlinker-project/openlinker/commit/c950f8c1362dc22f73c51256afef95edb96d711e)) * **listings:** stop rejecting adapter-supplied params, and mirror the category gate in the wizard ([#1963](https://github.com/openlinker-project/openlinker/issues/1963)) ([02172f7](https://github.com/openlinker-project/openlinker/commit/02172f79a94f1cee24023eba2fb300fcfb31ebcf)) * **prestashop:** hydrate the buyer e-mail on ingested orders ([#1928](https://github.com/openlinker-project/openlinker/issues/1928)) ([#1929](https://github.com/openlinker-project/openlinker/issues/1929)) ([b2cf6c5](https://github.com/openlinker-project/openlinker/commit/b2cf6c587c027fb821b98d753fde85afa81cbe71)) * **shipping,allegro:** relay a late-arriving waybill to the order source ([#1964](https://github.com/openlinker-project/openlinker/issues/1964)) ([deffd65](https://github.com/openlinker-project/openlinker/commit/deffd6554b7c49e86c617e7d98f214484c154a2e)) * **shipping:** serialise per-order dispatch and recover a lost carrier response ([#1921](https://github.com/openlinker-project/openlinker/issues/1921)) ([28ecb94](https://github.com/openlinker-project/openlinker/commit/28ecb94f38ec0df574f11c471ca86bf47db7763b)) * **web/connections:** let a disabled connection be re-enabled from the UI ([#1944](https://github.com/openlinker-project/openlinker/issues/1944)) ([97da368](https://github.com/openlinker-project/openlinker/commit/97da3681bf07e299a19078d71e3373f485bd1104)) * **web/listings:** serialize a variant's parameters with its own category schema ([#1950](https://github.com/openlinker-project/openlinker/issues/1950)) ([c3a6a6b](https://github.com/openlinker-project/openlinker/commit/c3a6a6bf541622d11ff95163d39963545269df77)) ### Performance Improvements * **test-kit,api:** cut integration-suite time - per-test truncation, shutdown sleep, cold jest cache, shared PrestaShop container ([#1920](https://github.com/openlinker-project/openlinker/issues/1920)) ([#1923](https://github.com/openlinker-project/openlinker/issues/1923)) ([8401f3f](https://github.com/openlinker-project/openlinker/commit/8401f3faaf8c9245ef5ed6f71c5b4ff62ce5c5c9)) ## [0.4.0](https://github.com/openlinker-project/openlinker/compare/v0.3.0...v0.4.0) (2026-07-27) ### Features * **api/auth:** theme-aware transactional email layout derived from app design tokens ([#1750](https://github.com/openlinker-project/openlinker/issues/1750)) ([135605c](https://github.com/openlinker-project/openlinker/commit/135605ca9ec1909af574a395f3cdb2b0e62d5dd1)), closes [#1748](https://github.com/openlinker-project/openlinker/issues/1748) * **auth:** allow login with username or email ([#1730](https://github.com/openlinker-project/openlinker/issues/1730)) ([d20e998](https://github.com/openlinker-project/openlinker/commit/d20e99896cac7eb3375824d344914a3dca6b8f96)) * **auth:** capture analytics consent at registration, drop post-login prompt ([#1744](https://github.com/openlinker-project/openlinker/issues/1744)) ([42a161b](https://github.com/openlinker-project/openlinker/commit/42a161b120b3087e9251a69d17321ed25893f168)) * **auth:** self-service analytics consent toggle on /settings ([#1884](https://github.com/openlinker-project/openlinker/issues/1884)) ([49a5ae9](https://github.com/openlinker-project/openlinker/commit/49a5ae976d37b62e0a57c549bb4d6227bf201f0b)) * **dpd:** add ConnectionTester so 'Test connection' runs a real auth probe ([#1732](https://github.com/openlinker-project/openlinker/issues/1732)) ([#1733](https://github.com/openlinker-project/openlinker/issues/1733)) ([b2342e8](https://github.com/openlinker-project/openlinker/commit/b2342e85962acfa04117d2c53c1e56755da77ba9)) * **erli:** fulfillment routing for Erli sources + routing-split bar ([#1740](https://github.com/openlinker-project/openlinker/issues/1740)) ([6224d18](https://github.com/openlinker-project/openlinker/commit/6224d1849a71960e801ae79a12e8b63ffeff8113)), closes [#1738](https://github.com/openlinker-project/openlinker/issues/1738) [#1739](https://github.com/openlinker-project/openlinker/issues/1739) * **erli:** implement OfferReader so listing details render for Erli ([#1735](https://github.com/openlinker-project/openlinker/issues/1735)) ([#1736](https://github.com/openlinker-project/openlinker/issues/1736)) ([2eee690](https://github.com/openlinker-project/openlinker/commit/2eee690632250d22ee7d6d6e421320e51b6c4d3f)) * **infakt:** webhook config modal - set signing secret + status ([#1770](https://github.com/openlinker-project/openlinker/issues/1770)) ([#1773](https://github.com/openlinker-project/openlinker/issues/1773)) ([aebc7cb](https://github.com/openlinker-project/openlinker/commit/aebc7cb43e069472d2454b9f3e8bcd9286761d46)) * **listings:** per-variant bulk offer config ([#1741](https://github.com/openlinker-project/openlinker/issues/1741)) ([#1757](https://github.com/openlinker-project/openlinker/issues/1757)) ([c2fc423](https://github.com/openlinker-project/openlinker/commit/c2fc42384ed71e8e66585de154a48bdcac99cf09)) * **listings:** reconcile stale terminal offer status against live Allegro publication ([#1760](https://github.com/openlinker-project/openlinker/issues/1760)) ([#1762](https://github.com/openlinker-project/openlinker/issues/1762)) ([35cfbee](https://github.com/openlinker-project/openlinker/commit/35cfbee85fc3735d1cbfb2f3bb77e7f76894eec6)) * **listings:** unify offer creation via multi-select picker + bulk wizard ([#1754](https://github.com/openlinker-project/openlinker/issues/1754)) ([#1774](https://github.com/openlinker-project/openlinker/issues/1774)) ([5fa88bb](https://github.com/openlinker-project/openlinker/commit/5fa88bbe166e3ad5c4fef91c25f9c58c0cbd8249)) * **listings:** unify publish flow + WooCommerce field completeness (epic [#1838](https://github.com/openlinker-project/openlinker/issues/1838)) ([#1870](https://github.com/openlinker-project/openlinker/issues/1870)) ([65cb8a5](https://github.com/openlinker-project/openlinker/commit/65cb8a5f2993498a4b541695c1f13c57b444609e)) * **orders:** mapping-aware delivery + non-Allegro ship-by (epic [#1776](https://github.com/openlinker-project/openlinker/issues/1776)) ([#1782](https://github.com/openlinker-project/openlinker/issues/1782)) ([a277764](https://github.com/openlinker-project/openlinker/commit/a277764ff68dd8cb1901aab8a88f2b597ddf905c)) * **products:** polish product detail page — full-width variant table, rich listing drawer, mobile layout ([#1753](https://github.com/openlinker-project/openlinker/issues/1753)) ([5dde2d4](https://github.com/openlinker-project/openlinker/commit/5dde2d4d7f75291d6beb1ab686e10e8659e37734)) * **products:** product-detail round-2 — rich variant drawer, single/multi states, master currency & attributes ([#1756](https://github.com/openlinker-project/openlinker/issues/1756)) ([8764423](https://github.com/openlinker-project/openlinker/commit/87644233abcf71ffaf6820b9b81ae72e7dfafeb7)) * **web/data-table:** frozen columns, pinned bulk-action bar, viewport-pinned accordion drawer ([#1758](https://github.com/openlinker-project/openlinker/issues/1758)) ([6e825bc](https://github.com/openlinker-project/openlinker/commit/6e825bcf9204c9bbce95107ed3f7f04650595e35)) * **web/mappings:** connection-pair strip, resolved labels, responsive layout ([#1784](https://github.com/openlinker-project/openlinker/issues/1784)) ([#1809](https://github.com/openlinker-project/openlinker/issues/1809)) ([a318ffd](https://github.com/openlinker-project/openlinker/commit/a318ffd98d7fea206eea9dbb03d575d0f3763e27)) ### Bug Fixes * **api/auth:** add OL_COOKIE_DOMAIN for split-subdomain deploys ([#1725](https://github.com/openlinker-project/openlinker/issues/1725)) ([#1726](https://github.com/openlinker-project/openlinker/issues/1726)) ([1dcf363](https://github.com/openlinker-project/openlinker/commit/1dcf36342f9fa11e9165f0e226923c513bf093dd)) * **api/integration-tests:** disable four core scheduler tasks in the harness ([#1889](https://github.com/openlinker-project/openlinker/issues/1889)) ([7281a10](https://github.com/openlinker-project/openlinker/commit/7281a107ca32ad84cc4e0e56687872453552d1a3)), closes [#1888](https://github.com/openlinker-project/openlinker/issues/1888) * **content:** allow viewer role read-only access to content tab ([#1880](https://github.com/openlinker-project/openlinker/issues/1880)) ([3c558eb](https://github.com/openlinker-project/openlinker/commit/3c558eb152391add5fc59052ff7fdaf9b588c8e8)) * **dpd:** carrier population, rejection diagnosability, sender-postcode hint ([#1775](https://github.com/openlinker-project/openlinker/issues/1775), [#1777](https://github.com/openlinker-project/openlinker/issues/1777), [#1778](https://github.com/openlinker-project/openlinker/issues/1778)) ([#1781](https://github.com/openlinker-project/openlinker/issues/1781)) ([95bca6d](https://github.com/openlinker-project/openlinker/commit/95bca6db27f348c993fb720e85bfeba2f7d3c70b)) * **erli:** reconcile frozen-field protection to the verified frozen{} object shape ([#1759](https://github.com/openlinker-project/openlinker/issues/1759)) ([f3a4dd2](https://github.com/openlinker-project/openlinker/commit/f3a4dd254eb6ce71956547a06688d8f7642114e9)) * **inpost:** flatten nested ShipX field-errors so target_point rejections classify correctly ([#1816](https://github.com/openlinker-project/openlinker/issues/1816)) ([bafe267](https://github.com/openlinker-project/openlinker/commit/bafe267add7c7e59d838d807bf3ee0a3349b6195)) * **invoicing:** thread buyer e-mail to Infakt so send-by-email stops 422ing ([#1811](https://github.com/openlinker-project/openlinker/issues/1811)) ([e824f68](https://github.com/openlinker-project/openlinker/commit/e824f68209680a092e66274bb24901bab3bbbf3a)) * **mailer:** validate fromAddress shape and reject CRLF header injection ([#1771](https://github.com/openlinker-project/openlinker/issues/1771)) ([dfa897f](https://github.com/openlinker-project/openlinker/commit/dfa897f222f12f6821f8784109f99578f9870533)), closes [#1765](https://github.com/openlinker-project/openlinker/issues/1765) * **web/connections:** generalize escape-hatch banner copy on advanced setup page ([#1746](https://github.com/openlinker-project/openlinker/issues/1746)) ([8792da9](https://github.com/openlinker-project/openlinker/commit/8792da933d3bc0c2d5b725283d03b14bf1a348e8)), closes [#1745](https://github.com/openlinker-project/openlinker/issues/1745) * **web/connections:** WooCommerce setup wizard with capability selection ([#1727](https://github.com/openlinker-project/openlinker/issues/1727)) ([#1731](https://github.com/openlinker-project/openlinker/issues/1731)) ([4dd3848](https://github.com/openlinker-project/openlinker/commit/4dd3848dd724fc0c77a90be43e10d3cb3fd50a4c)) * **web/demo:** mask passwords only in PostHog session recordings ([#1877](https://github.com/openlinker-project/openlinker/issues/1877)) ([#1878](https://github.com/openlinker-project/openlinker/issues/1878)) ([7e23bfa](https://github.com/openlinker-project/openlinker/commit/7e23bfa92af07f21f012ca57cccf49589801c0cf)) * **web/mailer-settings:** accept display-name form in From address field ([#1761](https://github.com/openlinker-project/openlinker/issues/1761)) ([7469e3c](https://github.com/openlinker-project/openlinker/commit/7469e3c35ba2876b033695c21c90d793a220deeb)) * **web/orders:** match products table header alignment and density ([#1751](https://github.com/openlinker-project/openlinker/issues/1751)) ([9a23b17](https://github.com/openlinker-project/openlinker/commit/9a23b1772fe83e4510448d53da3887c7c5496894)), closes [#1747](https://github.com/openlinker-project/openlinker/issues/1747) * **web/orders:** surface ShipX per-field validation details in the label-error Alert ([#1812](https://github.com/openlinker-project/openlinker/issues/1812)) ([328a17d](https://github.com/openlinker-project/openlinker/commit/328a17d413e389b2447afb6dc102149d6e973477)) * **worker:** cap master.product.syncAll default page size at 100 ([#1723](https://github.com/openlinker-project/openlinker/issues/1723)) ([#1724](https://github.com/openlinker-project/openlinker/issues/1724)) ([62ed30b](https://github.com/openlinker-project/openlinker/commit/62ed30bbe7eb272c0908f657e362395e035ecae8)) ## [0.3.0](https://github.com/openlinker-project/openlinker/compare/v0.2.0...v0.3.0) (2026-07-17) ### Features * **ksef:** session-lifecycle failure resilience - offline24, crash recovery, query fallback ([#1585](https://github.com/openlinker-project/openlinker/issues/1585)) ([#1711](https://github.com/openlinker-project/openlinker/issues/1711)) ([eb4305f](https://github.com/openlinker-project/openlinker/commit/eb4305f8003f1de66e162d5b62df35c1ff8e1218)) * **orders:** responsive orders-table redesign + deep links, invoicing status & empty-state actions ([#1715](https://github.com/openlinker-project/openlinker/issues/1715)) ([86a7d91](https://github.com/openlinker-project/openlinker/commit/86a7d911d353c6fea9f1dc651188468f56ec1ed6)) * **products:** remove inventory list page, redesign products as catalog cockpit ([#1722](https://github.com/openlinker-project/openlinker/issues/1722)) ([5db487a](https://github.com/openlinker-project/openlinker/commit/5db487ac012d0a4da04259cd49330d216e5fa837)) * **web/shipping:** scope COD currency to the routed carrier ([#1569](https://github.com/openlinker-project/openlinker/issues/1569)) ([#1716](https://github.com/openlinker-project/openlinker/issues/1716)) ([c2e2315](https://github.com/openlinker-project/openlinker/commit/c2e23158b370e95a5bbcad266c06c23e8ee14c0b)) ### Bug Fixes * **allegro:** allow operator/viewer to read responsible producers ([#1707](https://github.com/openlinker-project/openlinker/issues/1707)) ([#1708](https://github.com/openlinker-project/openlinker/issues/1708)) ([96b82c0](https://github.com/openlinker-project/openlinker/commit/96b82c0b0570621c4e8c2353e3c2114a19f19c9b)) * **ci:** use SSH_HOSTNAME for ssh-keyscan in deploy workflow ([#1717](https://github.com/openlinker-project/openlinker/issues/1717)) ([cbbb0a3](https://github.com/openlinker-project/openlinker/commit/cbbb0a3ccd59a247a6614ca3c92930d9dcc3e241)) * **inpost:** authenticate both documented webhook HMAC variants ([#1556](https://github.com/openlinker-project/openlinker/issues/1556)) ([#1721](https://github.com/openlinker-project/openlinker/issues/1721)) ([dc52cd5](https://github.com/openlinker-project/openlinker/commit/dc52cd52741663da88c73b5f71f8b46f69c3520f)) * **ksef:** gate numbering demo mode via useWriteAccess, keep nav open ([#1705](https://github.com/openlinker-project/openlinker/issues/1705)) ([#1712](https://github.com/openlinker-project/openlinker/issues/1712)) ([6681d7d](https://github.com/openlinker-project/openlinker/commit/6681d7d48e90e2b2c2611902d5a791d32f1f3409)) * **listings:** auto-retry bulk-wizard resolve step on transient failure ([#1710](https://github.com/openlinker-project/openlinker/issues/1710)) ([7fdf11d](https://github.com/openlinker-project/openlinker/commit/7fdf11d793b6dcdf9f545d410df8ab210125c732)), closes [#1709](https://github.com/openlinker-project/openlinker/issues/1709) * **listings:** gate Erli/bulk offer-creation submits on listings:write ([#1704](https://github.com/openlinker-project/openlinker/issues/1704)) ([#1706](https://github.com/openlinker-project/openlinker/issues/1706)) ([deef6d7](https://github.com/openlinker-project/openlinker/commit/deef6d75558e9c1b46cb5ef04b098309009e7343)) ## [0.2.0](https://github.com/openlinker-project/openlinker/compare/v0.1.0...v0.2.0) (2026-07-16) ### Features * **analytics:** add admin-configurable PostHog settings to /settings ([#1687](https://github.com/openlinker-project/openlinker/issues/1687)) ([dca7eb7](https://github.com/openlinker-project/openlinker/commit/dca7eb7f5502712aaef4d521db9d5b4e9771bbd5)) * **api,web:** email-confirmation activation for demo signup ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **api:** add mailer infrastructure (port + SMTP adapter) ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **api:** DB-backed mailer/SMTP settings (entity, encrypted credentials, admin controller) ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **auth:** grant viewer role read-only access to invoicing, customers, and shipments ([#1363](https://github.com/openlinker-project/openlinker/issues/1363)) ([d8d2d2f](https://github.com/openlinker-project/openlinker/commit/d8d2d2f7714808c1662415c68b57cf76c0e88d82)) * **auth:** rate-limit demo self-registration + scheduled cleanup of demo accounts ([#1471](https://github.com/openlinker-project/openlinker/issues/1471)) ([cb9d96f](https://github.com/openlinker-project/openlinker/commit/cb9d96fd83efc3d6f3f81a40e5f4dcf54af37a9d)), closes [#1469](https://github.com/openlinker-project/openlinker/issues/1469) * **connections:** Erli setup wizard environment select (Production/Sandbox) ([#1437](https://github.com/openlinker-project/openlinker/issues/1437)) ([2dd3f51](https://github.com/openlinker-project/openlinker/commit/2dd3f514adfbbb8b15c227abac483284bc4702d5)) * **demo:** add proxy/TLS overlay, parametrize DB credentials, add public-domain deployment guide ([#1406](https://github.com/openlinker-project/openlinker/issues/1406)) ([76d356a](https://github.com/openlinker-project/openlinker/commit/76d356a982cca131bec98df5824bb9bb98073b62)) * **demo:** demo-only PostHog session recording via server-gated config seam ([#1412](https://github.com/openlinker-project/openlinker/issues/1412)) ([035bbed](https://github.com/openlinker-project/openlinker/commit/035bbed5d207ad7b69361b7782ecf4119b561a3f)) * **demo:** lock AI controls and admin navigation in demo mode ([#1379](https://github.com/openlinker-project/openlinker/issues/1379)) ([#1398](https://github.com/openlinker-project/openlinker/issues/1398)) ([dd25418](https://github.com/openlinker-project/openlinker/commit/dd254188cd7c9fa2e464c9bc21996aeaf1881f77)) * **demo:** one-command Docker demo environment (API/Web/Worker + PrestaShop) ([#1365](https://github.com/openlinker-project/openlinker/issues/1365)) ([0792f07](https://github.com/openlinker-project/openlinker/commit/0792f07d2d2f10361d11151951203fe7cb8cf7d3)) * **erli:** category/parameter browsing from Allegro's catalog without a required Allegro connection ([#1407](https://github.com/openlinker-project/openlinker/issues/1407)) ([87bc11a](https://github.com/openlinker-project/openlinker/commit/87bc11a82328289aa24a8bea14e9665a05dc6a4f)) * **erli:** operator-selectable delivery price list on offer create ([#1530](https://github.com/openlinker-project/openlinker/issues/1530)) ([#1532](https://github.com/openlinker-project/openlinker/issues/1532)) ([4120c33](https://github.com/openlinker-project/openlinker/commit/4120c33e581b693206edfe3bacbcb8987c0c8f90)) * **infakt:** bank-account picker with live inFakt default sync ([#1303](https://github.com/openlinker-project/openlinker/issues/1303) follow-up) ([#1310](https://github.com/openlinker-project/openlinker/issues/1310)) ([b279e17](https://github.com/openlinker-project/openlinker/commit/b279e171954a947e7e70863c573be9493bd73b15)) * **infakt:** consume invoice_marked_as_paid webhook + payment-status sync ([#1354](https://github.com/openlinker-project/openlinker/issues/1354)) ([#1361](https://github.com/openlinker-project/openlinker/issues/1361)) ([861680f](https://github.com/openlinker-project/openlinker/commit/861680f0637bc6b9a4879480ebf0df79a5bc3ef5)) * **infakt:** resend rejected invoice to KSeF from the UI ([#1356](https://github.com/openlinker-project/openlinker/issues/1356)) ([#1360](https://github.com/openlinker-project/openlinker/issues/1360)) ([8531a56](https://github.com/openlinker-project/openlinker/commit/8531a568546d71c15c905b8d721786eb3b672491)) * **infakt:** send invoice to buyer by email one-click ([#1353](https://github.com/openlinker-project/openlinker/issues/1353)) ([#1358](https://github.com/openlinker-project/openlinker/issues/1358)) ([24feddc](https://github.com/openlinker-project/openlinker/commit/24feddc630cd585e48b182b9cbaa4d6cddb4dca6)) * **inpost:** close shipping adapter feature gaps ([#1540](https://github.com/openlinker-project/openlinker/issues/1540)) ([#1545](https://github.com/openlinker-project/openlinker/issues/1545)) ([ef94b44](https://github.com/openlinker-project/openlinker/commit/ef94b4496b125a8c33614adab2529be001679b39)) * **inpost:** model locker (paczkomat) COD in the ShipX adapter ([#1693](https://github.com/openlinker-project/openlinker/issues/1693)) ([ac95491](https://github.com/openlinker-project/openlinker/commit/ac9549111e46ced7b3709bfa5a9ef3d648fd1111)) * **integrations:** validate masterCatalogConnectionId shape on WooCommerce + Erli config ([#1505](https://github.com/openlinker-project/openlinker/issues/1505)) ([c814eae](https://github.com/openlinker-project/openlinker/commit/c814eae8316ece4f034a23205e2dfb657ef39b40)) * **invoicing:** add outbound PaymentMarker capability for inFakt ([#1362](https://github.com/openlinker-project/openlinker/issues/1362)) ([#1475](https://github.com/openlinker-project/openlinker/issues/1475)) ([cff0c94](https://github.com/openlinker-project/openlinker/commit/cff0c947c204d8062f57fb0822c7cf89ddc1fbcb)) * **invoicing:** bulk-issue invoices from the list ([#1355](https://github.com/openlinker-project/openlinker/issues/1355)) ([#1359](https://github.com/openlinker-project/openlinker/issues/1359)) ([c09ae86](https://github.com/openlinker-project/openlinker/commit/c09ae8655a56c0679dfc1125f1aff9f4411cd779)) * **invoicing:** inFakt epic - invoice shipping line + label wiring + webhook integration test ([#1567](https://github.com/openlinker-project/openlinker/issues/1567)) ([0452561](https://github.com/openlinker-project/openlinker/commit/045256160ec7d5381d944035ea6ee477fb15fb46)) * **invoicing:** invoice numbering series module ([#1527](https://github.com/openlinker-project/openlinker/issues/1527)) ([#1684](https://github.com/openlinker-project/openlinker/issues/1684)) ([35f770c](https://github.com/openlinker-project/openlinker/commit/35f770c0c85c9962470b66fce47f81d69a5894ff)) * **invoicing:** invoice-numbering follow-ups - routing axes, daily/fiscal-year, oświadczenie ([#1686](https://github.com/openlinker-project/openlinker/issues/1686)) ([#1697](https://github.com/openlinker-project/openlinker/issues/1697)) ([1f51e93](https://github.com/openlinker-project/openlinker/commit/1f51e934eabeb307fccce2786bed934fefde780a)) * **ksef:** emit P_6 / P_8A / P_9A in FA(3) documents ([#1529](https://github.com/openlinker-project/openlinker/issues/1529)) ([139bab9](https://github.com/openlinker-project/openlinker/commit/139bab982d411a3273310c403bf65159edf454e5)) * **ksef:** implement Test connection via the real auth handshake ([#1448](https://github.com/openlinker-project/openlinker/issues/1448)) ([8575253](https://github.com/openlinker-project/openlinker/commit/8575253ba249dc3816f7dea7a3cb6cd455b9902a)), closes [#1447](https://github.com/openlinker-project/openlinker/issues/1447) * **listings,allegro,erli:** default marketplace-required condition on offer creation ([#1507](https://github.com/openlinker-project/openlinker/issues/1507)) ([c4bc789](https://github.com/openlinker-project/openlinker/commit/c4bc789f51c0bbf7e5df3846f3d71bb70b53def9)) * **listings,erli,web:** operator-selectable responsible producer on offer create ([#1531](https://github.com/openlinker-project/openlinker/issues/1531)) ([#1533](https://github.com/openlinker-project/openlinker/issues/1533)) ([007a855](https://github.com/openlinker-project/openlinker/commit/007a855fad2ef6cc519d782d80edf075f25d12de)) * **listings:** expose filled parameter values and productSet linkage in MarketplaceOffer ([#1483](https://github.com/openlinker-project/openlinker/issues/1483)) ([3848e24](https://github.com/openlinker-project/openlinker/commit/3848e2462db19a3cad9c7e0b4f50600a76309cdc)), closes [#1482](https://github.com/openlinker-project/openlinker/issues/1482) * **listings:** let a demo viewer reach step 4 (Confirm) of the bulk-create offer wizard ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **listings:** redesign publish-to-shop dialog and make batch stock/price per-product ([#1422](https://github.com/openlinker-project/openlinker/issues/1422)) ([1901508](https://github.com/openlinker-project/openlinker/commit/19015083ce4c9f0532e2a5c56885cb06f2a28529)), closes [#1414](https://github.com/openlinker-project/openlinker/issues/1414) * **prestashop:** implement getProductCategories on ProductMaster adapter ([#1506](https://github.com/openlinker-project/openlinker/issues/1506)) ([0b1ef42](https://github.com/openlinker-project/openlinker/commit/0b1ef42facba1c632d260969b8679de0d73326b3)) * **shipping:** distinguish InPost paczkomat (APM) from PaczkoPunkt (POP) via point type ([#1434](https://github.com/openlinker-project/openlinker/issues/1434)) ([db18cbd](https://github.com/openlinker-project/openlinker/commit/db18cbd619b62fffeca83da2c6b961e877f17490)) * **shipping:** redesign the order-detail shipment panel across all states ([#1429](https://github.com/openlinker-project/openlinker/issues/1429)) ([c81cf5f](https://github.com/openlinker-project/openlinker/commit/c81cf5fd77f20ed736f12bf4bebd3e24dc1f40c3)) * **shipping:** source COD amount from Allegro and gate cash-on-delivery on payment status ([#1436](https://github.com/openlinker-project/openlinker/issues/1436)) ([5ed108a](https://github.com/openlinker-project/openlinker/commit/5ed108af58f62c26d0b92f3bd65f37cbd9d2a259)) * **shipping:** surface carrier-rejection details in the log and 502 body ([#1431](https://github.com/openlinker-project/openlinker/issues/1431)) ([2434b7c](https://github.com/openlinker-project/openlinker/commit/2434b7cc0e4c68cbd7fb8bdf63846225bd591253)) * **users:** enforce case-insensitive unique email on registration ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web,api:** connection Config tab visible to demo viewers, read-only ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web,api:** dashboard Infrastructure panel lists every infra-bearing connection ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web,api:** design pass on confirm-email page + HTML confirmation email template ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web,api:** show a clear permission error when a demo viewer issues an invoice ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web,erli:** add dedicated Callback URL field to Erli's edit-connection form ([#1459](https://github.com/openlinker-project/openlinker/issues/1459)) ([49ba486](https://github.com/openlinker-project/openlinker/commit/49ba4862c1290cef534093c359f3da144876120f)), closes [#1458](https://github.com/openlinker-project/openlinker/issues/1458) * **web/ksef:** rebuild FA(3) preview to mirror the official KSeF visualization ([#1528](https://github.com/openlinker-project/openlinker/issues/1528)) ([4f30355](https://github.com/openlinker-project/openlinker/commit/4f3035525af2d17e37ffcdabf76faab3cfe59f30)) * **web:** connection Actions tab visible to demo viewers, write submit disabled ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** mailer/SMTP settings tile + edit modal on /settings ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** orders items preview + fix page-section overflow at narrow widths ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** polish order invoice-generation panel layout ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** redesign order-detail Invoice panel to match Shipment panel ([#1484](https://github.com/openlinker-project/openlinker/issues/1484)) ([b27be04](https://github.com/openlinker-project/openlinker/commit/b27be0433a16291b0ea8709ec49de9abc80c6931)), closes [#1449](https://github.com/openlinker-project/openlinker/issues/1449) * **web:** redesign product detail page with gallery, KPIs and inline listings ([#1537](https://github.com/openlinker-project/openlinker/issues/1537)) ([54b9277](https://github.com/openlinker-project/openlinker/commit/54b92777c007e84e8a952b7e2dc0a3526f08f6c9)) * **web:** responsive orders table with expandable rows and mobile cards ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** surface the selected carrier in orders list and detail ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** unify Invoice Detail Page with OrderInvoicePanel redesign ([#1514](https://github.com/openlinker-project/openlinker/issues/1514)) ([921c088](https://github.com/openlinker-project/openlinker/commit/921c088cf3028a0857103de2360d2f2faa1e9fb4)), closes [#1462](https://github.com/openlinker-project/openlinker/issues/1462) * **woocommerce:** add inbound webhook decoder (InboundWebhookDecoderPort, ADR-021) ([#1696](https://github.com/openlinker-project/openlinker/issues/1696)) ([bf1d1cd](https://github.com/openlinker-project/openlinker/commit/bf1d1cdcc908ff2ae14350b27385e1f0c11fcfdc)) * **woocommerce:** propagate inventory to published products (OfferManager stock write-back) ([#1508](https://github.com/openlinker-project/openlinker/issues/1508)) ([3a896fd](https://github.com/openlinker-project/openlinker/commit/3a896fde6413feffb450c175270a5e63a4a1a76b)) ### Bug Fixes * **allegro,web:** advertise OfferManager sub-capabilities so bulk wizard shows Allegro category params ([#1370](https://github.com/openlinker-project/openlinker/issues/1370)) ([668717a](https://github.com/openlinker-project/openlinker/commit/668717acb119984e810da784fb6bbeae132c2966)), closes [#1367](https://github.com/openlinker-project/openlinker/issues/1367) * **allegro:** detect order cancellation in getOrder (status + fulfillment.status) ([#1461](https://github.com/openlinker-project/openlinker/issues/1461)) ([2d8be18](https://github.com/openlinker-project/openlinker/commit/2d8be18629c40649c99d0088d53dd7a3a75c3ece)), closes [#1460](https://github.com/openlinker-project/openlinker/issues/1460) * **api:** allow demo viewer to read connection diagnostics ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **api:** let demo viewer read mapping options and configuration ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **api:** raise default demo registration rate limit from 5 to 100 per hour ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **auth:** scope refresh cookie to versioned /v1/auth path ([#1340](https://github.com/openlinker-project/openlinker/issues/1340)) ([5dad02c](https://github.com/openlinker-project/openlinker/commit/5dad02c300410c2771afd8ec8757192706fe6677)), closes [#1327](https://github.com/openlinker-project/openlinker/issues/1327) * **ci:** resolve migration timestamp collision and flaky connection-form test ([#1699](https://github.com/openlinker-project/openlinker/issues/1699)) ([0121d19](https://github.com/openlinker-project/openlinker/commit/0121d1954268792378b1bf8804deedf30a64333f)), closes [#1698](https://github.com/openlinker-project/openlinker/issues/1698) * **core:** propagate master-side product/variant deletion ([#1599](https://github.com/openlinker-project/openlinker/issues/1599)) ([#1676](https://github.com/openlinker-project/openlinker/issues/1676)) ([c2d9111](https://github.com/openlinker-project/openlinker/commit/c2d9111639597298f5a4fd06a8dfb9c43b626e26)) * **demo:** boot WooCommerce with pnpm demo:up and fix its permanently-unhealthy healthcheck ([#1397](https://github.com/openlinker-project/openlinker/issues/1397)) ([08dc88a](https://github.com/openlinker-project/openlinker/commit/08dc88a2815fe3cda35feefd9f178e1e1edc3bfe)), closes [#1395](https://github.com/openlinker-project/openlinker/issues/1395) * **demo:** harden docker-compose port binding and add multi-instance parametrization ([#1402](https://github.com/openlinker-project/openlinker/issues/1402)) ([8b58024](https://github.com/openlinker-project/openlinker/commit/8b5802459d5b92821b5d29315db87f40455e1c97)), closes [#1400](https://github.com/openlinker-project/openlinker/issues/1400) * **demo:** route WooCommerce through the proxy overlay with a scoped X-Forwarded-Proto trust fix ([#1421](https://github.com/openlinker-project/openlinker/issues/1421)) ([78c2d7d](https://github.com/openlinker-project/openlinker/commit/78c2d7dccef2f9d20237b3113c59ab5cc302b9f8)) * **demo:** set PRESTASHOP_BASE_URL for the dashboard health check ([#1420](https://github.com/openlinker-project/openlinker/issues/1420)) ([2c7d8b5](https://github.com/openlinker-project/openlinker/commit/2c7d8b5356c0d21b3904f5d6acdc7eea7d5bf3c4)) * **demo:** use curl instead of PHP file_get_contents for PrestaShop healthcheck ([#1393](https://github.com/openlinker-project/openlinker/issues/1393)) ([a964d8b](https://github.com/openlinker-project/openlinker/commit/a964d8bd993438cd055539d280a099767c86b886)), closes [#1392](https://github.com/openlinker-project/openlinker/issues/1392) * **docker:** wire OL_DEMO_MODE + OL_REGISTRATION_ENABLED into the demo compose overlay ([#1504](https://github.com/openlinker-project/openlinker/issues/1504)) ([f87afc8](https://github.com/openlinker-project/openlinker/commit/f87afc8c07d3a2545a0b4fe1ac7f9efe70beb874)) * **erli,web:** reject inactive Allegro credential-reuse source, gate query on rotate panel ([#1466](https://github.com/openlinker-project/openlinker/issues/1466)) ([0664d1e](https://github.com/openlinker-project/openlinker/commit/0664d1ec35f61ba7c6b831f391a6259d3a3e3c63)), closes [#1465](https://github.com/openlinker-project/openlinker/issues/1465) * **erli:** map buyer-selected pickup point onto neutral IncomingOrder ([#1519](https://github.com/openlinker-project/openlinker/issues/1519)) ([#1678](https://github.com/openlinker-project/openlinker/issues/1678)) ([a6e200a](https://github.com/openlinker-project/openlinker/commit/a6e200ad671b2ea936bf8e9ae54aa11a45d3f0d1)) * **erli:** sandbox auth, missing bulk category picker, and rejected dictionary attributes ([#1443](https://github.com/openlinker-project/openlinker/issues/1443)) ([a2c9442](https://github.com/openlinker-project/openlinker/commit/a2c9442c7de6446897664f42badaaa380b37626a)), closes [#1440](https://github.com/openlinker-project/openlinker/issues/1440) * **erli:** stop the inbox poll starving on productsNeedSync events ([#1453](https://github.com/openlinker-project/openlinker/issues/1453)) ([c148ab5](https://github.com/openlinker-project/openlinker/commit/c148ab5a13bd0a301939d8ba1f9affc39a89a537)), closes [#1452](https://github.com/openlinker-project/openlinker/issues/1452) * **infakt:** issue corrections via the dedicated corrective_invoices endpoint ([#1342](https://github.com/openlinker-project/openlinker/issues/1342)) ([b8984ed](https://github.com/openlinker-project/openlinker/commit/b8984ed33867dfb349865a4282bc07e7a2cfc0fc)) * **infakt:** parse inFakt v3 list envelope as items/pagination, not entities/metainfo ([#1374](https://github.com/openlinker-project/openlinker/issues/1374)) ([0c9ef39](https://github.com/openlinker-project/openlinker/commit/0c9ef390f1a02bd0e8fd01505dabae7cfbf5649c)) * **infra:** pass WEB_URL through to the api container in demo compose ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **inventory:** prune stale inventory_items for variants deleted at the master ([#1495](https://github.com/openlinker-project/openlinker/issues/1495)) ([6d2ceaf](https://github.com/openlinker-project/openlinker/commit/6d2ceaf7284ce5ddb26b6761acc46069bd98eb08)), closes [#1478](https://github.com/openlinker-project/openlinker/issues/1478) * **invoicing:** convert invoice_records timezone-naive timestamps to timestamptz ([#1389](https://github.com/openlinker-project/openlinker/issues/1389)) ([25b4a00](https://github.com/openlinker-project/openlinker/commit/25b4a0037980ae158cde9e90d1984bd79edd5e3a)) * **invoicing:** stamp a distinct KSeF document number per correction ([#1451](https://github.com/openlinker-project/openlinker/issues/1451)) ([462085f](https://github.com/openlinker-project/openlinker/commit/462085f0c1b55645249870337cef42a794e62139)) * **ksef:** normalize and validate FA(3) KodKraju + map status 450 to rejected ([#1344](https://github.com/openlinker-project/openlinker/issues/1344)) ([2f49fb7](https://github.com/openlinker-project/openlinker/commit/2f49fb7358f751e8afb8e5a91e1ead6934b13096)), closes [#1343](https://github.com/openlinker-project/openlinker/issues/1343) * **ksef:** persist FA(3) P_2 document number on the issued InvoiceRecord ([#1341](https://github.com/openlinker-project/openlinker/issues/1341)) ([46502f6](https://github.com/openlinker-project/openlinker/commit/46502f6b88e76c79ae7cd02151d0b2b2e2345dfa)) * **listings,woocommerce:** publish carries the variant SKU ([#1485](https://github.com/openlinker-project/openlinker/issues/1485)) ([#1494](https://github.com/openlinker-project/openlinker/issues/1494)) ([f1adf81](https://github.com/openlinker-project/openlinker/commit/f1adf8170b39542a93f54b2401b754e2d6188f3e)) * **listings:** allow shop-publish master-catalog config and tolerate missing category read ([#1418](https://github.com/openlinker-project/openlinker/issues/1418)) ([e776573](https://github.com/openlinker-project/openlinker/commit/e776573d723542f1a09f2fbe231d7f36c70a3888)), closes [#1413](https://github.com/openlinker-project/openlinker/issues/1413) * **listings:** make bulk-wizard category resolve mapping-aware ([#1522](https://github.com/openlinker-project/openlinker/issues/1522)) ([#1523](https://github.com/openlinker-project/openlinker/issues/1523)) ([454a7c6](https://github.com/openlinker-project/openlinker/commit/454a7c64607b10c35ecc9068edb44301acb95795)) * **mappings:** grant operator write access to mapping configuration ([#1691](https://github.com/openlinker-project/openlinker/issues/1691)) ([512af83](https://github.com/openlinker-project/openlinker/commit/512af8350cc2f0c2a1740e0493cacbcf5158bb53)) * **prestashop-seed:** activate the PL country in the dev/demo shop ([#1467](https://github.com/openlinker-project/openlinker/issues/1467)) ([35b23ee](https://github.com/openlinker-project/openlinker/commit/35b23eea1197f7c729a4ac6397e74788d74316a9)), closes [#1446](https://github.com/openlinker-project/openlinker/issues/1446) * **shipping:** add locker-size field to the generate-label form ([#1424](https://github.com/openlinker-project/openlinker/issues/1424)) ([38a01e2](https://github.com/openlinker-project/openlinker/commit/38a01e217bc3fa7871105fa4389b9252cb0a1fd1)), closes [#1423](https://github.com/openlinker-project/openlinker/issues/1423) * **shipping:** backfill the InPost tracking number from getTracking ([#1430](https://github.com/openlinker-project/openlinker/issues/1430)) ([23742ca](https://github.com/openlinker-project/openlinker/commit/23742caca5fbb03639fe2bcea9b04241d50501ff)), closes [#1426](https://github.com/openlinker-project/openlinker/issues/1426) * **shipping:** reject generate-label requests that omit parcel/recipient ([#1518](https://github.com/openlinker-project/openlinker/issues/1518)) ([#1679](https://github.com/openlinker-project/openlinker/issues/1679)) ([3509437](https://github.com/openlinker-project/openlinker/commit/3509437add5cf329d26aff68d15631702d589633)) * **shipping:** use parcel_locker sending method for InPost paczkomat shipments ([#1432](https://github.com/openlinker-project/openlinker/issues/1432)) ([67b43c2](https://github.com/openlinker-project/openlinker/commit/67b43c246a6224b68d8f1b744392400631adee1d)), closes [#1427](https://github.com/openlinker-project/openlinker/issues/1427) * **subiekt:** rebase [#1324](https://github.com/openlinker-project/openlinker/issues/1324) onto main; address PR review findings ([#1335](https://github.com/openlinker-project/openlinker/issues/1335)) ([c89afbf](https://github.com/openlinker-project/openlinker/commit/c89afbfb29d60b3ed4b07ea6492a62ff76868765)) * **sync:** gate platformType-scoped order-poll scheduler tasks by capability ([#1455](https://github.com/openlinker-project/openlinker/issues/1455)) ([e9ee757](https://github.com/openlinker-project/openlinker/commit/e9ee757448fc36a554abf118522f234683cd71cc)), closes [#1454](https://github.com/openlinker-project/openlinker/issues/1454) * **web:** add spacing under section titles ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** add variant picker to WooCommerce publish-to-shop wizard ([#1391](https://github.com/openlinker-project/openlinker/issues/1391)) ([6102b24](https://github.com/openlinker-project/openlinker/commit/6102b244b7017fa28228e3687240262d9e621a3f)), closes [#1390](https://github.com/openlinker-project/openlinker/issues/1390) * **web:** correct InPost webhook runbook URL, self-service copy, and HMAC secret step ([#1477](https://github.com/openlinker-project/openlinker/issues/1477)) ([73add2f](https://github.com/openlinker-project/openlinker/commit/73add2ff1abce605d5f3a8cec54edd1763727a4f)), closes [#1473](https://github.com/openlinker-project/openlinker/issues/1473) * **web:** dialog overflow/blur, toast z-index, and master stock/price prefill in WooCommerce publish wizard ([#1442](https://github.com/openlinker-project/openlinker/issues/1442)) ([3981c55](https://github.com/openlinker-project/openlinker/commit/3981c553e2db6aada2cd81186df833ad0cb0e747)), closes [#1439](https://github.com/openlinker-project/openlinker/issues/1439) * **web:** fix bulk-dispatch dialog gap caused by order-id text-wrap explosion ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** fix orders filter bar overflow on mobile widths ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** gate trigger-sync jobs by capability, add invoicing reconcile trigger ([#1476](https://github.com/openlinker-project/openlinker/issues/1476)) ([d2deab6](https://github.com/openlinker-project/openlinker/commit/d2deab63a9c6cb069af4a3f10e6c3c6382a63b68)), closes [#1474](https://github.com/openlinker-project/openlinker/issues/1474) * **web:** hide demo-mode banner from admin/operator sessions ([#1470](https://github.com/openlinker-project/openlinker/issues/1470)) ([cac8c5e](https://github.com/openlinker-project/openlinker/commit/cac8c5eef126b4ca39ed6d0a63d7a344be6ec52c)), closes [#1468](https://github.com/openlinker-project/openlinker/issues/1468) * **webhooks:** resolve downstream-job link to the concrete SyncJob ([#1366](https://github.com/openlinker-project/openlinker/issues/1366) ([#1378](https://github.com/openlinker-project/openlinker/issues/1378)) ([cfd0c15](https://github.com/openlinker-project/openlinker/commit/cfd0c15136c63a5d542df2fe9084314e337b892b)) * **web:** keep demo-mode banner sticky while scrolling ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** restore contrast and fix layout overflow in marketplace picker modal ([#1463](https://github.com/openlinker-project/openlinker/issues/1463)) ([51faa47](https://github.com/openlinker-project/openlinker/commit/51faa473e2d140da0324605573d43bccd4852218)), closes [#1438](https://github.com/openlinker-project/openlinker/issues/1438) * **web:** show AI-suggest/generate-description to demo viewer, block invoke ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** show Create offer / Publish to shop to demo viewer, block only final submit ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** show New connection / Retry to demo viewer, block only writes ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) * **web:** stop EditConnectionForm's Save changes from clobbering a sibling panel's just-saved config field ([#1445](https://github.com/openlinker-project/openlinker/issues/1445)) ([cc004ed](https://github.com/openlinker-project/openlinker/commit/cc004ed81b0c0eaf1ea51dc3ceb376104901c87c)), closes [#1441](https://github.com/openlinker-project/openlinker/issues/1441) * **web:** stop mobile order cards overlapping badges with the id/copy button ([9ba89ef](https://github.com/openlinker-project/openlinker/commit/9ba89efb4c0d189f7798670afb6d22c6e5574515)) ## [0.1.0] First tracked release — the baseline snapshot of OpenLinker as a self-hosted, API-first, pluggable e-commerce orchestration platform: sync products, inventory, listings, and orders between your own shop and the marketplaces you sell on. ### Platform & architecture - **Hexagonal core** (ports & adapters) organised into bounded contexts — products, inventory, orders, customers, listings/offers, invoicing, content, AI, sync, shipping — with a strict CORE ↔ integration boundary. - **Capability ports** so a new platform is *new implementations, not core changes*: `ProductMasterPort`, `InventoryMasterPort`, `OrderSourcePort`, `OrderProcessorManagerPort`, `OfferManagerPort`, `InvoicingPort`, `ShippingProviderManagerPort`, each with composable sub-capabilities. - **Plugin SDK** (`@openlinker/plugin-sdk`) — framework-neutral adapter-plugin contract, per-connection adapter resolution, and self-registering capability / connection-test / webhook-provisioning / validator registries. - **Identifier mapping** from a single unified seed (`ol_product_*`, `ol_order_*`, `ol_variant_*`, …) so core logic works in internal IDs regardless of source. - **Multi-connection per platform type** (e.g. two PrestaShop stores from one instance), encrypted credentials store, and PII-aware storage (full or hash-only). ### HTTP API - Versioned REST API under **`/v1`** (URI versioning) with a runtime version surface at `GET /v1/health` reporting the product + API version. - JWT auth with refresh-token rotation, role-based authorization (admin / operator / viewer), and self-service registration + admin approval. - Inbound webhook ingestion with HMAC verification, replay protection, and Postgres-authoritative dedup. ### Core workflows - **Order sync** — cursor-based ingestion from marketplaces *and* shops, unified order model, destination order creation with auto-provisioned guest customers, status lifecycle, cancellations/returns, and order-status writeback (ADR-027). - **Inventory sync** — variant-keyed master stock propagated to marketplace offers, including per-combination stock for multi-variant products. - **Listings / offers** — offer creation, quantity + field updates, category & attribute projection across platforms, seller-policy discovery, offer-status snapshots, and a bulk offer-creation flow. - **Invoicing** — country-agnostic `InvoicingPort` (issue / clear / correct fiscal documents), with a browser-based invoice detail + correction surface. - **Content + AI** — per-channel product content with draft write-through and provider-agnostic AI description suggestions (Anthropic, OpenAI) plus editable, versioned prompt templates. - **Shipping / dispatch** — neutral delivery intent, label generation, pickup points, tracking, and shipment-status sync. - **Customer identity resolution** — multi-origin identity with optional email-fallback and address reuse. - **Sync-job orchestration** — scheduled + webhook-triggered jobs with retry classification and a status-vs-outcome split. ### Integrations Shops: - **PrestaShop** (`prestashop.webservice.v1`) — full shop surface (catalog + inventory reads, order ingestion via `date_upd`, order creation, lifecycle, cancellations, returns); ships the OL Dynamic Carrier module so marketplace buyer-paid shipping round-trips correctly. - **WooCommerce** (`woocommerce.restapi.v3`) — source + destination + inventory. Marketplaces: - **Allegro** (`allegro.publicapi.v1`) — order ingestion via the event journal, the full `OfferManager` sub-capability set, OAuth with refresh-on-401, and masked-buyer-email normalization. - **Erli** (`erli.shopapi.v1`) — offers + order source, reconciliation-first posture, borrowing Allegro-id taxonomy. Invoicing: - **Subiekt nexo** (`subiekt.invoicing.v1`) — first `InvoicingPort` adapter, via the Sfera bridge. - **KSeF** (`ksef.publicapi.v2`) — Polish national e-invoicing (FA(3) issue + clear + KOR corrections through the async submit → poll → UPO model). - **inFakt** (`infakt.accounting.v1`) — accounting/invoicing with KSeF indirection and read-back of clearance status. Shipping: - **InPost** (`inpost.shipx.v1`) — ShipX (paczkomat + courier), labels, webhooks. - **DPD Polska** (`dpd.polska.rest.v1`) — REST labels + protocols, SOAP tracking. Content: - **AI router** (Anthropic, OpenAI) — content-suggestion completions behind a provider-agnostic `AiCompletionPort`. ### Frontend - Browser-first admin SPA (React + TypeScript + Vite + TanStack Query) — an operator cockpit for connections, orders, products, inventory, listings, invoices, jobs & logs, webhooks, and cursors, with a build-time plugin registry for per-platform UI. ### Ops & docs - Real integration tests against Postgres/Redis (and a real PrestaShop install) via Testcontainers; TypeORM migrations as the schema source of truth. - Architecture Decision Records, per-context engineering standards, and per-integration setup guides. [0.1.0]: https://github.com/openlinker-project/openlinker/releases/tag/v0.1.0