Backend: API responses now sanitize stored international_pricing so every country entry includes canonical pricing fields (buy_netto, fba_shipping_cost) and an explicit ignore flag.
Added _sanitize_international_pricing() in the repricer articles endpoint to coerce legacy/incomplete country dicts into full FBM/ FBA country-pricing shapes before Pydantic validation and response serialization.
UVP: min_uvp and max_uvp are now optional in the set_uvp endpoint; downstream detail updates and exports only apply values when provided to avoid overwriting existing UVP data.
FBM/FBA writer paths now prefer creating FB(A|M)CountryPricing(...) instances and persist .model_dump() dicts to international_pricing to avoid serializer warnings and validation errors.
Top-level list/get article endpoints gracefully fallback: when FBMDetailsResponse.model_validate(...) raises a ValidationError, the API now sanitizes and validates a constructed dict so responses do not fail.
Reduced risk of losing UI flags: ignore and hazmat are explicitly preserved when updating per-country pricing during recalculation and export.
Removed a broken preservation snippet in the FBA manual-override branch that referenced undefined variables and could cause ignore to be overwritten.
Combined min/max margin calculations for FBA and FBM into a single SP-API call to reduce redundant work and speed up recalculation runs.
Normalized ArticleStatus usage across Otto flows and ensured status/state fields are written as the enum .value string to avoid Pydantic enum validation errors.
Manual monitor endpoint now falls back to the cron job's configured webhook when none is provided on the request.
Hardened monitor_all_prices and async update paths to correctly set item states and error handling when monitoring all items.
service_omni Sellerlogic: added a rate limiter and fixed filtering so FBA/FBM article queries fetch the correct seller_sku.
Fixed ignore flag being overwritten after FBA recalculation — existing per-country ignore values are now preserved.
Fixed intermittent Pydantic validation error when reading FBM details (missing fba_shipping_cost and buy_netto) by sanitizing legacy dicts and ensuring required fields are present.
Ensured legacy fbm_shipping_cost key remains available for the frontend while normalizing to the canonical fba_shipping_cost model field.
Fixed an export error in the FBA export path so batches export correctly and do not produce malformed payloads.
Fixed Plenty export for Otto where the channel field could sometimes contain a price instead of the channel identifier; the export now sends the correct channel value.
Restored and hardened sync polling for the Otto repricer so background sync falls back correctly and no longer drops updates.
Fixed Pydantic validation error after sync: ArticleStatus fields are now saved as expected strings (e.g. active) instead of ArticleStatus.ACTIVE.
When manually calling the monitor endpoint without a webhook, the system now uses the cron job's webhook (if configured) so monitor runs continue to notify the same destination.
Fixed several monitoring/all-items edge cases so bulk monitoring no longer produces invalid Product states or leaves items in inconsistent statuses.
No DB schema migration required — changes operate on the existing international_pricing JSONB column.
To verify: trigger a recalc for a known SKU or call the article list/get endpoints that previously raised the Pydantic error and confirm responses no longer fail.
If you still see race-related overwrites under heavy concurrency, consider adding a transactional retry or SELECT ... FOR UPDATE around the details row.