A web-based tool built with Next.js 15, React 19, and Tailwind CSS 4 for validating and visualizing OpenAPI schemas (YAML/JSON).
It supports file uploads, URL-based loading (including Internal Gitea-hosted specs), and provides detailed diagnostics and reports.
- Node.js 20+
- npm, yarn, or pnpm
npm install
# or
yarn install
# or
pnpm installRun the development server (using Turbopack):
npm run devThen open your browser at
http://localhost:3000
The app will automatically reload as you edit files.
Main entry point:
app/page.tsx
npm run buildnpm startThe app will be served at http://localhost:3000
docker build -t otc-openapi-schema-validator .docker run -p 3000:3000 otc-openapi-schema-validatorThe app will be available at
http://localhost:3000
| Command | Description | 
|---|---|
| npm run dev | Start development server with Turbopack | 
| npm run build | Build Next.js app for production | 
| npm start | Run the production server | 
| npm run lint | Lint code using ESLint | 
- Next.js 15 (App Router)
- React 19
- TypeScript 5
- Tailwind CSS 4
- @telekom/scale-components
- CodeMirror (YAML/JSON editors)
- Axios (API requests)
- js-yaml, yaml
- jspdf, jspdf-autotable, jszip (report generation)
- react-markdown, marked (documentation rendering)
Base URL (local): http://localhost:3000
All endpoints accept/return JSON unless noted. Body size limit: 10 MB.
Validate an OpenAPI spec (YAML/JSON) from raw content or a path/URL.
Body
{
  "path": "string (url or server path)",
  "file_content": "string (raw YAML/JSON)",
  "manual_rules": ["RULE_ID", "…"],
  "auto_rules": ["RULE_ID", "…"],
  "ruleset": "string (default: \"default\")",
  "export": "xml | pdf",
  "out": "string (required only when export=pdf)"
}Behavior
- If file_contentis provided, it takes precedence.
- If pathis an HTTP/HTTPS URL. For Gitea URL, expected next shape:/:owner/:repo/src/:branch/path/to/file.yaml.
- If pathis a server path, the file is read from disk (if accessible to the server).
- rulesetdirectory is read from- public/rulesets/<ruleset>; only auto‑rules with- status: implementedare used.
- export: "xml"builds Robot XML and imports a launch to ReportPortal (defaults used in server: project- openapi, dynamic launch name/description). Response includes the created launch payload.
- export: "pdf"currently returns 501 (use the UI export instead).
Success Response (default validation)
{
  "diagnostics": [
    { "id": "RULE_ID", "message": "…", "lineNumber": 42, "severity": "High", "from": 123, "to": 140 }
  ],
  "rules": {
    "manual": [ { "id": "…" } ],
    "auto": [ { "id": "…" } ],
    "manual_total": 0,
    "auto_total": 0,
    "manual_selected": 0,
    "auto_selected": 0
  }
}Examples
Validate with raw content:
curl -X POST http://localhost:3000/api/validate \
  -H 'Content-Type: application/json' \
  -d '{
    "file_content": "openapi: 3.0.3\ninfo:\n  title: Demo\n  version: 1.0.0\npaths: {}",
    "ruleset": "default"
  }'Validate from internal Gitea URL:
curl -X POST http://localhost:3000/api/validate \
  -H 'Content-Type: application/json' \
  -d '{
    "path": "https://gitea.my-service.com/owner/repo/src/main/specs/openapi.yaml",
    "auto_rules": ["RULE_1", "RULE_2"]
  }'Export Robot XML directly to ReportPortal:
curl -X POST http://localhost:3000/api/validate \
  -H 'Content-Type: application/json' \
  -d '{
    "file_content": "<your YAML here>",
    "export": "xml"
  }'Fetch launch details by ID.
Query params
- project— ReportPortal project name
- launchId— the launch ID
Example
curl "http://localhost:3000/api/reportportal?project=openapi&launchId=12345"Fetch all index clusters for a launch.
Query params
- project— ReportPortal project name
- launchId— the launch ID
Example
curl "http://localhost:3000/api/reportportal/clusters?project=openapi&launchId=12345"The app is optimized for deployment as a standalone Next.js server.
The Dockerfile includes:
- Multi-stage build for smaller images
- Standalone Next.js output
- Production-ready configuration
Default port: 3000