{"id":51623297,"url":"https://github.com/mikebionic/otweb","last_synced_at":"2026-07-12T21:30:27.568Z","repository":{"id":366473076,"uuid":"1276382993","full_name":"mikebionic/otweb","owner":"mikebionic","description":"OT-Commerce to CS-Cart integration. Products management and configuration | TAOBAO, 1688, AliExpress","archived":false,"fork":false,"pushed_at":"2026-06-22T01:00:34.000Z","size":362,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-22T03:04:56.975Z","etag":null,"topics":["1688","chinese-api","cs-cart","integration","jd","middleware","otapi","otcommerce","poizon","products-api","taobao"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mikebionic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-21T23:07:04.000Z","updated_at":"2026-06-22T01:00:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mikebionic/otweb","commit_stats":null,"previous_names":["mikebionic/otweb"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/mikebionic/otweb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikebionic%2Fotweb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikebionic%2Fotweb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikebionic%2Fotweb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikebionic%2Fotweb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikebionic","download_url":"https://codeload.github.com/mikebionic/otweb/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikebionic%2Fotweb/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35403794,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-12T02:00:06.386Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["1688","chinese-api","cs-cart","integration","jd","middleware","otapi","otcommerce","poizon","products-api","taobao"],"created_at":"2026-07-12T21:30:24.879Z","updated_at":"2026-07-12T21:30:27.542Z","avatar_url":"https://github.com/mikebionic.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OTAPI Hub\n\nКоннектор OT Commerce (Taobao/JD/Poizon) -\u003e CS-Cart (shop.com).\nЗабирает товары из китайских маркетплейсов, переводит на 3 языка через DeepSeek, публикует в интернет-магазин с вариациями (размер+цвет), ценами и остатками.\n\n## Быстрый старт\n\n```bash\n# 1. Поднять MySQL (Docker)\ndocker-compose up -d\n\n# 2. Скопировать конфигурацию\ncp config.yaml.example config.yaml\n# Заполнить API ключи в config.yaml\n\n# 3. Запустить\nmake run\n# или: go run .\n\n# 4. Открыть http://localhost:5500/otweb/\n```\n\n### Деплой на сервер\n\n```bash\n# Сборка Linux бинарника\nmake build\n# -\u003e otapi-hub-linux\n\n# Загрузка (через gzip для надёжности)\ngzip -k otapi-hub-linux\nscp otapi-hub-linux.gz root@server:/tmp/\nssh root@server \"gunzip /tmp/otapi-hub-linux.gz \u0026\u0026 cp /tmp/otapi-hub-linux /opt/otapi-hub-src/otapi-hub \u0026\u0026 chmod +x /opt/otapi-hub-src/otapi-hub \u0026\u0026 systemctl restart otapi-hub\"\n```\n\n### Серверная конфигурация\n\n```\nПуть:    /opt/otapi-hub-src/\nСервис:  systemctl status otapi-hub\nЛоги:    journalctl -u otapi-hub -f\nКонфиг:  /opt/otapi-hub-src/config.yaml\nNginx:   /etc/nginx/vhosts-resources/shop.com/otweb.conf\nURL:     https://shop.com/otweb/\n```\n\n---\n\n## Архитектура\n\n```\nOT Commerce API (otapi.net/service-json)\n  |\n  | 1. BatchSearchItemsFrame (100 товаров/запрос, фильтры)\n  | 2. GetItemFullInfo (1 товар/запрос, кеш 7 дней)\n  v\nOTAPI Hub (Go, порт 5500) -- MySQL otapi_hub (локальная БД)\n  |\n  | 3. DeepSeek: перевод RU/EN/TK + описания + характеристики\n  |\n  | 4. CS-Cart REST API:\n  |    POST /api/products       (товар + фото, status=D)\n  |    POST /api/options         (размер/цвет с картинками и ценами)\n  |    PUT  /api/products/{id}   (характеристики, обновление)\n  |    INSERT cscart_product_options_inventory (комбинации SKU)\n  v\nCS-Cart (shop.com) -- MySQL shop_mv (mirror)\n  Продавец: Shop Commerce (company_id=376)\n  Все товары: status=D (Hidden), avail_since=+7 дней\n```\n\n---\n\n## Структура файлов\n\n```\notapi-hub/\n├── main.go                     # HTTP сервер, 30+ маршрутов, все хэндлеры\n├── config/\n│   ├── config.go               # YAML конфигурация, структуры, Default()\n│   └── config_test.go\n├── otapi/                      # OT Commerce Legacy API клиент\n│   ├── client.go               # GetCatalog, SearchProducts, GetProduct\n│   ├── models.go               # SearchItem, ProductItem, SKU, Location, Price\n│   └── client_test.go\n├── cscart/                     # CS-Cart REST API клиент\n│   ├── client.go               # CreateProduct, UpdateProduct, CreateOptionAdvanced\n│   ├── models.go               # ProductInput, ProductUpdate, NormalizeSize\n│   └── client_test.go\n├── db/                         # MySQL (две базы: otapi_hub + shop_mv)\n│   ├── db.go                   # Store{Hub, Mirror} - два подключения\n│   ├── otapi_repo.go           # Product CRUD, фильтры, маппинги, наценки\n│   └── migrations/\n│       ├── 001_init.sql        # Полная схема (12 таблиц)\n│       ├── 002_detail_sync.sql # detail_fetched_at\n│       ├── 003_v4.sql          # enabled, settings, cs_categories\n│       ├── 004_descriptions.sql # description_ru/en/tk, weight_estimated\n│       └── 005_location.sql    # location_city, location_state\n├── sync/                       # Синхронизация OTAPI -\u003e Hub DB\n│   ├── importer.go             # SyncProducts (2 фазы), SyncPricesOnly\n│   └── importer_test.go\n├── push/                       # Push из Hub DB -\u003e CS-Cart\n│   └── api_pusher.go           # PushSingleProduct, комбинации, price modifiers\n├── translate/                  # DeepSeek AI перевод\n│   ├── deepseek.go             # API клиент, Normalize()\n│   └── prompt.go               # Промпт с enum-значениями характеристик\n├── web/templates/              # HTML шаблоны (Bootstrap 5, embedded)\n│   ├── layout.html             # Sidebar + topbar\n│   ├── dashboard.html          # Статистика\n│   ├── categories.html         # Категории OT Commerce\n│   ├── products.html           # Список товаров (сетка, фильтры, bulk actions)\n│   ├── product_detail.html     # Карточка товара (SKU, фото, переводы)\n│   ├── sync.html               # Синхронизация с фильтрами и live-логом\n│   ├── push.html               # Отправленные / готовые к отправке\n│   ├── mapping.html            # Маппинг категорий OT -\u003e CS-Cart\n│   └── settings.html           # API ключи, цены, доставка, cron\n├── config.yaml.example         # Шаблон конфигурации (без ключей)\n├── docker-compose.yml          # MySQL 8.4 + Adminer (dev)\n├── Makefile                    # run, build, test, deploy\n├── start.sh / stop.sh          # Скрипты запуска\n└── otapi-hub.postman_collection.json  # 33 запроса Postman\n```\n\n---\n\n## Конфигурация\n\n### config.yaml\n\n```yaml\nserver:\n  port: \"5500\"\n\ndatabase:\n  hub_dsn: \"user:pass@tcp(host:port)/otapi_hub?collation=utf8mb4_unicode_ci\u0026parseTime=true\"\n  mirror_dsn: \"user:pass@tcp(host:port)/shop_mv?collation=utf8mb4_unicode_ci\u0026parseTime=true\"\n\notapi:\n  instance_key: \"YOUR_KEY\"\n  base_url: \"https://rest.otapi.net\"\n  legacy_url: \"https://otapi.net/service-json\"\n\ncscart:\n  base_url: \"https://shop.com\"\n  email: \"api@shop.com\"\n  api_key: \"YOUR_KEY\"\n  company_id: 376\n\ndeepseek:\n  api_key: \"YOUR_KEY\"\n  base_url: \"https://api.deepseek.com\"\n\npricing:\n  default_markup_pct: 35.0\n  exchange_rate_cny: 0.57\n```\n\n### Настройки через веб-интерфейс (/otweb/settings)\n\nСохраняются в таблицу `settings`, не требуют рестарта:\n\n| Настройка | Описание |\n|-----------|----------|\n| Курс CNY -\u003e TMT | Обменный курс (по умолчанию 2.74) |\n| Наценка % | Процент наценки (по умолчанию 35%) |\n| Фиксированная надбавка | Плоская сумма к цене (TMT) |\n| Доставка $/кг | Стоимость авиадоставки из Китая ($7/кг) |\n| Курс USD/CNY | Для конвертации стоимости доставки (7.3) |\n| Включить доставку в цену | Вкл/выкл |\n| AI промпт | Кастомный промпт для DeepSeek |\n| Провайдеры | Вкл/выкл Taobao, JD, Poizon |\n| Cron расписание | Автосинк цен и товаров |\n\n---\n\n## HTTP маршруты\n\nВсе маршруты под префиксом `/otweb/`.\n\n### Просмотр\n\n| Метод | Путь | Описание |\n|-------|------|----------|\n| GET | `/` | Dashboard - статистика, последние синки |\n| GET | `/categories` | Список категорий OT Commerce |\n| GET | `/products` | Список товаров (фильтры, пагинация, bulk actions) |\n| GET | `/products/{id}` | Детальная карточка товара |\n| GET | `/sync` | Страница синхронизации + история |\n| GET | `/push` | Отправленные и готовые к push товары |\n| GET | `/mapping` | Маппинг категорий OT -\u003e CS-Cart |\n| GET | `/settings` | Все настройки |\n\n### Действия с товарами\n\n| Метод | Путь | Описание |\n|-------|------|----------|\n| POST | `/products/{id}/push` | Push/update одного товара в CS-Cart |\n| POST | `/products/{id}/translate` | AI-перевод или ручной ввод (action=deepseek/manual) |\n| POST | `/products/{id}/toggle-enabled` | Включить/скрыть товар |\n| POST | `/products/bulk-action` | Массовое действие (push/translate/enable/disable) |\n| POST | `/products/bulk-translate` | AI-перевод всех непереведённых (фон) |\n\n### Синхронизация\n\n| Метод | Путь | Описание |\n|-------|------|----------|\n| POST | `/sync/run` | Запуск синка категории (фон) |\n| GET | `/sync/log/{id}` | JSON лог синка в реальном времени |\n| POST | `/sync/prices` | Обновление только цен (без деталей) |\n\n### Маппинг и Push\n\n| Метод | Путь | Описание |\n|-------|------|----------|\n| POST | `/mapping/add` | Добавить маппинг OT -\u003e CS-Cart категория |\n| POST | `/mapping/delete` | Удалить маппинг |\n| POST | `/mapping/refresh-cscart` | Обновить список CS-Cart категорий |\n| POST | `/push/api` | Push всех товаров категории в CS-Cart |\n\n### Настройки\n\n| Метод | Путь | Описание |\n|-------|------|----------|\n| POST | `/settings/keys` | Сохранить API ключи |\n| POST | `/settings/product` | Статус, Company ID |\n| POST | `/settings/pricing` | Курс, наценка, надбавка |\n| POST | `/settings/delivery` | Доставка ($/кг, вкл/выкл) |\n| POST | `/settings/prompt` | Кастомный DeepSeek промпт |\n| POST | `/settings/providers` | Включить/выключить провайдеров |\n| POST | `/settings/cron` | Расписание автосинка |\n\n---\n\n## Потоки данных\n\n### 1. Синхронизация товаров (двухфазная)\n\n```\nPOST /otweb/sync/run\n  category_id=otc-3  max_products=100  min_volume=500\n\nФаза 1 - SearchProducts (дешёвая, 100 товаров/запрос):\n  -\u003e BatchSearchItemsFrame с XML фильтрами\n  -\u003e Сохраняет: title, price_cny, qty, main_image, vendor, brand, sales, location\n  -\u003e 100 товаров = 1 API запрос\n\nФаза 2 - GetItemFullInfo (дорогая, 1 товар/запрос, кеш 7 дней):\n  -\u003e Только для товаров БЕЗ detail_fetched_at или старше 7 дней\n  -\u003e Сохраняет: description, weight, все SKU (qty+price), все фото, все атрибуты\n  -\u003e 100 новых товаров = 100 API запросов\n\nСтоимость:\n  Первый раз: 1 + 100 = 101 запрос\n  Повторно:   1 + 0   = 1 запрос (всё в кеше)\n```\n\n### 2. Push товара в CS-Cart\n\n```\nPOST /otweb/products/{id}/push\n\n1. Загрузка данных из Hub DB\n2. DeepSeek нормализация (~3 сек, ~$0.001):\n   -\u003e Названия RU/EN/TK\n   -\u003e Описания RU/EN/TK (2-3 предложения)\n   -\u003e Характеристики (цвет, ткань, модель...)\n3. Создание/обновление товара в CS-Cart:\n   -\u003e POST /api/products (новый) или PUT /api/products/{id} (обновление)\n   -\u003e status=D (Hidden), company_id=376\n   -\u003e avail_since = +7 дней (предзаказ)\n   -\u003e Фото: main + до 5 дополнительных\n4. Опция \"Размер\":\n   -\u003e CreateOptionAdvanced с price modifiers\n   -\u003e NormalizeSize: \"S подходит для 85-105 фунтов\" -\u003e \"S\"\n5. Опция \"Цвет\":\n   -\u003e CreateOptionAdvanced с картинками и price modifiers\n   -\u003e image_url из product_attrs\n6. SKU комбинации:\n   -\u003e INSERT INTO cscart_product_options_inventory\n   -\u003e CRC32 hash для combination_hash\n   -\u003e tracking='O' (отслеживание по опциям)\n7. Характеристики:\n   -\u003e featureMap: \"Цвет\"-\u003e567, \"Ткань\"-\u003e563, \"Модель\"-\u003e574...\n   -\u003e ResolveFeatureVariant -\u003e UpdateProductFeatures\n\nВремя: ~10-15 сек/товар\n```\n\n### 3. AI-перевод (DeepSeek)\n\n```\nОдин запрос DeepSeek = один товар:\n\nВход:\n  - Оригинальное название (CN)\n  - Машинный перевод (RU)\n  - Атрибуты (is_configurator=0)\n  - Цвета вариаций\n\nВыход (JSON):\n  - title_ru, title_en, title_tk\n  - description_ru, description_en, description_tk\n  - keywords_ru, keywords_en\n  - color, fabric, material, occasion, thickness, pattern\n  - leg_type, model, waist_height, country, hood\n\nСтоимость: ~$0.001/товар, ~3 сек\n```\n\n### 4. Обновление цен (дешёвый синк)\n\n```\nPOST /otweb/sync/prices\n\n-\u003e SearchProducts постранично (frameSize=20)\n-\u003e UPDATE price_cny, price_tmt WHERE otapi_id=?\n-\u003e Пропускает disabled товары\n-\u003e 1000 товаров = 50 запросов, ~2 мин\n```\n\n---\n\n## Таблицы базы данных\n\n### otapi_hub (основная)\n\n| Таблица | Назначение | Ключевые поля |\n|---------|-----------|---------------|\n| `products` | Товары (28+ колонок) | otapi_id, provider, title_ru/en/tk, price_cny/tmt, cs_product_id, location_city/state, description_ru/en/tk |\n| `product_skus` | SKU варианты | product_id, sku_id, quantity, price_cny, configurators (JSON) |\n| `product_images` | Фотографии | product_id, url, is_main, position |\n| `product_attrs` | Атрибуты | product_id, pid, vid, property_name, value, is_configurator, image_url |\n| `categories` | OT Commerce категории | id, provider, name_ru, parent_id, item_count |\n| `category_config` | Настройки синка | category_id, enabled, max_products, last_synced_at |\n| `category_map` | Маппинг OT -\u003e CS-Cart | otapi_category_id, cs_category_id |\n| `markup_rules` | Наценки (3 уровня) | scope_type (global/category/product), markup_pct, exchange_rate, fixed_addon |\n| `sync_jobs` | История синков | job_type, status, items_processed, log_text (real-time) |\n| `settings` | Key-value настройки | key_name, value |\n| `color_map` | Маппинг цветов CN-\u003eCS | otapi_value, cs_variant_id |\n| `size_map` | Маппинг размеров | otapi_value (XS-5XL), cs_variant_id |\n\n### shop_mv (CS-Cart mirror, read + limited write)\n\n| Таблица | Доступ | Назначение |\n|---------|--------|-----------|\n| `cscart_product_options_inventory` | SELECT, INSERT, UPDATE | SKU комбинации |\n| `cscart_products` | SELECT, UPDATE | tracking='O' |\n| Остальные | SELECT only | Категории, описания, цены |\n\n---\n\n## Ценообразование\n\n### Формула\n\n```\nprice_TMT = price_CNY * exchange_rate * (1 + markup_pct / 100) + fixed_addon\n```\n\n### Трёхуровневая иерархия (markup_rules)\n\n1. **Товар** (scope_type='product') - наивысший приоритет\n2. **Категория** (scope_type='category') - средний\n3. **Глобальный** (scope_type='global') - по умолчанию\n\n### Price modifiers на вариациях\n\nЕсли SKU имеют разные цены (price_cny в product_skus), для каждого размера/цвета вычисляется modifier:\n\n```\nmodifier = (avg_sku_price_CNY * exchange_rate) - base_price_TMT\n```\n\nModifier передаётся в CS-Cart через `CreateOptionAdvanced` как абсолютная надбавка к базовой цене.\n\n### Доставка (планируется)\n\n```\nprice_TMT = (price_CNY + weight_kg * delivery_per_kg_USD * usd_to_cny) * exchange_rate * (1 + markup%) + addon\n```\n\nНастройки: delivery_cost_per_kg ($7), usd_to_cny (7.3), delivery_included (вкл/выкл).\n\n---\n\n## OT Commerce API\n\n### Используемые методы\n\n| Метод | Тип | Назначение |\n|-------|-----|-----------|\n| `GetRootCategoryInfoList` | Бесплатный | 122 корневых категории |\n| `BatchSearchItemsFrame` | Платный | Поиск товаров (до 100/запрос) |\n| `GetItemFullInfo` | Платный | Полная карточка товара |\n| `GetCallStatistics` | Бесплатный | Статистика вызовов |\n| `GetEnabledFeatures` | Бесплатный | Доступные провайдеры |\n\n### Фильтры поиска (XML параметры)\n\n```xml\n\u003cSearchItemsParameters\u003e\n  \u003cCategoryId\u003eotc-3\u003c/CategoryId\u003e\n  \u003cMinVolume\u003e500\u003c/MinVolume\u003e\n  \u003cMinPrice\u003e50\u003c/MinPrice\u003e\n  \u003cMaxPrice\u003e500\u003c/MaxPrice\u003e\n  \u003cItemTitle\u003eрубашка\u003c/ItemTitle\u003e\n  \u003cVendorName\u003eмагазин\u003c/VendorName\u003e\n  \u003cBrandName\u003eбренд\u003c/BrandName\u003e\n  \u003cOrderBy\u003ePrice:Asc\u003c/OrderBy\u003e\n  \u003cStuffStatus\u003eNew\u003c/StuffStatus\u003e\n  \u003cIsTmall\u003etrue\u003c/IsTmall\u003e\n  \u003cPropertySearch\u003e\u003c![CDATA[pid:value]]\u003e\u003c/PropertySearch\u003e\n\u003c/SearchItemsParameters\u003e\n```\n\n### Провайдеры\n\n| Провайдер | Category prefix | Доступен |\n|-----------|----------------|----------|\n| Taobao | otc-* (default) | Да |\n| JD | otc-121 | Зависит от ключа |\n| Poizon | otc-122 | Зависит от ключа |\n\n### Лимиты\n\n- Дневной лимит платных вызовов: ~300 (зависит от тарифа)\n- frameSize: 100 работает стабильно с MinVolume фильтром\n- GetItemFullInfo: ~1-2 сек/запрос\n- При превышении лимита: ErrorCode=AccessDenied, SubErrorCode=CallLimit\n\n### Данные из API\n\n**SearchProducts (Phase 1):**\ntitle, price, qty, main_image, vendor, brand, sales, fav_count, features (Tmall/Expired/FakeQty), location (city+state)\n\n**GetItemFullInfo (Phase 2):**\n+ description_html, weight, all SKUs (qty+price+configurators), all photos, all attributes (pid/vid/value/is_configurator/image_url), has_internal_delivery\n\n---\n\n## CS-Cart API\n\n### Методы\n\n| Метод | Endpoint | Назначение |\n|-------|----------|-----------|\n| CreateProduct | POST /api/products | Новый товар (status=D) |\n| UpdateProduct | PUT /api/products/{id} | Обновление товара |\n| CreateOptionAdvanced | POST /api/options | Опция с картинками и price modifiers |\n| UpdateProductFeatures | PUT /api/products/{id} | Установка характеристик |\n| ResolveFeatureVariant | GET /api/features/{id} | Поиск variant_id по значению |\n| DeleteProduct | DELETE /api/products/{id} | Удаление товара |\n\n### Маппинг характеристик (featureMap)\n\n| Характеристика | feature_id | Допустимые значения |\n|---------------|-----------|-------------------|\n| Цвет | 567 | Черный, Белый, Синий, Серый, Красный... (25 вариантов) |\n| Ткань | 563 | Деним, Трикотаж, Хлопок, Шифон... |\n| Модель | 574 | Oversize, Skinny, Прямой, Свободный |\n| Высота талии | 575 | Завышенная, Заниженная, Нормальная |\n| Штанина | 573 | Прямая, Узкая, Широкая, Клёш |\n| Длина | 570 | - |\n| Толщина | 571 | Средний, Толстый, Тонкий |\n| Повод | 566 | Повседневный, Офис, Спорт, Вечернее |\n| Подкладка | 565 | - |\n| Капюшон | 562 | Без капюшона, С капюшоном |\n| Страна | 578 | Генерируется AI |\n\n### Комбинации (SKU inventory)\n\nCS-Cart не имеет API для комбинаций. Запись напрямую в MySQL:\n\n```sql\nINSERT INTO cscart_product_options_inventory\n  (product_id, product_code, combination_hash, combination, amount)\nVALUES (?, ?, CRC32(?), ?, ?)\nON DUPLICATE KEY UPDATE amount=VALUES(amount);\n\nUPDATE cscart_products SET tracking='O' WHERE product_id=?;\n```\n\n---\n\n## Веб-интерфейс\n\n### Страница товаров (/otweb/products)\n\n**Фильтры:** категория, провайдер, сортировка (новые/продажи/цена/отзывы/избранное), поиск, не отправлены, включённые, кол-во на странице (40/80/120/200)\n\n**Bulk actions (чекбоксы):**\n- AI-перевод - DeepSeek для выбранных\n- Push - отправить в CS-Cart\n- Скрыть / Включить\n\n**Бейджи на карточках:**\n- CS#XXX (зелёный) - отправлен в CS-Cart\n- Скрыт (тёмный)\n- N продаж (жёлтый)\n- Нет перевода (красный)\n- Город (серый, если Location есть)\n\n### Страница товара (/otweb/products/{id})\n\n- Фото + галерея\n- Цена CNY -\u003e TMT\n- Location продавца (город, провинция)\n- Названия RU/EN/TK с бейджем статуса (AI/Ручной)\n- Описания RU/EN/TK\n- Доставка: через неделю (7 дней)\n- SKU таблица (sku_id, qty, price, конфигурация)\n- Кнопки: Push / Обновить в CS-Cart / AI-перевод / Ручной ввод\n\n### Страница синхронизации (/otweb/sync)\n\n**Фильтры API:**\n- Провайдер, категория, макс. товаров\n- Мин. продаж (50-50K)\n- Цена от/до (CNY)\n- Поиск по названию\n- Сортировка (по умолчанию, цена, продажи)\n- Состояние (новый/б/у), только Tmall\n- Только цены (быстрый синк)\n\n**Live лог:** polling каждые 2 сек, статус running/done/error\n\n### Настройки (/otweb/settings)\n\n- API ключи (OTAPI, CS-Cart, DeepSeek)\n- Товары (статус по умолчанию, Company ID)\n- Ценообразование (курс, наценка, надбавка)\n- Доставка ($/кг, USD/CNY, вкл/выкл)\n- AI промпт (кастомизация)\n- Провайдеры (вкл/выкл)\n- Cron расписание\n\n---\n\n## Graceful degradation\n\n| Сбой | Поведение |\n|------|----------|\n| DeepSeek недоступен | Товар создаётся с оригинальным названием, без описания |\n| CS-Cart timeout | Ошибка логируется, следующий товар продолжается |\n| Фото 404 | CS-Cart пропускает фото, товар создаётся без него |\n| Feature variant не найден | Логируется, остальные features сохраняются |\n| API лимит (AccessDenied) | Phase 1 данные сохранены, Phase 2 пропущена |\n| mirror DB нет прав | Ошибка логируется с деталями (не молча) |\n\n---\n\n## Миграции\n\n```\n001_init.sql          - Полная схема: 12 таблиц, индексы, color_map, size_map\n002_detail_sync.sql   - detail_fetched_at для кеша GetItemFullInfo\n003_v4.sql            - enabled, hidden_at, settings, cs_categories\n004_descriptions.sql  - description_ru/en/tk, weight_estimated\n005_location.sql      - location_city, location_state продавца\n```\n\n---\n\n## Makefile\n\n```bash\nmake run      # go run .\nmake build    # GOOS=linux GOARCH=amd64 go build -o otapi-hub-linux .\nmake test     # go test ./...\nmake stop     # kill процесс на порту 5500\nmake restart  # stop + run\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikebionic%2Fotweb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikebionic%2Fotweb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikebionic%2Fotweb/lists"}