Skip to main content

noon-listing

Noon listing operations — create SKU (3-step wizard) and edit listings (Offer / Content / Sizes / Groups tabs). Load when creating, editing, pricing, restocking, or updating content on a noon SKU.

Ir para a instalação

Informações da origem

Repositório
zpoint/vibe-seller
Última atividade na origem
20 de setembro de 2026 às 06:42
Idioma detectado do SKILL.md
inglês
Estrelas
83
Forks
19

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
2 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
noon-listing
description
Noon listing operations — create SKU (3-step wizard) and edit listings (Offer / Content / Sizes / Groups tabs). Load when creating, editing, pricing, restocking, or updating content on a noon SKU.
requires
["noon-shared"]
review
{"criteria":"- The SKU is ACTUALLY created and live on noon, not just \"submitted\":\n the create flow reached the success redirect to\n /catalog/{noon_sku}/p, and the Offer tab shows the base price /\n sale price / stock / barcode as entered (committed on the live\n page). Content/Sizes match the request.\n- For a NIS import: the import's **Report File** is non-empty and\n every row carries a `catalog_sku`. `Status: Complete` and\n `Total Processed Rows: N` are NOT evidence of creation — an import\n that created nothing shows both, with a 4-byte Report File.\n- Every bilingual field the request supplied in English also has its\n Arabic half on the live Content tab (title, long description, each\n feature bullet) — not a stub a fraction of the English length.\n- An edit is done only when the live page reflects it (green success\n + updated values), not on a toast alone.\n","verify_by":"Open the created SKU's catalog page and its Offer tab; confirm price\n/ stock / barcode match what was entered. For an edit, reload the tab\nand confirm the new values persisted. A feed/toast without the live\npage reflecting it is a gap. For a NIS import, additionally download\nthe import's Report File and confirm one row per SKU with a\n`catalog_sku`, and open the Content tab to confirm the Arabic half of\nevery filled English field. Import-row counters are not evidence.\n"}
# Noon — Listing Operations > **PREREQUISITE:** Read `../noon-shared/SKILL.md` for login, page > structure, modals, and button-click patterns. Covers SKU creation and the post-creation edit flow (price, stock, barcode, content, visibility status). > **Two create paths — PREFER file-based, FALL BACK to click.** > File-based (§1, NIS spreadsheet import) sets every hard field through a > spreadsheet, so it never touches the Ant-Design dropdowns (Warranty, > Department, Gender, Size, Content selects) that the click wizard needs > a *trusted mouse* to open — those dropdowns are the recurring wall on > the click path. Use file-based whenever creating one or more SKUs of a > known category. Use the click wizard (§2) only for a one-off where you > can drive a real trusted click, or to *edit* a SKU after creation. ## 1. Create Listing — File-based (PREFERRED, NIS import) Noon's **NIS** (noon Item Sheet) importer creates SKUs in bulk from a spreadsheet. Everything the click wizard sets via a dropdown is a plain cell here, so it sidesteps the anti-automation selects entirely. **Flow:** `Imports` → **Add Import** → **Type = Content**, **Subtype = NIS Create/Update** → pick the category → **Download** the template → fill it → **Next** → upload → SKUs go to async Quality Check (QC). URL: `https://noon-catalog.noon.partners/en/imports/create?project=PRJ{project_id}` The Type / Subtype selects are Ant-Design dropdowns — open each with a trusted `click_at_xy` on the field, then option-click the item in `.ant-select-dropdown .ant-select-item` (type-to-filter does NOT work; see `../noon-shared`). ### 1.1 Which import for which field Imports are keyed by **Type → Subtype**. The relevant ones: | Type | Subtype | Creates / sets | |------|---------|----------------| | Content | **NIS Create/Update** | **Creates new SKUs** — identity, sizes, attributes, images, in bulk. This is the create step. | | Content | Product Import | *Updates* content (title/description/attributes) of **existing** SKUs only. | | Pricing | **Price Update** | Base price + sale price/window for existing SKUs (see §1.3). | | Pricing | Price Range Update | Long-dated sale windows (the discount pattern, §1.3). | | Stock | (stock subtype) | On-hand quantity for existing SKUs. **Match the store's warehouse type**: an FBP Stock Update fails ("no FBP warehouse") if the store has none; FBN stock requires an ASN shipment flow, not a stock import. Check the SKU's Offer→Stock section for which warehouse the store actually has before choosing the stock import. | | Warranty | (warranty subtype) | Warranty type for existing SKUs (file equivalent of the click "No Warranty"). | So a full file-based create is: **NIS Create/Update** (identity + images) → then **Price Update** (price) and **Stock** as follow-up imports keyed on the `seller_sku`/`partner_sku` you assigned. Each import's own "ABOUT THIS UPLOAD" panel lists its exact Required/Optional columns — read it in-page before filling; do not assume. ### 1.2 The NIS template (Content → NIS Create/Update) - **Category**: "Download templates for" → **Specific category** → drill the tree (e.g. **Apparel** → product-types incl. *Socks & Tights*) and select it, **plus** the target store/marketplace, to enable the per-category **Download English** / **Download English + Arabic** buttons (AE stores need the +Arabic template for the local title). "All categories" downloads a generic shell without the category attribute columns — only use it to see the structure. - **`With Instructions`** checkbox adds a column-guidance row — leave it on the first time. - **Core required columns** (from the template's `valid values` sheet): `family`, `product_type`, `product_subtype`, `seller_sku`, `item_condition` (`New`), `parent_child_variation` (`Parent`/`Child` for sized products), and per-marketplace `vat_rate_ae` / `vat_rate_sa` / `vat_rate_eg` (`Std`). Category attribute columns + image-URL columns follow — fill per the in-sheet guidance and the linked "How to fill out the NIS sheet" article. - Each row needs a **unique `seller_sku`**. Partial failures are per-row: good rows still create; fix the error file and re-upload the rest. - **A parent needs a child — a lone parent creates NOTHING.** Verified live: a single row with `parent_child_variation=parent` imports "successfully" but the SKU never appears, and the error file's `creation_error` column reads **`child is missing`**. Every product needs **two rows sharing one `parent_group_key`**: a `parent` row (identity) **and** at least one `child` row (the sellable variant, with its own distinct `seller_sku` and a `size_variation`/`size_map`, e.g. `One Size`). The **child** is what carries the offer — follow-up Pricing/Stock imports key on the **child** `seller_sku`. - **Multiple sizes = one parent row + one child row PER SIZE** (all sharing the parent's `parent_group_key`). Verified live: a parent + three children (`size_variation`/`size_map` = `S`, `M`, `L`, distinct `seller_sku`s) created one parent noon-SKU with children `-1/-2/-3`, one per size — the same shape a real sized product uses (e.g. an S/M/L/XL/XXL family is a parent + five child rows). `size_map` is the **noon** size and may differ from your label (e.g. `XXL` → noon `2XL`); check the template's `valid values` / the live **Sizes tab** for the noon size names. This is noon's **new** variation style — always use it for new listings. ⚠️ **NIS has no Arabic-size column — only `size_variation` (Seller Size EN) and `size_map` (noon Size).** So after a NIS create the sized product's **Seller Size (AR)** — a `*`-mandatory field on the Sizes tab — is not authored by you: noon back-fills it with the *English* `size_variation` string, so the field looks satisfied while showing English text in the Arabic column. (An earlier revision of this skill said it shows `--`; re-verified, it is the copied English value.) Either way the family is bound but not content-complete. Fill the Arabic seller size per row on the live **Sizes tab** (edit each size) after import. Verified live: a parent + S/M/L children imported correctly (one parent hash, children `-1/-2/-3`, all shown bound on the Sizes tab) but with **Seller Size (AR) holding the English `size_variation` string** until replaced by hand. - **Leave a field BLANK unless the task specified it.** This is the default, not a preference. A NIS sheet has ~150 columns and almost all of them are optional; filling one "because it is there" invents data the seller never agreed to. Every invented value in the one audited run was wrong: `hs_code` was a guessed 4-digit customs code (rejected for length), a select attribute carried a value nobody claimed (rejected as out-of-enum), and one answer of "100 AED" was fanned out to `msrp_ae`, `msrp_sa` **and** `msrp_eg` — pricing two marketplaces the user never priced, one of which the seller does not sell in. > ⚠️ **On noon an invented value is effectively permanent.** A blank > cell in a NIS *update* means "no change", NOT "clear" — verified: an > update whose `msrp_*` cells were emptied imported with 0 errors and > left the live values untouched. Clearing them on the Content tab did > not persist either. So the only reliable moment to not have a wrong > value is **before the first upload**. If a field seems needed but the task did not give it, ASK — do not infer it from the English copy, the other marketplaces, or the Amazon listing. - **Pre-flight the sheet BEFORE uploading — always:** ```bash # Your CWD is the task workspace, not the skill dir — address the # script through the synced skill path. S=.claude/skills/noon-listing/scripts # --markets is the marketplaces the TASK covers, not the ones the # store has. "Only list on the UAE site" means --markets AE. python3 $S/validate_nis.py FILLED.xlsx --markets AE ``` It fails the file on the traps that have each burned a live import: a leftover template sample row, a select value that is not in the template's `valid values` sheet, an out-of-range `hs_code`, an English field whose Arabic half is empty, and a per-marketplace field (`msrp_*`, `vat_rate_*`) set outside the task's scope. A live import costs minutes and its error reporting is unreliable (below); this costs nothing. - **DELETE the template's sample row(s) before uploading.** The downloaded template ships a row carrying only `family` / `product_type` / `product_subtype` and no `seller_sku`. Leave it in and noon's Error File reports **only** that row's `seller_sku is missing` and silently drops every real row's `content_error`, while the counters read `1 error / N processed` — which reads as success. Verified: the same import's Error File still showed only the sample row 6.5 h later, and its Report File was empty. - **Upload flow (filled NIS sheet):** Imports → Add Import → Type=Content, Subtype=NIS Create/Update → **Next** → drag/drop or pick the `.xlsx` (the hidden `input[type=file]` accepts `.csv,.xlsx`) → **Submit**. The import runs async (a `IMP…` code); it shows Completed even on row failures, so verify the SKUs actually appear in My Catalog. - **`Total Processed Rows` is NOT "created" — the Report File is.** The counter counts rows that passed *partner-level* validation; rows that then fail content validation still count toward it. The only trustworthy signal is the import's **Report File**: one row per SKU with a filled `catalog_sku` (and `sku_parent` for a variation family). A failed import's Report File is **4 bytes** — a UTF-8 BOM and a newline. Download it every time; do not report success without it. - **Reading the error file is the debug loop.** An import that shows Completed but creates nothing failed row validation; open the import's Result/error CSV — its trailing `partner_error` / `content_error` / `creation_error` columns name the exact problem. Fix those cells (use the exact valid-value strings) and re-upload. If the error file names only a row you did not write, you still have a sample row in the file (above) — remove it and re-upload to see the real errors. - **Fill BOTH halves of every bilingual pair.** The `English + Arabic` template pairs each localised field (`product_title_*`, `long_description_*`, `feature_bullet_N_*`, `colour_name_*`). Filling only `_en` imports clean — no error, no warning — and ships a half-translated listing; shipped once with all four Arabic feature bullets empty and Arabic title/description stubs a third the length of their English source. `validate_nis.py` fails the file on a missing `_ar`, and warns when one is suspiciously short. ### 1.3 Pricing import — optional high-base + long sale (a seller pattern) Some sellers list a **high base price** and a **long-dated half-price sale** so the page shows a large discount on day one, while the true selling price is the sale price every day. This is a **guideline, not a requirement** — only apply it when the seller asks for it. To do it file-based, after the SKU exists run **Pricing → Price Update** (columns: required `country_code`, `id_partner`, `partner_sku`; optional `price`, `sale_price`, `sale_start`, `sale_end`, `is_active`): - `price` = the high base (e.g. `100`) - `sale_price` = the real everyday price (e.g. `50`) - `sale_start` = today, `sale_end` = a far-future date (e.g. +5 years) For a rolling window use **Pricing → Price Range Update**. If the seller did not ask for the discount pattern, just set `price` to the real price and leave the sale columns blank. ## 2. Create Listing — Click wizard (FALLBACK) **URL**: `https://noon-catalog.noon.partners/en/catalog/create?project=PRJ{project_id}` > Use this only when file-based isn't practical (a true one-off you can > drive with a real trusted click). It needs trusted `click_at_xy` for > every Ant-Design select; a programmatic `.click()` / nativeSetter does > NOT register. If a required dropdown won't open, fall back to §1. 3-step wizard: **Category → Brand → Identity**. > **MINIMAL PATH to a valid listing — do exactly these, in order, and > STOP:** > 1. Wizard create (Category → Brand → Identity), `fill_input` the SKU. > 2. **Offer tab** → `fill_input` **Base Price**, then **set Warranty** > (MANDATORY — see below), then **Save Changes** (green modal; price > persists across reload). > 3. **Content** on `/d?code=…&tab=content` → Product **Title** (EN via > `fill_input`, Arabic via `Input.insertText` — see §2.7) + set > **Gender** (MANDATORY; Department + Arabic gender auto-derive — §2.7) > → **Save Changes** → Submit → "sent for review" (async QC — done; > do NOT re-fill). > 4. **Image** (mandatory ≥1): upload the seller's **real product photo** > (§2.7) — a placeholder fails noon's async image validation and the > listing never goes live. > 5. **Seller Status → ON**. > > **Warranty is MANDATORY — but trivial: select "No Warranty".** The > Offer save FAILS with `Save failed — Warranty / No Offer Created` > unless the Warranty **type** is set. Do NOT try to configure a real > warranty (service center + 1–60mo duration — that path IS an > anti-automation rathole). Just open the Warranty **type** select and > pick **"No Warranty"** (options: No Warranty / Seller Warranty / > Manufacturer Warranty) — no service center or duration needed, and the > offer saves. Open it with a trusted `click_at_xy` on the select's > centre (it's below the fold — grow the viewport via > `Emulation.setDeviceMetricsOverride` first), then click the > **"No Warranty"** option in the `.ant-select-dropdown`. Verified live: > price + No-Warranty → Save → offer created, persists across reload. > > **Gender IS MANDATORY (verified live) — Department derives from it.** > Content Check flags `Missing Department` until Gender is set; you do > NOT set Department directly (there is no Department field). Set the > **English `Gender *`** select (e.g. `Men`) and noon **auto-fills the > Arabic gender (`رجال`) and clears the Department requirement**. The > Gender select is the same anti-automation ant-select as Warranty — open > it with the virtual-list technique in §2.7 (grow viewport → scroll the > dropdown's `.rc-virtual-list-holder` → in-panel trusted `click_at_xy`). > An earlier note calling Gender "optional, skip it" was WRONG — a listing > without Gender never clears mandatory content and never goes live. > > **These ARE optional — skip unless the seller asked:** Size Unit, > Feature Bullets, Long Description, Material, Colour, and the other > detailed-content attributes. The listing saves and goes live without > them. If a seller explicitly wants one and its dropdown won't open with > §2.7, note it as a manual follow-up rather than looping. **Runnable Offer-tab snippet (price + No Warranty) — copy verbatim.** The below-fold Warranty select can't be found by an un-scrolled DOM query; this grows the viewport, trusted-clicks the Warranty card's select, and picks "No Warranty". It also clears the price field first (`fill_input` *appends* if a value is already present → `59.59.9`). Verified live: ```bash browser-use <<'PY' import time, json # 1) price — clear first (fill_input appends to an existing value), then fill js("var i=document.querySelector('input[name=new_price]'); if(i){i.value='';}") fill_input('input[name="new_price"]', '59.90') # 2) Warranty = No Warranty (MANDATORY). Grow viewport (it's below fold), # trusted-click the Warranty card's ant-select, option-click No Warranty. cdp("Emulation.setDeviceMetricsOverride", width=1500, height=2200, deviceScaleFactor=1, mobile=False) time.sleep(2) info = js("""(function(){
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub