mattrguerra/meridian-skillsmainPrivate on GitHub, published here in full

SKILL.md

Language Markdown9.9 KB152 lines

skills/production-speed-csv/SKILL.md

  1. ---
  2. name: production-speed-csv
  3. description: >-
  4. Build a CSV of turnaround options (Standard / Express / Super Express) for every product on a
  5. Meridian Display Co. category page. Use this skill whenever Matt provides a
  6. meridiandisplay.example category URL and asks for production speeds, turnaround times,
  7. business-day breakdowns, or a speed comparison spreadsheet, including casual phrasing like "pull
  8. the speed options for this category," "production days for these products," "build the speed CSV,"
  9. "speed table for the new category," or "how fast can we turn these around." Also use when Matt
  10. drops a category URL into chat with the phrase "production speeds" anywhere nearby.
  11. ---
  12. # Production Speed CSV
  13. Scrape every product page under a Meridian Display Co. category URL, parse the Turnaround Options section out of each, and produce a CSV with normalized day counts plus an overnight-shipping-adjusted column.
  14. ## What the output looks like
  15. A single CSV with seven columns:
  16. | # | Product Name | Standard Turnaround Days | Express Turnaround Days | Super Express Days | Production Days (slash-separated) | Production + Overnight Shipping (slash-separated) |
  17. Row example:
  18. ```
  19. 1,10x10 Modular Booth Kit with Half Side Panels,12 business days,8 business days,,12 / 8,13 / 9
  20. 2,Lightweight SEG Frame Display (10x8ft),7 business days,4 business days,2 business days,7 / 4 / 2,8 / 5 / 3
  21. 3,10ft Backlit Fabric Display,9 business days,5 business days,1 business day,9 / 5 / 1,10 / 6 / 2
  22. ```
  23. The last two columns use slash separators on purpose. See "Why slashes, not commas" below.
  24. ## Use the bundled script. Don't reimplement.
  25. `scripts/build_speed_csv.py` encodes everything painful that came out of building this the first time: every label variant observed in the wild, the option-group bounding logic that keeps the parser from greedy-matching neighboring radio groups, and the rate-limit-safe fetch cadence. If you re-derive any of this from scratch you will miss cases.
  26. Run it:
  27. ```
  28. python scripts/build_speed_csv.py <category_url> [<output_csv_path>]
  29. ```
  30. Example:
  31. ```
  32. python scripts/build_speed_csv.py https://meridiandisplay.example/10x10-booths/
  33. ```
  34. Default output path is `<category_slug>_production_speeds.csv` in the current directory.
  35. The script:
  36. - Fetches the category page, extracts every product URL while preserving the on-page display order
  37. - Excludes nav/menu/utility URLs (menus, contact, help, the turnaround guide, the category page itself)
  38. - Fetches each product page sequentially with 1.5-second spacing (well under the WAF rate-limit threshold for a typical 15-25 product category; see the `site-safe-fetch` skill for the broader rate-limit story if you ever scale this up)
  39. - Locates the `md-option-group` headed "Turnaround Option" or "Turnaround Options" on each page
  40. - Extracts the `data-option-label` of every radio option in that block
  41. - Maps each option to one of three tiers (Standard / Express / Super Express) using the label-variant table
  42. - Writes the CSV
  43. It prints a per-product summary as it runs and flags any product where it found no speed options at all.
  44. ## Test fixture (offline mode)
  45. `scripts/fixtures/` holds a small invented category page (`category-10x10-booths.html`), one saved page per product, and the CSV the script should produce (`expected.csv`). If the first argument is a file on disk rather than a URL, the script runs offline: it reads the category page from that file, takes the category URL from its `<link rel="canonical">`, and reads each product from `<slug>.html` in the same folder, with no network access and no request spacing. URL runs are unchanged.
  46. ```
  47. cd scripts
  48. python build_speed_csv.py fixtures/category-10x10-booths.html /tmp/speeds.csv
  49. diff /tmp/speeds.csv fixtures/expected.csv
  50. ```
  51. The fixture exercises every case the parser has to handle: nav, footer and duplicate links; option groups before and after the speed block that must not leak into it; lowercase, colon and "Order" label variants; a day count with no space before it; a size caveat; an unknown tier ("Economy"); and a custom-quote product with no Turnaround section and no H1. Run it after any change to the parser or to `references/label_variants.md`.
  52. ## The +1 column = overnight shipping
  53. The "Production + Overnight Shipping" column is production days + 1, representing the most common client-facing total turnaround quote (production + one overnight). Do not interpret it as a buffer or safety margin. It's a literal shipping-day add.
  54. For Super Express at 1 business day, the +1 math still applies (1 + 1 = 2 door-to-door). That's correct: a Super Express order shipped overnight arrives in two business days total.
  55. ## Why slashes, not commas
  56. The two summary columns use `12 / 8` not `12, 8`. Reason: Claude.ai's in-browser CSV previewer has a bug where it ignores RFC 4180 quote-escaping. A cell containing `"12, 8"` (correct CSV) gets split into two cells with literal quote characters showing. Slashes sidestep this and render correctly in every viewer Matt actually opens the file in (preview, Excel, Sheets, Numbers).
  57. If you ever need actual commas inside those cells (e.g., for a downstream parser that splits on commas), edit the script: there's a `SEPARATOR` constant at the top. RFC-correct CSV will work in Excel/Sheets, just not in the Claude.ai preview.
  58. ## Label variant handling
  59. Meridian product pages do not use a consistent label vocabulary for turnaround options. The script handles all known variants:
  60. **Standard tier:**
  61. - `Standard Turnaround` (most common)
  62. - `Standard turnaround` (lowercase t)
  63. - `Standard turnaround:` (with colon)
  64. - `Standard Order` (used on Booth Concept A, Booth Concept B, Monitor Stand Bridge, and possibly other "request-a-quote" style pages)
  65. **Express tier:**
  66. - `Express Turnaround`
  67. - `Express turnaround`
  68. - `Express turnaround:`
  69. - `Express order`
  70. **Super Express tier:**
  71. - `Super Express Turnaround`
  72. - `Super Express turnaround` (sometimes runs into the day count with no space: "Super Express turnaround1 business day")
  73. The script normalizes all of these to the three canonical tier names in the CSV.
  74. Inconsistent whitespace and missing spaces ("Turnaround10 business days") are also tolerated, because the script extracts the day count by regex, not by splitting on whitespace.
  75. See `references/label_variants.md` for the full table and how to add new variants.
  76. ## Caveats are dropped from the cell
  77. Some products have constraints attached to a speed tier. The clearest case is the 10ft Backlit Fabric Display, where Super Express is `1 business day` but only on the 8ft and 10ft widths. The script puts only the day count in the cell (e.g., `1 business day`) and does **not** include the caveat inline.
  78. Rationale: the Super Express column should stay clean and machine-readable. Caveats belong somewhere else: a notes column the consumer adds, a separate exceptions file, CRM notes on the SKU. The script prints any caveat it stripped to the terminal so it's not silently lost.
  79. If Matt asks for caveats in-line, edit the script. The caveat text is captured in the parser, just suppressed at the write step.
  80. ## Data quality observations to surface
  81. While running the script, surface anything that looks like a data inconsistency on the storefront. Matt sells these and uses this skill to audit turnaround quotes, so he wants to know about problems on the site. Things worth flagging:
  82. - **Label inconsistency across products** (some pages say "Standard Turnaround," others "Standard Order"). Indicates a copy mismatch between product page templates.
  83. - **Suspicious turnaround times** that deviate from the category norm (e.g., a 5-day standard when every other product in the category is 12 days). Could be a copy-paste error on the page or an actual production difference, so check with the production team.
  84. - **Size-gated Super Express options** (the 8ft/10ft caveat on the backlit fabric display). Easy for a client to pick the option on an ineligible size and get a surprise later.
  85. - **Products missing a Turnaround section entirely.** The script logs these. Usually means a custom-quote-only product, but worth confirming.
  86. Don't fix these. Flag them in the response so Matt can route them to production or the web team.
  87. ## How to run the skill
  88. When triggered:
  89. 1. **Confirm the category URL.** If Matt gave one, use it. If he just said "for the new category" or similar, ask which one.
  90. 2. **Run the script.** Output progress per product. Show the final summary (total products, count with all three tiers, count with two tiers, count with no speed section).
  91. 3. **Present the file.** Use `present_files` so Matt can download or open it directly.
  92. 4. **Surface anomalies.** List any data-quality oddities the parser saw: label inconsistencies, suspicious times, size caveats, missing sections. Keep it brief.
  93. ## When the script fails
  94. - **The WAF fires (403 Forbidden):** Stop. Wait 15 minutes. Tell Matt. See the `site-safe-fetch` skill for how to recognise a WAF block and the broader recovery pattern. (For a single category this should never happen, so if it does, something's off.)
  95. - **A product page returns 404:** Log the URL, skip the row, continue. Probably a recently-removed product still linked from the category page.
  96. - **The Turnaround section is missing on a product:** That's the script's "no options found" log line. Leave the row out of the CSV and mention it in the response. Often these are custom-quote-only products.
  97. - **A new label variant appears that the script doesn't recognize:** The script logs the raw `data-option-label` string. Open `scripts/build_speed_csv.py`, add the variant to the `TIER_PATTERNS` list, rerun. Don't paper over it with a looser regex, because that will misclassify.
  98. ## Bundled files
  99. - `scripts/build_speed_csv.py`: end-to-end fetch, parse, and CSV writer. Run as a CLI.
  100. - `scripts/fixtures/`: offline test fixture (invented category page, product pages, and `expected.csv`).
  101. - `references/label_variants.md`: the full known-variant table for turnaround labels, plus the procedure for adding a new one.