diff --git a/openapi/calle.openapi.yaml b/openapi/calle.openapi.yaml index 3475d52..938e9d7 100644 --- a/openapi/calle.openapi.yaml +++ b/openapi/calle.openapi.yaml @@ -1163,6 +1163,8 @@ components: This is useful for batch calls where each recipient needs their own outcome, such as `can_attend`, `confirmed`, `requested_callback`, or `interest_level`. + Supported schema features are `type`, `properties`, `required`, `enum`, nested `object` fields, simple `array.items`, `description`, and `additionalProperties: false`. Unsupported features include `$ref`, `oneOf`, `anyOf`, `allOf`, recursive schemas, complex format validation, and `additionalProperties: true`. + Do not use reserved recipient response field names such as `summary`, `status`, `transcript`, `call_id`, or timing fields as custom result fields. Use names such as `customer_summary`, `notes`, or `reason` instead. Field `description` values are passed to the extraction model and should explain how enum values should be selected. Descriptions guide extraction but are not hard validation rules. Hard validation comes from `type`, `required`, `enum`, and `additionalProperties`. diff --git a/src/regions.mjs b/src/regions.mjs index 8e3a050..f19d658 100644 --- a/src/regions.mjs +++ b/src/regions.mjs @@ -17,8 +17,7 @@ export function extractRegions(readme) { !section || !rows || rows.length < 3 || - rows[0] !== - "| Country | Country Code | Calling Code | Languages | Default Line |" || + !/^\| Country \| Country Code \| Calling Code \| Languages \| (?:Default Line|Line Region) \|$/.test(rows[0]) || !/^\|(?:[ \t]*:?-+:?[ \t]*\|){5}$/.test(rows[1]) || rows.some((row) => row.split("|").length !== 7) || rows.slice(2).some((row) => diff --git a/tests/docs-site.spec.ts b/tests/docs-site.spec.ts index d7d7c9e..55d0af3 100644 --- a/tests/docs-site.spec.ts +++ b/tests/docs-site.spec.ts @@ -75,6 +75,8 @@ Unrelated examples.`; test("extracts only valid region coverage from the source README", () => { expect(extractRegions(regionsReadme)).toBe(regionSection); expect(extractRegions(regionsReadme.replaceAll("\n", "\r\n"))).toBe(regionSection); + expect(extractRegions(regionsReadme.replace("Default Line", "Line Region"))) + .toBe(regionSection.replace("Default Line", "Line Region")); for (const invalid of [ regionsReadme.replace("Supported Regions and Languages", "Removed section"), regionsReadme.replace("| Languages |", "| Renamed column |"), @@ -100,6 +102,13 @@ test("refreshes region coverage without rebuilding the docs", async ({ page }) = await expect(page.getByRole("cell", { name: "Test language" })).toBeVisible(); await expect(page.getByText("Unrelated examples.")).toHaveCount(0); + await page.route(REGIONS_README_URL, (route) => route.fulfill({ + contentType: "text/plain", + body: regionsReadme.replace("Default Line", "Line Region"), + })); + await page.reload(); + await expect(page.getByRole("columnheader", { name: "Line Region" })).toBeVisible(); + await page.setViewportSize({ width: 390, height: 844 }); expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(390); await page.setViewportSize({ width: 1280, height: 720 }); @@ -113,13 +122,13 @@ test("refreshes region coverage without rebuilding the docs", async ({ page }) = test("retains a readable region snapshot when refresh fails", async ({ page, request }) => { await page.setViewportSize({ width: 390, height: 844 }); - const tableHeader = "| Country | Country Code | Calling Code | Languages | Default Line |"; + const tableHeader = /\| Country \| Country Code \| Calling Code \| Languages \| (?:Default Line|Line Region) \|/; const html = await request.get("/regions"); expect(await html.text()).toContain("