codeant-ai-for-open-source[bot] commented on code in PR #37434:
URL: https://github.com/apache/superset/pull/37434#discussion_r2729749543


##########
docs/scripts/generate-api-index.mjs:
##########
@@ -0,0 +1,240 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Generates a comprehensive API index MDX file from the OpenAPI spec.
+ * This creates the api.mdx landing page with all endpoints organized by 
category.
+ */
+
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+const SPEC_PATH = path.join(__dirname, '..', 'static', 'resources', 
'openapi.json');
+const OUTPUT_PATH = path.join(__dirname, '..', 'docs', 'api.mdx');
+
+// Category groupings for better organization
+const CATEGORY_GROUPS = {
+  'Authentication': ['Security'],
+  'Core Resources': ['Dashboards', 'Charts', 'Datasets', 'Database'],
+  'Data Exploration': ['Explore', 'SQL Lab', 'Queries', 'Datasources', 
'Advanced Data Type'],
+  'Organization & Customization': ['Tags', 'Annotation Layers', 'CSS 
Templates'],
+  'Sharing & Embedding': [
+    'Dashboard Permanent Link', 'Explore Permanent Link', 'SQL Lab Permanent 
Link',
+    'Embedded Dashboard', 'Dashboard Filter State', 'Explore Form Data'
+  ],
+  'Scheduling & Alerts': ['Report Schedules'],
+  'Security & Access Control': [
+    'Security Roles', 'Security Users', 'Security Permissions',
+    'Security Resources (View Menus)', 'Security Permissions on Resources 
(View Menus)',
+    'Row Level Security'
+  ],
+  'Import/Export & Administration': ['Import/export', 'CacheRestApi', 
'LogRestApi'],
+  'User & System': ['Current User', 'User', 'Menu', 'Available Domains', 
'AsyncEventsRestApi', 'OpenApi'],
+};
+
+function slugify(text) {
+  return text
+    .toLowerCase()
+    .replace(/[^a-z0-9]+/g, '-')
+    .replace(/(^-|-$)/g, '');
+}
+
+function generateEndpointLink(summary) {
+  // Convert summary to the slug format used by docusaurus-openapi-docs
+  return slugify(summary);
+}
+
+function main() {
+  console.log(`Reading OpenAPI spec from ${SPEC_PATH}`);
+  const spec = JSON.parse(fs.readFileSync(SPEC_PATH, 'utf-8'));
+
+  // Build a map of tag -> endpoints
+  const tagEndpoints = {};
+  const tagDescriptions = {};
+
+  // Get tag descriptions
+  for (const tag of spec.tags || []) {
+    tagDescriptions[tag.name] = tag.description || '';
+  }
+
+  // Collect endpoints by tag
+  for (const [pathUrl, methods] of Object.entries(spec.paths || {})) {
+    for (const [method, details] of Object.entries(methods)) {
+      if (!['get', 'post', 'put', 'delete', 'patch'].includes(method)) 
continue;
+
+      const tags = details.tags || ['Untagged'];
+      const summary = details.summary || `${method.toUpperCase()} ${pathUrl}`;
+
+      for (const tag of tags) {
+        if (!tagEndpoints[tag]) {
+          tagEndpoints[tag] = [];
+        }
+        tagEndpoints[tag].push({
+          method: method.toUpperCase(),
+          path: pathUrl,
+          summary,
+          slug: generateEndpointLink(summary),
+        });
+      }
+    }
+  }
+
+  // Sort endpoints within each tag by path
+  for (const tag of Object.keys(tagEndpoints)) {
+    tagEndpoints[tag].sort((a, b) => a.path.localeCompare(b.path));
+  }
+
+  // Generate MDX content
+  let mdx = `---
+title: API Reference
+hide_title: true
+sidebar_position: 10
+---
+
+import { Alert } from 'antd';
+
+## REST API Reference
+
+Superset exposes a comprehensive **REST API** that follows the [OpenAPI 
specification](https://swagger.io/specification/).
+You can use this API to programmatically interact with Superset for 
automation, integrations, and custom applications.
+
+<Alert
+  type="info"
+  showIcon
+  message="Code Samples & Schema Documentation"
+  description={
+    <span>
+      Each endpoint includes ready-to-use code samples in 
<strong>cURL</strong>, <strong>Python</strong>, and <strong>JavaScript</strong>.
+      Browse the <a href="./api/schemas">Schema definitions</a> for detailed 
data model documentation.
+    </span>
+  }
+  style={{ marginBottom: '24px' }}
+/>
+
+---
+
+`;
+
+  // Track which tags we've rendered
+  const renderedTags = new Set();
+
+  // Render Authentication first (it's critical for using the API)
+  mdx += `### Authentication
+
+Most API endpoints require authentication via JWT tokens.
+
+#### Quick Start
+
+\`\`\`bash
+# 1. Get a JWT token
+curl -X POST http://localhost:8088/api/v1/security/login \\
+  -H "Content-Type: application/json" \\
+  -d '{"username": "admin", "password": "admin", "provider": "db"}'
+
+# 2. Use the access_token from the response
+curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \\
+  http://localhost:8088/api/v1/dashboard/
+\`\`\`
+
+#### Security Endpoints
+
+`;
+
+  // Render Security tag endpoints
+  if (tagEndpoints['Security']) {
+    mdx += `| Method | Endpoint | Description |\n`;
+    mdx += `|--------|----------|-------------|\n`;
+    for (const ep of tagEndpoints['Security']) {
+      mdx += `| \`${ep.method}\` | [${ep.summary}](./api/${ep.slug}) | 
\`${ep.path}\` |\n`;
+    }
+    mdx += '\n';
+    renderedTags.add('Security');
+  }
+
+  mdx += `---\n\n### API Endpoints\n\n`;
+
+  // Render each category group
+  for (const [groupName, groupTags] of Object.entries(CATEGORY_GROUPS)) {
+    if (groupName === 'Authentication') continue; // Already rendered
+
+    const tagsInGroup = groupTags.filter(tag => tagEndpoints[tag] && 
!renderedTags.has(tag));
+    if (tagsInGroup.length === 0) continue;
+
+    mdx += `#### ${groupName}\n\n`;
+
+    for (const tag of tagsInGroup) {
+      const description = tagDescriptions[tag] || '';
+      const endpoints = tagEndpoints[tag];
+
+      mdx += `<details>\n`;
+      mdx += `<summary><strong>${tag}</strong> (${endpoints.length} endpoints) 
— ${description}</summary>\n\n`;
+      mdx += `| Method | Endpoint | Description |\n`;
+      mdx += `|--------|----------|-------------|\n`;
+
+      for (const ep of endpoints) {
+        mdx += `| \`${ep.method}\` | [${ep.summary}](./api/${ep.slug}) | 
\`${ep.path}\` |\n`;
+      }
+
+      mdx += `\n</details>\n\n`;
+      renderedTags.add(tag);
+    }
+  }
+
+  // Render any remaining tags not in a group
+  const remainingTags = Object.keys(tagEndpoints).filter(tag => 
!renderedTags.has(tag));
+  if (remainingTags.length > 0) {
+    mdx += `#### Other\n\n`;
+
+    for (const tag of remainingTags.sort()) {
+      const description = tagDescriptions[tag] || '';
+      const endpoints = tagEndpoints[tag];
+
+      mdx += `<details>\n`;
+      mdx += `<summary><strong>${tag}</strong> (${endpoints.length} endpoints) 
— ${description}</summary>\n\n`;
+      mdx += `| Method | Endpoint | Description |\n`;
+      mdx += `|--------|----------|-------------|\n`;
+
+      for (const ep of endpoints) {
+        mdx += `| \`${ep.method}\` | [${ep.summary}](./api/${ep.slug}) | 
\`${ep.path}\` |\n`;

Review Comment:
   **Suggestion:** In the "Other" tag section, endpoint links again use 
`./api/${ep.slug}` from the `/docs/api` page, which incorrectly resolves to 
`/docs/api/api/<slug>` and breaks all links for uncategorized tags. [logic 
error]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ \"Other\" section links 404 on the API index page.
   - ⚠️ Unlabeled endpoints unreachable from index.
   - ⚠️ Search/navigation burden increased for users.
   ```
   </details>
   
   ```suggestion
           mdx += `| \`${ep.method}\` | [${ep.summary}](./${ep.slug}) | 
\`${ep.path}\` |\n`;
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Run docs/scripts/generate-api-index.mjs which produces the "Other" tag 
section using
   the loop at docs/scripts/generate-api-index.mjs:204-223; the per-endpoint 
link template is
   at lines 217-219.
   
   2. Serve the site (yarn start) and open /docs/api/; scroll to the "Other" 
section
   generated from the remaining tags.
   
   3. Click any endpoint link in that "Other" section. The link target uses 
"./api/<slug>"
   (from the generator at docs/scripts/generate-api-index.mjs:219) and resolves 
to
   /docs/api/api/<slug> instead of /docs/api/<slug>, leading to missing pages.
   
   4. Inspecting api.mdx confirms the duplicated "api" segment was produced by 
the template;
   switching to "./${ep.slug}" (improved code) produces correct links.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** docs/scripts/generate-api-index.mjs
   **Line:** 218:218
   **Comment:**
        *Logic Error: In the "Other" tag section, endpoint links again use 
`./api/${ep.slug}` from the `/docs/api` page, which incorrectly resolves to 
`/docs/api/api/<slug>` and breaks all links for uncategorized tags.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



##########
docs/src/styles/custom.css:
##########
@@ -187,3 +187,81 @@ ul.dropdown__menu svg {
 [data-theme='dark'] .ant-collapse-header {
   color: var(--ifm-font-base-color);
 }
+
+/* Hide the non-functional "Send API Request" button and Response block in API 
docs */
+/* The interactive API testing doesn't work due to CORS restrictions */
+.openapi-explorer__request-btn {
+  display: none !important;
+}
+
+.openapi-explorer__response-container {
+  display: none !important;

Review Comment:
   **Suggestion:** Hiding `.openapi-explorer__response-container` with 
`display: none !important` will completely remove the API "Response" block from 
all endpoint pages, which likely includes the documented response status codes 
and schemas that the new API reference is supposed to expose, so users won't 
see response information at all; keeping the button hidden is fine, but the 
response container itself should remain visible. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ API response schemas hidden on all endpoint pages.
   - ❌ Response status codes invisible to documentation readers.
   - ⚠️ Developer portal `/docs/api/` user experience degraded.
   - ⚠️ Documentation testers cannot see examples inline.
   ```
   </details>
   
   ```suggestion
     /* Keep the response container visible so response status codes and 
schemas remain documented.
        Interactive "Send request" behavior is disabled separately via the 
request button rule. */
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Build and run the docs site locally (as described in PR): run `cd docs && 
yarn install
   && yarn start`.
   
   2. Open the API reference landing page at `/docs/api/` in the running dev 
server.
   
   3. Navigate to any endpoint page (e.g., click an endpoint entry on the 
landing page).
   
   4. Inspect the endpoint page DOM in the browser devtools and find the 
element with class
   `openapi-explorer__response-container` (the docusaurus-openapi-docs response 
block).
   
   5. Observe that because `docs/src/styles/custom.css` contains the rule at 
lines 197-199,
   the response container element has `display: none !important` and is hidden 
— response
   status codes and example schemas are not visible.
   
   6. Confirm behavior is global by testing multiple endpoints: the same CSS 
rule in
   `docs/src/styles/custom.css:197-199` hides responses site-wide.
   
   Note: Hiding the request button is appropriate for CORS reasons
   (`.openapi-explorer__request-btn` at lines 193-195), but the separate 
response container
   rule at 197-199 removes documented response information entirely.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** docs/src/styles/custom.css
   **Line:** 198:198
   **Comment:**
        *Logic Error: Hiding `.openapi-explorer__response-container` with 
`display: none !important` will completely remove the API "Response" block from 
all endpoint pages, which likely includes the documented response status codes 
and schemas that the new API reference is supposed to expose, so users won't 
see response information at all; keeping the button hidden is fine, but the 
response container itself should remain visible.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



##########
docs/scripts/generate-api-index.mjs:
##########
@@ -0,0 +1,240 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Generates a comprehensive API index MDX file from the OpenAPI spec.
+ * This creates the api.mdx landing page with all endpoints organized by 
category.
+ */
+
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+const SPEC_PATH = path.join(__dirname, '..', 'static', 'resources', 
'openapi.json');
+const OUTPUT_PATH = path.join(__dirname, '..', 'docs', 'api.mdx');
+
+// Category groupings for better organization
+const CATEGORY_GROUPS = {
+  'Authentication': ['Security'],
+  'Core Resources': ['Dashboards', 'Charts', 'Datasets', 'Database'],
+  'Data Exploration': ['Explore', 'SQL Lab', 'Queries', 'Datasources', 
'Advanced Data Type'],
+  'Organization & Customization': ['Tags', 'Annotation Layers', 'CSS 
Templates'],
+  'Sharing & Embedding': [
+    'Dashboard Permanent Link', 'Explore Permanent Link', 'SQL Lab Permanent 
Link',
+    'Embedded Dashboard', 'Dashboard Filter State', 'Explore Form Data'
+  ],
+  'Scheduling & Alerts': ['Report Schedules'],
+  'Security & Access Control': [
+    'Security Roles', 'Security Users', 'Security Permissions',
+    'Security Resources (View Menus)', 'Security Permissions on Resources 
(View Menus)',
+    'Row Level Security'
+  ],
+  'Import/Export & Administration': ['Import/export', 'CacheRestApi', 
'LogRestApi'],
+  'User & System': ['Current User', 'User', 'Menu', 'Available Domains', 
'AsyncEventsRestApi', 'OpenApi'],
+};
+
+function slugify(text) {
+  return text
+    .toLowerCase()
+    .replace(/[^a-z0-9]+/g, '-')
+    .replace(/(^-|-$)/g, '');
+}
+
+function generateEndpointLink(summary) {
+  // Convert summary to the slug format used by docusaurus-openapi-docs
+  return slugify(summary);
+}
+
+function main() {
+  console.log(`Reading OpenAPI spec from ${SPEC_PATH}`);
+  const spec = JSON.parse(fs.readFileSync(SPEC_PATH, 'utf-8'));
+
+  // Build a map of tag -> endpoints
+  const tagEndpoints = {};
+  const tagDescriptions = {};
+
+  // Get tag descriptions
+  for (const tag of spec.tags || []) {
+    tagDescriptions[tag.name] = tag.description || '';
+  }
+
+  // Collect endpoints by tag
+  for (const [pathUrl, methods] of Object.entries(spec.paths || {})) {
+    for (const [method, details] of Object.entries(methods)) {
+      if (!['get', 'post', 'put', 'delete', 'patch'].includes(method)) 
continue;
+
+      const tags = details.tags || ['Untagged'];
+      const summary = details.summary || `${method.toUpperCase()} ${pathUrl}`;
+
+      for (const tag of tags) {
+        if (!tagEndpoints[tag]) {
+          tagEndpoints[tag] = [];
+        }
+        tagEndpoints[tag].push({
+          method: method.toUpperCase(),
+          path: pathUrl,
+          summary,
+          slug: generateEndpointLink(summary),
+        });
+      }
+    }
+  }
+
+  // Sort endpoints within each tag by path
+  for (const tag of Object.keys(tagEndpoints)) {
+    tagEndpoints[tag].sort((a, b) => a.path.localeCompare(b.path));
+  }
+
+  // Generate MDX content
+  let mdx = `---
+title: API Reference
+hide_title: true
+sidebar_position: 10
+---
+
+import { Alert } from 'antd';
+
+## REST API Reference
+
+Superset exposes a comprehensive **REST API** that follows the [OpenAPI 
specification](https://swagger.io/specification/).
+You can use this API to programmatically interact with Superset for 
automation, integrations, and custom applications.
+
+<Alert
+  type="info"
+  showIcon
+  message="Code Samples & Schema Documentation"
+  description={
+    <span>
+      Each endpoint includes ready-to-use code samples in 
<strong>cURL</strong>, <strong>Python</strong>, and <strong>JavaScript</strong>.
+      Browse the <a href="./api/schemas">Schema definitions</a> for detailed 
data model documentation.
+    </span>
+  }
+  style={{ marginBottom: '24px' }}
+/>
+
+---
+
+`;
+
+  // Track which tags we've rendered
+  const renderedTags = new Set();
+
+  // Render Authentication first (it's critical for using the API)
+  mdx += `### Authentication
+
+Most API endpoints require authentication via JWT tokens.
+
+#### Quick Start
+
+\`\`\`bash
+# 1. Get a JWT token
+curl -X POST http://localhost:8088/api/v1/security/login \\
+  -H "Content-Type: application/json" \\
+  -d '{"username": "admin", "password": "admin", "provider": "db"}'
+
+# 2. Use the access_token from the response
+curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \\
+  http://localhost:8088/api/v1/dashboard/
+\`\`\`
+
+#### Security Endpoints
+
+`;
+
+  // Render Security tag endpoints
+  if (tagEndpoints['Security']) {
+    mdx += `| Method | Endpoint | Description |\n`;
+    mdx += `|--------|----------|-------------|\n`;
+    for (const ep of tagEndpoints['Security']) {
+      mdx += `| \`${ep.method}\` | [${ep.summary}](./api/${ep.slug}) | 
\`${ep.path}\` |\n`;
+    }
+    mdx += '\n';
+    renderedTags.add('Security');
+  }
+
+  mdx += `---\n\n### API Endpoints\n\n`;
+
+  // Render each category group
+  for (const [groupName, groupTags] of Object.entries(CATEGORY_GROUPS)) {
+    if (groupName === 'Authentication') continue; // Already rendered
+
+    const tagsInGroup = groupTags.filter(tag => tagEndpoints[tag] && 
!renderedTags.has(tag));
+    if (tagsInGroup.length === 0) continue;
+
+    mdx += `#### ${groupName}\n\n`;
+
+    for (const tag of tagsInGroup) {
+      const description = tagDescriptions[tag] || '';
+      const endpoints = tagEndpoints[tag];
+
+      mdx += `<details>\n`;
+      mdx += `<summary><strong>${tag}</strong> (${endpoints.length} endpoints) 
— ${description}</summary>\n\n`;
+      mdx += `| Method | Endpoint | Description |\n`;
+      mdx += `|--------|----------|-------------|\n`;
+
+      for (const ep of endpoints) {
+        mdx += `| \`${ep.method}\` | [${ep.summary}](./api/${ep.slug}) | 
\`${ep.path}\` |\n`;

Review Comment:
   **Suggestion:** In the grouped category sections, endpoint links are built 
as `./api/${ep.slug}` from the `/docs/api` page, which resolves to 
`/docs/api/api/<slug>` and thus does not match the actual OpenAPI-generated 
routes under `/docs/api/<slug>`. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ Category endpoint links broken on API index page.
   - ⚠️ Users cannot open endpoint docs from categories.
   - ⚠️ Documentation navigation is confusing.
   ```
   </details>
   
   ```suggestion
           mdx += `| \`${ep.method}\` | [${ep.summary}](./${ep.slug}) | 
\`${ep.path}\` |\n`;
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Execute docs/scripts/generate-api-index.mjs to produce docs/docs/api.mdx 
(script writes
   output at docs/scripts/generate-api-index.mjs:234-235). The category 
sections use the loop
   at docs/scripts/generate-api-index.mjs:176-201 and produce per-endpoint 
links using the
   template at lines 194-196.
   
   2. Serve docs (yarn start) and navigate to /docs/api/ where the category 
tables are
   displayed.
   
   3. Click any endpoint link inside a grouped category. The anchor generated 
from the
   template is "./api/<slug>" (docs/scripts/generate-api-index.mjs:196) which 
resolves to
   /docs/api/api/<slug>, not /docs/api/<slug>, causing the link to fail to 
reach the
   OpenAPI-generated page.
   
   4. Verify by inspecting the generated MDX (api.mdx) or browser link target; 
fix by
   changing the template to "./${ep.slug}" as in the improved code.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** docs/scripts/generate-api-index.mjs
   **Line:** 195:195
   **Comment:**
        *Logic Error: In the grouped category sections, endpoint links are 
built as `./api/${ep.slug}` from the `/docs/api` page, which resolves to 
`/docs/api/api/<slug>` and thus does not match the actual OpenAPI-generated 
routes under `/docs/api/<slug>`.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



##########
docs/sidebars.js:
##########
@@ -107,9 +107,14 @@ const sidebars = {
       id: 'faq',
     },
     {
-      type: 'doc',
-      label: 'API',
-      id: 'api',
+      type: 'category',
+      label: 'API Reference',
+      link: {
+        type: 'doc',
+        id: 'api',
+      },
+      // eslint-disable-next-line @typescript-eslint/no-require-imports
+      items: require('./docs/api/sidebar.js'),

Review Comment:
   **Suggestion:** The sidebar now unconditionally requires a generated file 
`./docs/api/sidebar.js`; on a fresh clone or whenever `yarn generate:api-docs` 
hasn't been run yet, this file does not exist, so loading `sidebars.js` (and 
thus running Docusaurus commands directly) will throw a "Cannot find module 
'./docs/api/sidebar.js'" error and break the docs build; wrapping the require 
with a try/catch and falling back to an empty array makes the configuration 
robust while still using the generated sidebar when available. [possible bug]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ Local docs dev server fails to start.
   - ❌ CI docs build fails on fresh clones.
   - ⚠️ New contributors blocked running docs locally.
   - ⚠️ Release docs automation may break without generation.
   ```
   </details>
   
   ```suggestion
           items: (() => {
             try {
               // Generated by `yarn generate:api-docs`
               return require('./docs/api/sidebar.js');
             } catch (error) {
               // Fallback when API sidebar has not been generated yet
               return [];
             }
           })(),
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Clone the repository and do not run the API generation step (skip `yarn
   generate:api-docs`), so `docs/api/sidebar.js` is absent.
   
   2. From the repository root run the docs dev server in the docs directory: 
`cd docs &&
   yarn start`. Docusaurus loads `docs/sidebars.js` during startup.
   
   3. `docs/sidebars.js` (file path: `docs/sidebars.js`, lines 107-118) 
executes the line
   `items: require('./docs/api/sidebar.js')` and Node attempts to resolve
   `./docs/api/sidebar.js`.
   
   4. Because `./docs/api/sidebar.js` does not exist, Node throws "Cannot find 
module
   './docs/api/sidebar.js'" and the Docusaurus build/dev server fails to start 
— observable
   as a startup error in the terminal where `yarn start` was run.
   
   5. Repeating in CI: any CI job that runs docs build without first generating 
the API docs
   will reproduce the same failure during the docs build step (the exact 
failing location is
   `docs/sidebars.js:107-118` as shown above).
   
   Note: This is not hypothetical — the PR introduced an unconditional require 
for a
   generated file (`./docs/api/sidebar.js`) in `docs/sidebars.js` (lines 
107-118), so a fresh
   clone or skipped generation step will trigger this error.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** docs/sidebars.js
   **Line:** 115:117
   **Comment:**
        *Possible Bug: The sidebar now unconditionally requires a generated 
file `./docs/api/sidebar.js`; on a fresh clone or whenever `yarn 
generate:api-docs` hasn't been run yet, this file does not exist, so loading 
`sidebars.js` (and thus running Docusaurus commands directly) will throw a 
"Cannot find module './docs/api/sidebar.js'" error and break the docs build; 
wrapping the require with a try/catch and falling back to an empty array makes 
the configuration robust while still using the generated sidebar when available.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



##########
docs/docusaurus.config.ts:
##########
@@ -189,6 +195,29 @@ const config: Config = {
       },
     ],
     ...dynamicPlugins,
+    [
+      'docusaurus-plugin-openapi-docs',
+      {
+        id: 'api',
+        docsPluginId: 'classic',

Review Comment:
   **Suggestion:** The OpenAPI docs plugin is configured to attach to a docs 
plugin with id `classic`, but in this configuration the main docs plugin 
created by the `@docusaurus/preset-classic` preset has no explicit `id` and 
therefore uses the default id (`default`), so the OpenAPI plugin will not find 
the expected docs instance and `docusaurus gen-api-docs superset`/builds can 
fail with "docs plugin not found" errors. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ API docs generation fails during docs build.
   - ⚠️ Contributor local docs workflow blocked.
   - ⚠️ CI docs build may fail for PRs touching docs.
   - ❌ /docs/api pages won't be produced.
   ```
   </details>
   
   ```suggestion
           docsPluginId: 'default',
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open the Docusaurus site config at docs/docusaurus.config.ts and locate 
the preset docs
   block starting at `presets` around `docs/docusaurus.config.ts:372` where the 
preset
   classic's docs options are defined (see `docs: { sidebarPath:
   require.resolve('./sidebars.js'), ... }` at ~line 374). This preset 
registers the docs
   plugin without an explicit id (so it uses the default id `default`).
   
   2. Inspect the OpenAPI plugin configuration at 
`docs/docusaurus.config.ts:199-219` where
   the plugin is registered. The plugin is configured with `docsPluginId: 
'classic'` (exact
   line: `docs/docusaurus.config.ts:202`).
   
   3. Run the docs build or generation step (e.g., from repository root: `cd 
docs && yarn
   start` or `yarn build`). During startup Docusaurus initializes plugins; the 
openapi plugin
   will attempt to look up the docs plugin instance by id `'classic'`.
   
   4. Because the preset-registered docs plugin has no id (it is the default 
`default`), the
   openapi plugin cannot find a docs instance named `'classic'` and the 
generation step
   errors with messages such as "docs plugin not found" or "Cannot find docs 
plugin with id
   'classic'". This prevents API docs from being generated and the site build 
from
   completing.
   
   Note: I verified the two locations above in the final file: the preset docs 
block (no
   explicit id) at the presets section (~line 372-380) and the openapi plugin 
config
   containing `docsPluginId: 'classic'` at line 202 in 
`docs/docusaurus.config.ts`.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** docs/docusaurus.config.ts
   **Line:** 202:202
   **Comment:**
        *Logic Error: The OpenAPI docs plugin is configured to attach to a docs 
plugin with id `classic`, but in this configuration the main docs plugin 
created by the `@docusaurus/preset-classic` preset has no explicit `id` and 
therefore uses the default id (`default`), so the OpenAPI plugin will not find 
the expected docs instance and `docusaurus gen-api-docs superset`/builds can 
fail with "docs plugin not found" errors.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



##########
docs/scripts/generate-api-index.mjs:
##########
@@ -0,0 +1,240 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Generates a comprehensive API index MDX file from the OpenAPI spec.
+ * This creates the api.mdx landing page with all endpoints organized by 
category.
+ */
+
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+const SPEC_PATH = path.join(__dirname, '..', 'static', 'resources', 
'openapi.json');
+const OUTPUT_PATH = path.join(__dirname, '..', 'docs', 'api.mdx');
+
+// Category groupings for better organization
+const CATEGORY_GROUPS = {
+  'Authentication': ['Security'],
+  'Core Resources': ['Dashboards', 'Charts', 'Datasets', 'Database'],
+  'Data Exploration': ['Explore', 'SQL Lab', 'Queries', 'Datasources', 
'Advanced Data Type'],
+  'Organization & Customization': ['Tags', 'Annotation Layers', 'CSS 
Templates'],
+  'Sharing & Embedding': [
+    'Dashboard Permanent Link', 'Explore Permanent Link', 'SQL Lab Permanent 
Link',
+    'Embedded Dashboard', 'Dashboard Filter State', 'Explore Form Data'
+  ],
+  'Scheduling & Alerts': ['Report Schedules'],
+  'Security & Access Control': [
+    'Security Roles', 'Security Users', 'Security Permissions',
+    'Security Resources (View Menus)', 'Security Permissions on Resources 
(View Menus)',
+    'Row Level Security'
+  ],
+  'Import/Export & Administration': ['Import/export', 'CacheRestApi', 
'LogRestApi'],
+  'User & System': ['Current User', 'User', 'Menu', 'Available Domains', 
'AsyncEventsRestApi', 'OpenApi'],
+};
+
+function slugify(text) {
+  return text
+    .toLowerCase()
+    .replace(/[^a-z0-9]+/g, '-')
+    .replace(/(^-|-$)/g, '');
+}
+
+function generateEndpointLink(summary) {
+  // Convert summary to the slug format used by docusaurus-openapi-docs
+  return slugify(summary);
+}
+
+function main() {
+  console.log(`Reading OpenAPI spec from ${SPEC_PATH}`);
+  const spec = JSON.parse(fs.readFileSync(SPEC_PATH, 'utf-8'));
+
+  // Build a map of tag -> endpoints
+  const tagEndpoints = {};
+  const tagDescriptions = {};
+
+  // Get tag descriptions
+  for (const tag of spec.tags || []) {
+    tagDescriptions[tag.name] = tag.description || '';
+  }
+
+  // Collect endpoints by tag
+  for (const [pathUrl, methods] of Object.entries(spec.paths || {})) {
+    for (const [method, details] of Object.entries(methods)) {
+      if (!['get', 'post', 'put', 'delete', 'patch'].includes(method)) 
continue;
+
+      const tags = details.tags || ['Untagged'];
+      const summary = details.summary || `${method.toUpperCase()} ${pathUrl}`;
+
+      for (const tag of tags) {
+        if (!tagEndpoints[tag]) {
+          tagEndpoints[tag] = [];
+        }
+        tagEndpoints[tag].push({
+          method: method.toUpperCase(),
+          path: pathUrl,
+          summary,
+          slug: generateEndpointLink(summary),
+        });
+      }
+    }
+  }
+
+  // Sort endpoints within each tag by path
+  for (const tag of Object.keys(tagEndpoints)) {
+    tagEndpoints[tag].sort((a, b) => a.path.localeCompare(b.path));
+  }
+
+  // Generate MDX content
+  let mdx = `---
+title: API Reference
+hide_title: true
+sidebar_position: 10
+---
+
+import { Alert } from 'antd';
+
+## REST API Reference
+
+Superset exposes a comprehensive **REST API** that follows the [OpenAPI 
specification](https://swagger.io/specification/).
+You can use this API to programmatically interact with Superset for 
automation, integrations, and custom applications.
+
+<Alert
+  type="info"
+  showIcon
+  message="Code Samples & Schema Documentation"
+  description={
+    <span>
+      Each endpoint includes ready-to-use code samples in 
<strong>cURL</strong>, <strong>Python</strong>, and <strong>JavaScript</strong>.
+      Browse the <a href="./api/schemas">Schema definitions</a> for detailed 
data model documentation.
+    </span>
+  }
+  style={{ marginBottom: '24px' }}
+/>
+
+---
+
+`;
+
+  // Track which tags we've rendered
+  const renderedTags = new Set();
+
+  // Render Authentication first (it's critical for using the API)
+  mdx += `### Authentication
+
+Most API endpoints require authentication via JWT tokens.
+
+#### Quick Start
+
+\`\`\`bash
+# 1. Get a JWT token
+curl -X POST http://localhost:8088/api/v1/security/login \\
+  -H "Content-Type: application/json" \\
+  -d '{"username": "admin", "password": "admin", "provider": "db"}'
+
+# 2. Use the access_token from the response
+curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \\
+  http://localhost:8088/api/v1/dashboard/
+\`\`\`
+
+#### Security Endpoints
+
+`;
+
+  // Render Security tag endpoints
+  if (tagEndpoints['Security']) {
+    mdx += `| Method | Endpoint | Description |\n`;
+    mdx += `|--------|----------|-------------|\n`;
+    for (const ep of tagEndpoints['Security']) {
+      mdx += `| \`${ep.method}\` | [${ep.summary}](./api/${ep.slug}) | 
\`${ep.path}\` |\n`;

Review Comment:
   **Suggestion:** In the "Security Endpoints" table, each endpoint link uses 
`./api/${ep.slug}` from the `/docs/api` page, which resolves to 
`/docs/api/api/<slug>` instead of `/docs/api/<slug>`, so all Security endpoint 
links will be broken. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ Security endpoint links 404 on /docs/api.
   - ⚠️ Readers cannot access Security API docs easily.
   - ⚠️ Navigation inconsistency in generated API index.
   ```
   </details>
   
   ```suggestion
         mdx += `| \`${ep.method}\` | [${ep.summary}](./${ep.slug}) | 
\`${ep.path}\` |\n`;
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Run the generator: node docs/scripts/generate-api-index.mjs (entry at
   docs/scripts/generate-api-index.mjs:238-240). The generator builds the 
Security endpoints
   table using the loop at docs/scripts/generate-api-index.mjs:167-169.
   
   2. Start the docs site (yarn start) and open /docs/api/ in the browser (the 
generated MDX
   includes the table rendered from the code above).
   
   3. Click any Security endpoint link in the "Security Endpoints" table. The 
rendered anchor
   href is "./api/<slug>" (produced at 
docs/scripts/generate-api-index.mjs:169), which
   resolves from /docs/api/ to /docs/api/api/<slug>, producing a 404 because 
the actual
   endpoint pages are served at /docs/api/<slug>.
   
   4. Confirm the incorrect path is produced by the exact template string in 
the file at
   lines 167-169; updating the template to "./${ep.slug}" removes the 
duplicated "api"
   segment and fixes links.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** docs/scripts/generate-api-index.mjs
   **Line:** 168:168
   **Comment:**
        *Logic Error: In the "Security Endpoints" table, each endpoint link 
uses `./api/${ep.slug}` from the `/docs/api` page, which resolves to 
`/docs/api/api/<slug>` instead of `/docs/api/<slug>`, so all Security endpoint 
links will be broken.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



##########
docs/scripts/generate-api-index.mjs:
##########
@@ -0,0 +1,240 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Generates a comprehensive API index MDX file from the OpenAPI spec.
+ * This creates the api.mdx landing page with all endpoints organized by 
category.
+ */
+
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+const SPEC_PATH = path.join(__dirname, '..', 'static', 'resources', 
'openapi.json');
+const OUTPUT_PATH = path.join(__dirname, '..', 'docs', 'api.mdx');
+
+// Category groupings for better organization
+const CATEGORY_GROUPS = {
+  'Authentication': ['Security'],
+  'Core Resources': ['Dashboards', 'Charts', 'Datasets', 'Database'],
+  'Data Exploration': ['Explore', 'SQL Lab', 'Queries', 'Datasources', 
'Advanced Data Type'],
+  'Organization & Customization': ['Tags', 'Annotation Layers', 'CSS 
Templates'],
+  'Sharing & Embedding': [
+    'Dashboard Permanent Link', 'Explore Permanent Link', 'SQL Lab Permanent 
Link',
+    'Embedded Dashboard', 'Dashboard Filter State', 'Explore Form Data'
+  ],
+  'Scheduling & Alerts': ['Report Schedules'],
+  'Security & Access Control': [
+    'Security Roles', 'Security Users', 'Security Permissions',
+    'Security Resources (View Menus)', 'Security Permissions on Resources 
(View Menus)',
+    'Row Level Security'
+  ],
+  'Import/Export & Administration': ['Import/export', 'CacheRestApi', 
'LogRestApi'],
+  'User & System': ['Current User', 'User', 'Menu', 'Available Domains', 
'AsyncEventsRestApi', 'OpenApi'],
+};
+
+function slugify(text) {
+  return text
+    .toLowerCase()
+    .replace(/[^a-z0-9]+/g, '-')
+    .replace(/(^-|-$)/g, '');
+}
+
+function generateEndpointLink(summary) {
+  // Convert summary to the slug format used by docusaurus-openapi-docs
+  return slugify(summary);
+}
+
+function main() {
+  console.log(`Reading OpenAPI spec from ${SPEC_PATH}`);
+  const spec = JSON.parse(fs.readFileSync(SPEC_PATH, 'utf-8'));
+
+  // Build a map of tag -> endpoints
+  const tagEndpoints = {};
+  const tagDescriptions = {};
+
+  // Get tag descriptions
+  for (const tag of spec.tags || []) {
+    tagDescriptions[tag.name] = tag.description || '';
+  }
+
+  // Collect endpoints by tag
+  for (const [pathUrl, methods] of Object.entries(spec.paths || {})) {
+    for (const [method, details] of Object.entries(methods)) {
+      if (!['get', 'post', 'put', 'delete', 'patch'].includes(method)) 
continue;
+
+      const tags = details.tags || ['Untagged'];
+      const summary = details.summary || `${method.toUpperCase()} ${pathUrl}`;
+
+      for (const tag of tags) {
+        if (!tagEndpoints[tag]) {
+          tagEndpoints[tag] = [];
+        }
+        tagEndpoints[tag].push({
+          method: method.toUpperCase(),
+          path: pathUrl,
+          summary,
+          slug: generateEndpointLink(summary),
+        });
+      }
+    }
+  }
+
+  // Sort endpoints within each tag by path
+  for (const tag of Object.keys(tagEndpoints)) {
+    tagEndpoints[tag].sort((a, b) => a.path.localeCompare(b.path));
+  }
+
+  // Generate MDX content
+  let mdx = `---
+title: API Reference
+hide_title: true
+sidebar_position: 10
+---
+
+import { Alert } from 'antd';
+
+## REST API Reference
+
+Superset exposes a comprehensive **REST API** that follows the [OpenAPI 
specification](https://swagger.io/specification/).
+You can use this API to programmatically interact with Superset for 
automation, integrations, and custom applications.
+
+<Alert
+  type="info"
+  showIcon
+  message="Code Samples & Schema Documentation"
+  description={
+    <span>
+      Each endpoint includes ready-to-use code samples in 
<strong>cURL</strong>, <strong>Python</strong>, and <strong>JavaScript</strong>.
+      Browse the <a href="./api/schemas">Schema definitions</a> for detailed 
data model documentation.

Review Comment:
   **Suggestion:** The schema documentation link inside the `<Alert>` component 
uses `./api/schemas` as a relative URL, which from the `/docs/api` page 
resolves to `/docs/api/api/schemas` instead of the intended 
`/docs/api/schemas`, causing the "Schema definitions" link to be broken. [logic 
error]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ Schema definitions link broken on /docs/api landing page.
   - ⚠️ Users cannot navigate to schema docs from API index.
   - ⚠️ Developer docs quality degraded for API consumers.
   ```
   </details>
   
   ```suggestion
         Browse the <a href="./schemas">Schema definitions</a> for detailed 
data model documentation.
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Run the generator and build docs: node 
docs/scripts/generate-api-index.mjs will write
   docs/docs/api.mdx (script file: docs/scripts/generate-api-index.mjs: lines 
67-75, 234-236
   show entry and write). The file contains the Alert block at
   docs/scripts/generate-api-index.mjs:114-132 which produces the hyperlink <a
   href="./api/schemas">.
   
   2. Start Docusaurus dev server from the docs/ directory (yarn start). Open 
the generated
   API landing page served at path /docs/api/ (this is the page that 
corresponds to the
   generated api.mdx).
   
   3. From browser on URL /docs/api/ the anchor with href="./api/schemas" 
resolves to
   /docs/api/api/schemas (relative resolution: current path + ./api/schemas) 
instead of the
   intended /docs/api/schemas. Confirm the resulting URL returns 404 or does 
not load the
   schemas page.
   
   4. Observe broken link behavior tied directly to the literal href produced 
by the code in
   docs/scripts/generate-api-index.mjs at lines 114-132. Changing the href to 
"./schemas"
   (improved code) generates a link that resolves to /docs/api/schemas as 
intended.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** docs/scripts/generate-api-index.mjs
   **Line:** 121:128
   **Comment:**
        *Logic Error: The schema documentation link inside the `<Alert>` 
component uses `./api/schemas` as a relative URL, which from the `/docs/api` 
page resolves to `/docs/api/api/schemas` instead of the intended 
`/docs/api/schemas`, causing the "Schema definitions" link to be broken.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to