{"id":"code-dev-regex-sku-new-region","audience":"developers","category":"coding","track":"coding","technique":"context","title":"Write a SKU regex that passes the tests plus a new rule","free":false,"task":"The SKU check is failing its tests. Last week the warehouse added Z as a valid region letter, and the tests don't cover it yet, so the regex must accept regions A, B or Z. It also needs named groups region and num. Reply with exactly 1 code block containing only the single line const SKU_RE = /.../; with no flags, plus under 40 words of explanation.","materialLabel":"The failing validator and its tests (attached to your prompt automatically)","material":"// src/sku.js  (Node 20, ES2022)\n// SKU format: region letter, dash, 4 digits, optional dash + size code\n// Examples in the wild: A-1042, B-0007-L, A-9999-XL\nconst SKU_RE = /[A-Z]-\\d+/;   // TODO: too loose, see tests\n\nexport function isValidSku(text) {\n  return SKU_RE.test(text);\n}\n\nexport function skuParts(text) {\n  const m = text.match(SKU_RE);\n  return m ? m.groups : null;\n}\n\n// test/sku.test.js\nimport { isValidSku } from \"../src/sku.js\";\n\nconst mustMatch = [\n  \"A-1042\",\n  \"B-0007\",\n  \"B-0007-L\",\n  \"A-9999-XL\",\n  \"A-0001-S\",\n];\n\nconst mustNotMatch = [\n  \"a-1042\",       // lowercase region\n  \"C-1042\",       // unknown region\n  \"A-104\",        // only 3 digits\n  \"A-10420\",      // 5 digits\n  \"A-1042-XXL\",   // XXL isn't sold\n  \"A-1042-\",      // dangling dash\n  \" A-1042\",      // leading space\n  \"SKU A-1042\",   // extra text\n];\n\ntest.each(mustMatch)(\"accepts %s\", (s) => expect(isValidSku(s)).toBe(true));\ntest.each(mustNotMatch)(\"rejects %s\", (s) => expect(isValidSku(s)).toBe(false));\n\n// Valid size codes per the catalog: S, M, L, XL","rules":[{"type":"codeBlocks","count":1},{"type":"maxCodeLines","max":1},{"type":"maxProseWords","max":40}],"mistakes":[{"title":"Leaving out the new region","why":"The tests only show A and B, so the AI builds [AB] and rejects Z SKUs the warehouse now ships.","fix":"Add: \"Region letters are A, B or Z (Z is new and not in the tests yet).\"","checks":["r1"]},{"title":"Forgetting the groups","why":"skuParts() reads m.groups, but the AI won't add named groups unless asked.","fix":"Add: \"Use named groups region and num.\"","checks":["r2"]},{"title":"Getting test code and a tutorial","why":"The AI likes to explain each regex piece and reprint the tests.","fix":"Say: \"One code block with only the const SKU_RE line; under 40 words of explanation.\"","checks":["codeBlocks","maxCodeLines","maxProseWords"]},{"title":"Not anchoring","why":"Without ^ and $, ' A-1042' and 'SKU A-1042' slip through.","fix":"Add: \"Anchor with ^ and $; it must reject every mustNotMatch string.\"","checks":["r0"]}],"promptHints":[{"label":"Mentions the new Z region","patterns":["\\bZ\\b","new region","region.{0,20}(letter|A, B)"]},{"label":"Asks for named groups","patterns":["named group","\\?<","region and num"]},{"label":"Says what to return","patterns":["one line","const SKU_RE","only the regex","one code block"]},{"label":"Mentions anchoring or the tests","patterns":["anchor","\\^","must.?not.?match","tests"]},{"label":"Caps the explanation","patterns":["\\d+\\s*words","no explanation","brief"]}],"hint":"The tests are out of date and your code needs named groups. Give the AI the rule the tests don't show and tell it exactly what one line to hand back.","rubricLabels":["The regex is anchored with ^ and $ and allows only 4 digits and an optional size suffix of exactly -S, -M, -L or -XL, so it rejects every must-not-match example (lowercase, 3 or 5 digits, XXL, trailing dash, leading space, extra text)","The region part accepts only A, B or Z (e.g. [ABZ]), so C is rejected and Z is accepted","Uses named capture groups called region and num (e.g. (?<region>[ABZ]) and (?<num>\\d{4})), has no flags after the closing slash, and is written as const SKU_RE = /.../;"]}