Skip to content

feat: RSS-CORE-00 swagger editor app release - #46

Open
FierceSloth wants to merge 66 commits into
mainfrom
develop
Open

FierceSloth wants to merge 66 commits into
mainfrom
develop

Conversation

@FierceSloth

@FierceSloth FierceSloth commented Jul 13, 2026 •

Copy link
Copy Markdown
Owner

Important

🔑 Required Environment Variables for Local Running

To run the application locally (enabling authorization, history logging, and CORS proxying), you must configure the Supabase keys. Without them, the local server will throw a Missing environment variable error.

  1. Create a .env (or .env.local) file in the root directory of the project.
  2. Add the following lines to it:
NEXT_PUBLIC_SUPABASE_URL=https://tjauezlydekhtstcmymw.supabase.co/
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_Y8crjslJ7ozxW3X6z-DJQw_sFsROSKo
  1. Once configured, you can start the development server:
npm run dev

📋 Trello Task ID

  • RSS-SE-## (Task ID / Trello Card)
  • No ID (Final release: develop → main)

⚡️ Summary

Merge the develop branch into main for the final release of the Swagger/OpenAPI UI application. This PR encompasses the complete implementation of the REST client and API specification editor according to the project requirements.


  1. Task: Swagger/OpenAPI UI Task
  2. Deployment: https://swagger-editor-app-gmt.vercel.app/en/home
  3. Demo Video: https://youtu.be/MxXD0E_D5gs
  4. Done: 13.07.2026 / Deadline: 13.07.2026
  5. Score: 550 / 550

🏆 Evaluation Criteria (550 max)

  • Feature 1: App Header (60/60)

    • Non-authenticated users see Sign In and Sign Up buttons in the header's upper right corner. (15)
    • Authenticated users see History and Sign Out buttons in the header's upper right corner. (10)
    • Navigation link to About page is available in header and footer. (10)
    • If the token is expired/invalid, the user is redirected from private routes to the Main page. (10)
    • Pressing the Sign In / Sign Up button redirects to the route with the respective form. (15)
  • Feature 2: Sign In / Sign Up (50/50)

    • Buttons for Sign In / Sign Up / Sign Out are present everywhere they should be. (10)
    • Client-side validation is implemented (email format, password strength: min 8 chars, at least one letter, one digit, one special character, Unicode supported). (20)
    • Upon successful login, the user is redirected to the Main page. (10)
    • If the user is already logged in and tries to reach Sign In / Sign Up routes, they are redirected to the Main page. (10)
  • Feature 3: Swagger Editor (120/120)

    • Loading/pasting OpenAPI/Swagger schema in JSON and YAML formats is supported. (25)
    • Auto-detection of input format (JSON vs YAML) is implemented. (20)
    • Format switching with automatic conversion (JSON ↔ YAML) works correctly. (20)
    • Schema validation with error indication is implemented. (15)
    • Authenticated users can save schemas; the saved schema is automatically restored in the editor upon next login. (10)
    • The Viewer automatically populates with endpoints when the schema is valid. (10)
    • Responsive split view adjusts based on screen orientation (horizontal/vertical). (20)
  • Feature 4: Swagger Viewer (120/120)

    • Endpoint list is displayed with organization by path/method. (20)
    • Endpoint details show method, path, and all parameter types (path, query, header, cookie). (25)
    • Request schema and example payloads are displayed. (20)
    • Response schema, examples, and all supported status codes are displayed. (25)
    • Try-It-Out functionality allows filling parameters, headers, and body; executing requests; and displaying responses. (20)
    • Generate cURL button with copy-to-clipboard functionality is implemented. (10)
  • Feature 5: History and Analytics (70/70)

    • History and analytics is server-side generated and shows an informational message with links to the editor/viewer when there are no requests in the database. (15)
    • Requests are displayed sorted by timestamp (most recent first). (10)
    • The following analytics are recorded from the server side and displayed: request duration, response status code, request timestamp, request method, request size, response size, error details, endpoint/URL. (45)
  • Feature 6: About Page (25/25)

    • About page is accessible to all users (public route). (5)
    • About page contains information about the RS School course. (5)
    • About page contains team member information (names, roles, GitHub links). (10)
    • About page design is consistent with the application design. (5)
  • Feature 7: General Requirements (55/55)

    • Multiple (at least 2) languages are supported with an i18n toggler in the header. (30)
    • Sticky header with animation when it becomes sticky is implemented. (10)
    • Errors are displayed in a user-friendly format. (10)
    • Private routes are properly protected (401 if not authenticated). (5)
  • Feature 8: YouTube Video (50/50)

    • A 5–7 minute YouTube video is linked in the pull request demonstrating all implemented features. (50)

⛔ Penalties (0 points applied)

  • No forbidden frameworks used.
  • No @ts-ignore or code-smells present.
  • Test coverage meets the required thresholds.
  • Lazy-loaded routes are implemented correctly.
  • No unexpected console errors/warnings/logs.
  • ESLint, Prettier, and Husky git hooks are properly configured.
  • Custom favicon is set.
  • Commit history and PR guidelines followed correctly.

Summary by CodeRabbit

  • Новые возможности

    • Добавлены локализованные страницы Home, About, входа, регистрации и истории запросов.
    • Реализован редактор OpenAPI/Swagger с подсветкой, конвертацией JSON/YAML и валидацией схем.
    • Добавлен просмотр эндпоинтов с параметрами, примерами запросов и ответов.
    • Доступна функция Try it out с выполнением запросов и генерацией cURL.
    • Добавлены аутентификация, автосохранение схем и переключение языков EN/RU.
    • Реализована история запросов с отображением статусов, длительности и ошибок.
  • Документация

    • Обновлены инструкции по установке, настройке окружения и участию в разработке.
  • Тесты

    • Расширено покрытие компонентов, авторизации, прокси, валидации и конвертации форматов.

FierceSloth and others added 30 commits June 25, 2026 16:31
- Setup App Router structure with locale-based routing
- Integrate next-intl for i18n support
- Add localized routes for Home, About, Login, Register, and History pages
- Configure i18n routing, navigation, middleware, and request config
- Add translation messages for English and Russian
- Add redirect from root pages to localized Home page
- Configured global SCSS architecture (variables, mixins, fonts).
- Installed radix-ui dependency.
- Implemented reusable UI components (Button, StatusBadge, Input, ArcBackground, GlassCard).
- Added unit tests for UI components.
- Setup global SCSS architecture (variables, mixins, fonts)
- Implement reusable UI components (Button, StatusBadge, Input, ArcBackground)
- Setup basic routing with next-intl (en/ru)
- Configure vitest coverage
- Add AuthForm feature component with login/register variants
- Implement SignIn and SignUp pages
- Add localization (ru/en) for auth forms
- Add strict Zod validation schemas for login and registration
- Integrate react-hook-form with zodResolver into AuthForm
- Configure dynamic mode validation on field change
- Add validation error translations for en and ru locales
- Added @uiw/react-codemirror with JSON/YAML support
- Created reusable CodeEditor in shared/ui with readonly and transparent props
- Applied custom dark theme and syntax highlighting via SCSS and JS
- Integrated CodeEditor into SwaggerEditor widget
- add auth-provider, get-current-user
- add AuthProvider to layout
- add checks in middleware
- Create format-converter feature to detect and convert between JSON and YAML
- Implement FormatToggle UI component with unknown state handling
- Integrate format converter logic and toggle into SwaggerEditor widget
- Add i18n support for the format converter UI
- Integrate `@stoplight/spectral-core` to parse and validate OpenAPI schemas in both JSON and YAML formats.
- Add `CodeMirror Linter` adapter to display validation errors directly in the editor with inline tooltips.
- Customize the Spectral `oas` ruleset to ignore annoying stylistic rules and focus only on structural errors.
- Add comprehensive unit tests for the schema validation utility.
- Implemented `ValidationStatus` and `ValidationFeedback` UI components to visualize schema validity and error counts.
- Added `next-intl` localization support for all new validation UI elements.
- Integrated CodeMirror's `onUpdate` listener to efficiently extract real-time lint diagnostics without causing redundant validation runs.
- Created a responsive split-view layout for the `HomePage` using Flexbox and aspect-ratio media queries.
- Assembled the main page by integrating the `SwaggerEditor` into the primary pane and adding a placeholder stub for the `SwaggerViewer`.
- Refactor SwaggerEditor to operate as a fully controlled component by removing its internal local state.
- Implement a custom useDebounce hook to optimize performance during user input.
- Lift state management up to the HomePage to track raw text and validation status.
- Create header and footer.
- Add conditional rendering for auth buttons: Sign In / Sign Up vs History / Sign Out.
- Add links to the About page.
- Integrate the language switcher (i18n) into the Header.
- implement next.js route handler for proxying requests
- add client utility to perform requests via proxy
- add tests for proxy client utility
- Replace 'unknown' magic string with null in DetectedFormat type
- Extract parseToObject helper to shared/lib to eliminate duplicated yaml parsing
- Replace nested ternary with getStatus function in ValidationFeedback
- Split validation object state into separate errorsCount/warningsCount states
- Derive currentFormat via useMemo with debounce instead of useState + useEffect
- Sync package-lock.json
* Integrate code editor for OpenAPI/Swagger specifications
* Implement auto-detection for JSON and YAML formats
* Add seamless JSON ↔ YAML format conversion
* Add real-time OpenAPI schema validation with UI feedback
* Create responsive split view (horizontal/vertical) for Editor and Viewer
* Synchronize parsed schema state between Editor and Viewer
- add translations for errors
- add submit form and database errors
- add styles and edits to app router
- delete try catch
* chore: change name of env

* refactor: add edits

* chore: change package-lock.json

* chore: change package-lock

* chore: change package-lock

* fix: fix package-lock

---------

Co-authored-by: dilmun1101 <dilmun94@gmail.com>
- add auth
- add connection to supabase
dilmun1101 and others added 16 commits July 13, 2026 21:18
- implemented and styled the About page
- A request history page has been added that displays the HTTP method, status, URL, duration, and payload sizes for each request.
- For failed requests, detailed error information is shown when available.
- The history is sorted from newest to oldest.
- When there are no records, an informative empty-state message is displayed.
- Added a request history and analytics page.
- History entries display URL, method, status, duration, timestamp, and payload sizes.
- Request errors are shown directly in the history cards.
- For an empty history, an explanatory message and a shortcut back to the editor are provided.
- Requests are now automatically saved to history together with their execution parameters.
- Added a request history page with data about status, duration, execution time, and request/response sizes.
- Implemented logging of both successful and failed proxy requests into the history.
- Non-authorized users are redirected to the main page.
- Updated Russian and English texts for the history page and its UI elements.
- Added empty history states and a shortcut to navigate back to the editor.
- Implemented Supabase-backed authenticated request history and analytics for Try-It-Out requests.
- Added detailed per-request metrics (method, status, URL, duration, timestamp, payload sizes).
- Logged successful and failed proxy requests with inline error details in history.
- Protected SSR history route with redirect for unauthorized users to the main page.
- Added informative empty states with localized texts and shortcuts back to the editor.
- Creating Toast and Spinner components (shared UI)
- Configuring ToastProvider with the useToast() hook
- Error Boundary (error.tsx) with toast notifications
- Adding loading.tsx with the Spinner to all pages
- Add favicon
- Write unit and integration tests for authentication flow and form validation
- Implement tests for application header and navigation components
- Cover Swagger Editor and schema parsing logic with tests
- Add comprehensive tests for Swagger Viewer and endpoint rendering
- Cover proxy server functionality and SSR History page with tests
- Achieve total code coverage exceeding 95% across the application
@vercel

vercel Bot commented Jul 13, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
swagger-editor-app Ready Ready Preview Sep 6, 2026 1:29pm UTC

@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown

Review Change Stack

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Team

Run ID: dfd436dd-5fae-4d0a-8588-cbf70c983dc8

📝 Walkthrough

Walkthrough

PR добавляет полноценное Next.js-приложение: инфраструктуру и CI, Supabase-аутентификацию, прокси API с историей, OpenAPI-редактор и просмотрщик, общие UI-компоненты, i18n, а также страницы home, about, history, login и register.

Changes

Основные функциональные потоки

Layer / File(s) Summary
Конфигурация и runtime
.commitlintrc.json, .github/*, eslint.config.mjs, package.json, tsconfig.json, vitest.*, next.config.mjs, src/app/styles/*, messages/*
Настроены CI, commit/pre-commit hooks, ESLint, Prettier, Vitest, Next.js, i18n, environment-пример и глобальные стили.
Аутентификация и маршрутизация
src/shared/api/supabase/*, src/features/auth/*, src/features/auth-form/*, proxy.ts, app/[locale]/{layout,login,register}/*
Добавлены Supabase clients, auth actions, AuthProvider, middleware redirects, формы входа/регистрации и локализованный layout.
OpenAPI workflow и proxy API
app/api/proxy/*, src/entities/endpoint/*, src/features/{format-converter,schema-validator,schema-persistence}/*, src/widgets/swagger-*/*, src/pages/home-page/*
Добавлены парсинг/конвертация/валидация OpenAPI, группировка endpoint’ов, TryItOut, прокси-запросы, история и автосохранение схемы.
Страницы и UI
src/shared/ui/*, src/pages/{about-page,history-page,login,register}/*, src/widgets/{header,footer}/*, app/[locale]/{about,history,error,loading,not-found}/*
Добавлены UI-примитивы, навигация, страницы About и History, error boundary, loading и not-found состояния.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested reviewers: dilmun1101, lexarudak

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Заголовок точно описывает основной результат PR: выпуск Swagger Editor приложения.
Description check ✅ Passed Описание содержит Trello ID, подробный Summary, ссылки на деплой и демо, а также полный перечень реализованных функций.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (27)
src/entities/endpoint/ui/try-it-out-form/try-it-out-form.module.scss-48-74 (1)

48-74: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Одинаковое нарушение Stylelint declaration-empty-line-before в двух SCSS-файлах. Причина одна — пустые строки используются для визуального разделения групп CSS-объявлений, что конфликтует с текущей конфигурацией Stylelint.

  • src/entities/endpoint/ui/try-it-out-form/try-it-out-form.module.scss#L48-L74: убрать пустые строки перед padding (после строки 52), font-size (после строки 55), outline (после строки 59) и color (после строки 63) в блоке .textArea.
  • app/app.module.scss#L9-L11: убрать пустую строку перед padding: 0 3rem; (после flex: 1;) в блоке .container.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/entities/endpoint/ui/try-it-out-form/try-it-out-form.module.scss` around
lines 48 - 74, Remove the declaration-separating empty lines that violate
Stylelint: in .textArea, delete the blank lines before padding, font-size,
outline, and color. Also remove the blank line before padding in .container
within app/app.module.scss; make no other styling changes.

Source: Linters/SAST tools

src/features/schema-validator/ui/validation-feedback/validation-feedback.module.scss-1-9 (1)

1-9: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Убрать пустую строку перед объявлением (stylelint).

Stylelint фиксирует лишнюю пустую строку перед display: flex внутри одного блока объявлений.

Исправление
 .wrapper {
   padding: 0.75rem 1.5rem;
   background-color: var(--bg-surface-1);
   border-top: 1px solid var(--bg-surface-2);
-
   display: flex;
   align-items: center;
   gap: 0.75rem;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/features/schema-validator/ui/validation-feedback/validation-feedback.module.scss`
around lines 1 - 9, Remove the blank line within the .wrapper declaration block
so display: flex follows the preceding border-top declaration directly,
preserving all existing styles.

Source: Linters/SAST tools

src/features/auth-form/ui/auth-form.module.scss-6-6 (1)

6-6: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Исправьте ошибки Stylelint перед слиянием.

Удалите пустые строки перед декларациями display на строках 6, 45 и 59: правило declaration-empty-line-before сейчас нарушено.

Предлагаемое исправление
   gap: 24px;
-
   display: flex;
   padding-bottom: 0.875rem;
-
   display: flex;
   line-height: 1.25rem;
-
   display: flex;

Also applies to: 45-45, 59-59

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/auth-form/ui/auth-form.module.scss` at line 6, Remove the empty
lines immediately before the display declarations in the stylesheet, including
the declarations at the referenced positions, so they comply with Stylelint’s
declaration-empty-line-before rule.

Source: Linters/SAST tools

src/shared/ui/spinner/spinner.module.scss-22-35 (1)

22-35: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Добавьте поддержку prefers-reduced-motion.

Три бесконечные анимации будут продолжать работать для пользователей, запросивших уменьшение движения. Отключите их в media query:

Предлагаемое исправление
+@media (prefers-reduced-motion: reduce) {
+  .phaseRing.ringA,
+  .phaseRing.ringB,
+  .phaseRing.ringC,
+  .phaseCore {
+    animation: none;
+  }
+}

Also applies to: 63-83

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/spinner/spinner.module.scss` around lines 22 - 35, Добавьте
media query для prefers-reduced-motion: reduce в стилях, содержащих анимацию
.phaseRing и остальные три бесконечные анимации, и отключите их выполнение для
пользователей, запросивших уменьшение движения.
src/shared/api/supabase/get-current-user.ts-5-18 (1)

5-18: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Согласовать Supabase Auth API между кодом и тестом. getCurrentUser() вызывает supabase.auth.getUser(), а тесты мокают только getClaims(), поэтому они не проходят по текущему сценарию. Либо перевести тесты на getUser()/data: { user }, либо, если это действительно задумано, заменить реализацию на getClaims().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/api/supabase/get-current-user.ts` around lines 5 - 18, Согласуйте
API Supabase между реализацией и тестами: в
src/shared/api/supabase/get-current-user.ts (строки 5-18) сохраните выбранный
вызов auth.getUser() и структуру data.user либо замените его на
auth.getClaims(), если это требуемый контракт; в
src/shared/api/supabase/get-current-user.test.ts (строки 1-55) обновите моки и
ожидаемые данные под тот же API. Убедитесь, что getCurrentUser возвращает
пользователя при успешном ответе и null при ошибке или отсутствии пользователя.
src/shared/api/proxy-client.ts-4-6 (1)

4-6: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Кодируйте нормализованный URL.

Сейчас trim() используется только для проверки, а в targetUrl попадает исходная строка. Для URL с пробелами это может привести к ошибке разбора или изменению адреса назначения.

Предлагаемое исправление
 export function fetchViaProxy(url: string, options?: RequestInit): Promise<Response> {
-  if (!url.trim()) throw new Error('URL is required');
+  const normalizedUrl = url.trim();
+  if (!normalizedUrl) throw new Error('URL is required');

-  const proxyUrl = `/api/proxy?targetUrl=${encodeURIComponent(url)}`;
+  const proxyUrl = `/api/proxy?targetUrl=${encodeURIComponent(normalizedUrl)}`;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/api/proxy-client.ts` around lines 4 - 6, Normalize the input URL
once in the proxy-client flow by trimming it after validating it, then pass that
normalized value to encodeURIComponent when constructing proxyUrl. Ensure
targetUrl never uses the original untrimmed url while preserving the existing
required-URL error behavior.
src/features/auth/model/action.ts-14-28 (1)

14-28: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Не сопоставлять ошибки Supabase по тексту сообщения.
В mapAuthError ветка default использует message.toLowerCase().includes('already registered'); для Supabase нужно опираться на error.code/error.name, потому что error.message не является стабильным контрактом и может меняться.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/auth/model/action.ts` around lines 14 - 28, Update mapAuthError
to remove the message-based “already registered” fallback and rely only on
stable Supabase error identifiers such as code or name. Preserve the existing
mappings for invalid_credentials, user_already_exists, and
over_request_rate_limit, while returning unknownError when no recognized
identifier is present.
src/shared/ui/input/input.module.scss-4-4 (1)

4-4: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Исправить ошибки Stylelint declaration-empty-line-before.

Правило declaration-empty-line-before требует убрать пустые строки перед декларациями на этих строках — иначе линт-проверка в CI не пройдёт.

🎨 Предложенное исправление
 .input {
   width: 100%;
-
   background: var(--bg-surface-2);
   border: 2px solid var(--bg-surface-3);
   border-radius: 1rem;
-
   padding: 0.75rem 3.5rem 0.75rem 1.25rem;
   margin-top: 8px;
-
   font-size: 1rem;
   line-height: 1.5rem;
-
   outline: none;
   transition: all 0.3s;
-
   color: var(--text-primary);

и аналогично для строк 53-58 (.errorContainer).

Also applies to: 8-8, 11-11, 14-14, 17-17, 54-54, 58-58

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/input/input.module.scss` at line 4, Уберите пустые строки перед
декларациями в стилях input.module.scss, включая декларации в основном блоке и
секции .errorContainer. Примените это также к указанным повторяющимся местам,
чтобы все декларации соответствовали правилу Stylelint
declaration-empty-line-before.

Source: Linters/SAST tools

src/shared/lib/parse-to-object.ts-6-7 (1)

6-7: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Обе проверки принимают массивы за объектные документы.

  • src/shared/lib/parse-to-object.ts#L6-L7: добавьте !Array.isArray(parsed) перед возвратом Record<string, unknown>.
  • src/features/format-converter/lib/detect-format.ts#L8-L10: примените ту же проверку при распознавании JSON.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/lib/parse-to-object.ts` around lines 6 - 7, Массивы ошибочно
принимаются за объектные документы в обеих проверках. В
src/shared/lib/parse-to-object.ts:6-7 обновите условие вокруг parseToObject,
добавив исключение Array.isArray(parsed) перед возвратом Record<string,
unknown>; в src/features/format-converter/lib/detect-format.ts:8-10 примените
такую же проверку при распознавании JSON.
src/pages/home-page/ui/home-page.module.scss-44-45 (1)

44-45: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Удалите пустую строку перед opacity.

Stylelint сообщает о нарушении declaration-empty-line-before на Line 45.

Предлагаемое исправление
   justify-content: center;
-
   opacity: 0.5;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/home-page/ui/home-page.module.scss` around lines 44 - 45, Remove
the empty line immediately before the opacity declaration in the affected style
rule so the declaration-empty-line-before lint violation is resolved.

Source: Linters/SAST tools

src/widgets/swagger-editor/ui/swagger-editor.module.scss-9-20 (1)

9-20: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Дублирующиеся CSS-свойства в .toolbar.

display и align-items объявлены два раза (строки 10-11 и 16-17) — похоже на артефакт слияния. Второй блок также нарушает правило declaration-empty-line-before (пустая строка перед display на строке 16).

🧹 Предлагаемое исправление
 .toolbar {
   display: flex;
   align-items: center;
   padding: 0.75rem 1.5rem;
   background-color: var(--bg-surface-1);
   border-bottom: 1px solid var(--bg-surface-2);
-
-  display: flex;
-  align-items: center;
   justify-content: space-between;
   gap: 0.75rem;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/widgets/swagger-editor/ui/swagger-editor.module.scss` around lines 9 -
20, Remove the duplicate display and align-items declarations from .toolbar,
preserving each property once along with justify-content, gap, and the existing
styling; eliminate the unnecessary empty line before the remaining declarations.

Source: Linters/SAST tools

src/features/schema-validator/lib/codemirror-linter.ts-22-30 (1)

22-30: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Ограничь character по Line.to
from/to сейчас ограничиваются только номером строки, но character может вывести позицию за пределы строки и сломать применение диагностики.

🛡️ Предлагаемое исправление
     const startLine = doc.line(Math.min(startLinePos.line + 1, doc.lines));
     const endLine = doc.line(Math.min(endLinePos.line + 1, doc.lines));

-    const from = startLine.from + startLinePos.character;
-    const to = endLine.from + endLinePos.character;
+    const from = Math.min(startLine.from + startLinePos.character, startLine.to);
+    const to = Math.min(endLine.from + endLinePos.character, endLine.to);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/schema-validator/lib/codemirror-linter.ts` around lines 22 - 30,
Ограничьте значения character при вычислении from и to соответствующими
границами строк через Line.to, чтобы позиции диагностики никогда не выходили за
пределы строки. Обновите расчёты в текущем обработчике, сохранив существующее
ограничение номеров строк и поведение для корректных позиций.
src/pages/history-page/ui/history-requst-card/history-request-card.tsx-39-41 (1)

39-41: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Захардкоженные строки не локализованы.

Строки Req:, Res: и Error: вшиты напрямую, хотя в этом же PR RequestBody использует useTranslations из next-intl. Приложение заявляет поддержку en/ru — эти строки не переведутся на русский.

♻️ Пример исправления
+import { useTranslations } from 'next-intl';
...
+  const t = useTranslations('HistoryRequestCard');
...
-          <span className={styles.metaItem}>
-            Req: {formatSize(item.request_size)}
-            <span className={styles.separator}>|</span>
-            Res: {formatSize(item.response_size)}
-          </span>
+          <span className={styles.metaItem}>
+            {t('requestSize', { size: formatSize(item.request_size) })}
+            <span className={styles.separator}>|</span>
+            {t('responseSize', { size: formatSize(item.response_size) })}
+          </span>
...
-          <span className={styles.errorLabel}>Error:</span>
+          <span className={styles.errorLabel}>{t('error')}</span>

Also applies to: 49-49

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/history-page/ui/history-requst-card/history-request-card.tsx`
around lines 39 - 41, Localize the hardcoded “Req:”, “Res:”, and “Error:” labels
in the history request card. Reuse the existing next-intl useTranslations setup
from RequestBody or the surrounding component, add the corresponding en/ru
translation keys, and render translated labels in place of the literals.
src/pages/history-page/ui/empty-history-message/empty-history-message.tsx-19-23 (1)

19-23: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Локализуйте все пользовательские строки пустого состояния.

SCANNING_STREAM и SYSTEM.STUB // NO_RECORDS_FOUND остаются на английском, поэтому русская версия страницы будет частично отображать английский текст. Добавьте эти строки в messages/en.json и messages/ru.json, затем получайте их через namespace History.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/history-page/ui/empty-history-message/empty-history-message.tsx`
around lines 19 - 23, Локализуйте пользовательские строки SCANNING_STREAM и
SYSTEM.STUB // NO_RECORDS_FOUND из компонента empty-history-message: добавьте
соответствующие ключи в messages/en.json и messages/ru.json, затем получайте их
через namespace History вместо жестко заданного текста, сохранив текущую
разметку scanLabel и Badge.
src/entities/endpoint/lib/generate-example.ts-34-40 (1)

34-40: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Несогласованная обработка массивов без явного type: 'array'.

Для объектов есть fallback schema.type === 'object' || schema.properties (строка 24), а для массивов аналогичного fallback на schema.items нет. Схема с items, но без "type": "array", провалится в switch и вернёт null вместо примера массива.

🐛 Предлагаемый фикс
-  if (schema.type === 'array') {
+  if (schema.type === 'array' || schema.items) {
     if (!schema.items) {
       return [];
     }
 
     return [generateExample(schema.items)];
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/entities/endpoint/lib/generate-example.ts` around lines 34 - 40, Update
the array handling in generateExample to recognize schemas with items even when
schema.type is not explicitly 'array'. Reuse the existing schema.items
validation and return an array containing generateExample(schema.items), while
preserving the current empty-array behavior when items is absent.
src/pages/history-page/ui/empty-history-message/empty-history-message.module.scss-28-34 (1)

28-34: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Переименовать keyframe в kebab-case.

Линтер требует kebab-case для имён @keyframes. Нужно переименовать spinReverse → spin-reverse и обновить ссылку в .ringInner.

🎨 Предлагаемое исправление
 .ringInner {
   position: absolute;
   inset: 16px;
   border-radius: 50%;
   border: 1px dashed var(--bg-surface-4);
-  animation: spinReverse 12s linear infinite;
+  animation: spin-reverse 12s linear infinite;
 }
...
-@keyframes spinReverse {
+@keyframes spin-reverse {
   from {
     transform: rotate(360deg);
   }
   to {
     transform: rotate(0deg);
   }
 }

Also applies to: 64-71

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/pages/history-page/ui/empty-history-message/empty-history-message.module.scss`
around lines 28 - 34, Rename the spinReverse keyframe identifier to spin-reverse
and update the animation reference in .ringInner accordingly, including the
corresponding occurrence in the additional affected section.

Source: Linters/SAST tools

src/pages/about-page/ui/about-hero-section/about-hero-section.module.scss-83-87 (1)

83-87: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Исправить регистр ключевого слова CSS согласно правилу линтера.

Stylelint требует lowercase для значений-ключевых слов: currentColor → currentcolor.

🎨 Предлагаемое исправление
 .arrow {
   width: 10px;
   aspect-ratio: 1/1;
-  color: currentColor;
+  color: currentcolor;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/about-page/ui/about-hero-section/about-hero-section.module.scss`
around lines 83 - 87, Update the color keyword in the .arrow style rule from
currentColor to lowercase currentcolor to satisfy the Stylelint casing
requirement.

Source: Linters/SAST tools

src/features/schema-validator/ui/validation-status/validation-status.module.scss-7-7 (1)

7-7: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Уберите пустую строку перед декларацией.

Stylelint завершает проверку с ошибкой declaration-empty-line-before; удалите пустую строку между justify-content и gap.

Предлагаемое исправление
   justify-content: center;
- 
   gap: 0.3rem;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/features/schema-validator/ui/validation-status/validation-status.module.scss`
at line 7, Remove the empty line before the display declaration in the
validation-status styles, specifically between justify-content and gap, so
adjacent declarations satisfy the declaration-empty-line-before Stylelint rule.

Source: Linters/SAST tools

.github/workflows/checks.yml-1-1 (1)

1-1: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Исправьте окончания строк в YAML.

yamllint сообщает, что файл использует CRLF вместо ожидаемых LF; приведите .github/workflows/checks.yml к LF, иначе YAML-проверка остаётся красной.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/checks.yml at line 1, Convert the line endings in the
GitHub Actions workflow identified by the name “CI Check” from CRLF to LF
throughout the file, without changing its YAML content.

Source: Linters/SAST tools

src/app/styles/abstract/_constants.scss-18-19 (1)

18-19: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Исправьте fallback для моноширинного шрифта.

При недоступности --font-jetbrains-mono текущий fallback sans-serif будет отображать код пропорциональным шрифтом. Используйте monospace и задайте fallback внутри var(...).

Предлагаемое исправление
-  --font-mono: var(--font-jetbrains-mono), sans-serif;
+  --font-mono: var(--font-jetbrains-mono, monospace);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/styles/abstract/_constants.scss` around lines 18 - 19, Update the
--font-mono declaration to use monospace as the fallback when
--font-jetbrains-mono is unavailable, placing that fallback inside var(...).
Leave the --font-ui declaration unchanged.
src/shared/ui/button-link/button-link.module.scss-6-7 (1)

6-7: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Убрать пустые строки перед объявлениями (Stylelint: declaration-empty-line-before).

Строки 6-7 и 13-14 нарушают правило declaration-empty-line-before.

🛠️ Исправление пустых строк
 .button {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   gap: 12px;
-
   font-size: 0.875rem;
   line-height: 1.25rem;
   font-weight: 600;
   text-decoration: none;
   cursor: pointer;
   transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
-
   border-radius: var(--radius-card);
   padding: 8px 24px;
   border: none;
   background: transparent;
   margin: 0;
   box-sizing: border-box;

Also applies to: 13-14

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/button-link/button-link.module.scss` around lines 6 - 7, Remove
the empty lines immediately before the declarations around font-size and the
corresponding declarations at the second reported location in the button-link
styles, so the SCSS complies with Stylelint’s declaration-empty-line-before
rule.

Source: Linters/SAST tools

src/pages/about-page/ui/card/card.module.scss-35-39 (1)

35-39: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Аналогичная проблема с transition только на :hover.

.githubLink:hover .githubIcon задаёт transition: 1.5s; только для состояния наведения — обратный переход (color/transform) не будет анимирован при уходе курсора. Тот же паттерн, что и в .card выше.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/about-page/ui/card/card.module.scss` around lines 35 - 39, Move the
transition declaration from the `.githubLink:hover .githubIcon` rule to the base
`.githubIcon` rule, while keeping the hover color and transform changes
unchanged so both entering and leaving hover are animated.
src/pages/about-page/ui/card/card.module.scss-1-14 (1)

1-14: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

transition объявлен только в :hover, обратный переход не анимируется.

transition: 1s; и transform заданы только внутри .card:hover. При наведении переход плавный, но при снятии курсора свойства применяются мгновенно, так как у базового .card нет transition.

🎨 Предлагаемое исправление
 .card {
   display: flex;
   flex-direction: column;
   gap: 20px;
   border-radius: 25px;
   padding: 20px;
   border: 1px solid transparent;
+  transition: border-color 1s, transform 1s;

   &:hover {
     border: 1px solid rgba(255, 255, 255, 0.5);
-    transition: 1s;
     transform: translateY(-3px);
   }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/about-page/ui/card/card.module.scss` around lines 1 - 14, Move the
transition declaration from .card:hover to the base .card rule so both hover and
hover-exit transitions are animated; keep the existing hover border and
transform behavior unchanged.
src/entities/endpoint/ui/endpoint-list/endpoint-list.module.scss-13-14 (1)

13-14: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Уберите пустую строку перед text-transform.

Stylelint сообщает об ошибке declaration-empty-line-before на Line 14; в текущем виде проверка стилей может завершиться ошибкой. Это замечание основано на предоставленном отчёте Stylelint.

Предлагаемое исправление
   font-weight: 600;
-
   text-transform: uppercase;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/entities/endpoint/ui/endpoint-list/endpoint-list.module.scss` around
lines 13 - 14, Remove the empty line immediately before the text-transform
declaration in the affected style rule, preserving all other declarations and
formatting.

Source: Linters/SAST tools

src/app/styles/base/_base.scss-63-71 (1)

63-71: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Stylelint: пустая строка перед объявлением.

Statiс-анализ (declaration-empty-line-before) указывает на лишнюю пустую строку перед position: relative; внутри блока #root.

🎨 Предлагаемое исправление
 `#root` {
   width: 100%;
   min-height: 100dvh;
   display: flex;
   flex-direction: column;
-
   position: relative;
   z-index: var(--z-base);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/styles/base/_base.scss` around lines 63 - 71, Remove the extra empty
line before position in the `#root` style block, keeping the declaration sequence
and all existing values unchanged.

Source: Linters/SAST tools

src/shared/ui/accordion/accordion.module.scss-43-45 (1)

43-45: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Имена keyframes не в kebab-case (нарушение stylelint).

slideDown/slideUp нарушают правило keyframes-name-pattern, что может ломать линт-проверку в CI.

♻️ Предлагаемое исправление
   &[data-state='open'] {
-    animation: slideDown 0.3s cubic-bezier(0.87, 0, 0.13, 1);
+    animation: slide-down 0.3s cubic-bezier(0.87, 0, 0.13, 1);
   }
   &[data-state='closed'] {
-    animation: slideUp 0.3s cubic-bezier(0.87, 0, 0.13, 1);
+    animation: slide-up 0.3s cubic-bezier(0.87, 0, 0.13, 1);
   }
 }

-@keyframes slideDown {
+@keyframes slide-down {
   from {
     height: 0;
   }
   to {
     height: var(--radix-accordion-content-height);
   }
 }

-@keyframes slideUp {
+@keyframes slide-up {
   from {
     height: var(--radix-accordion-content-height);
   }
   to {
     height: 0;
   }
 }

Also applies to: 64-64, 67-67, 79-95

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/accordion/accordion.module.scss` around lines 43 - 45,
Переименуйте keyframes slideDown и slideUp в имена в kebab-case согласно правилу
keyframes-name-pattern и обновите все ссылки на них в стилях accordion, включая
отмеченные блоки 64, 67 и 79–95. Сохраните текущую анимацию и поведение
состояний open/closed.

Source: Linters/SAST tools

src/shared/ui/arc-background/arc-background.module.scss-21-29 (1)

21-29: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Пустые строки перед объявлениями внутри блоков (stylelint declaration-empty-line-before).

Во всех отмеченных местах (.arc, .arc::before, .arc::after) пустая строка стоит перед объявлением свойства, следующим за другим объявлением в том же блоке — линтер требует убрать такие пустые строки. Это может фейлить lint-проверку в CI.

♻️ Предлагаемое исправление (пример для `.arc`)
   top: 50%;
   left: 0;
-
   transform: translate(-70%, -50%);
   background: `#000`;
-
   opacity: 0.8;
-
   box-shadow: 0 0 150px 30px rgba(var(--fringe-rgb), 0.1);
-
   animation: breathe 8s ease-in-out infinite alternate;

Аналогично нужно убрать пустые строки перед border, filter, box-shadow в блоках .arc::before и .arc::after.

Also applies to: 38-41, 43-53, 61-62, 64-70

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/arc-background/arc-background.module.scss` around lines 21 -
29, Remove the empty lines between consecutive declarations in the .arc,
.arc::before, and .arc::after style blocks, including before the flagged
properties such as opacity, border, filter, and box-shadow, so they comply with
stylelint declaration-empty-line-before.

Source: Linters/SAST tools

🧹 Nitpick comments (22)
app/api/proxy/getProxyHeaders.ts (1)

3-3: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Стоит дополнить список hop-by-hop заголовками.

Список исключений корректно защищает от утечки cookie/authorization на внешний хост, но не включает hop-by-hop заголовки (connection, keep-alive, transfer-encoding, upgrade, proxy-authenticate, proxy-authorization), которые по спецификации не должны пересылаться прокси и иногда вызывают ошибки в fetch/undici при передаче третьей стороне.

♻️ Предлагаемое исправление
-const EXCLUDED_REQUEST_HEADERS = ['host', 'origin', 'referer', 'cookie', 'content-length', 'authorization'];
+const EXCLUDED_REQUEST_HEADERS = [
+  'host',
+  'origin',
+  'referer',
+  'cookie',
+  'content-length',
+  'authorization',
+  'connection',
+  'keep-alive',
+  'transfer-encoding',
+  'upgrade',
+  'proxy-authenticate',
+  'proxy-authorization',
+];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/api/proxy/getProxyHeaders.ts` at line 3, Расширьте константу
EXCLUDED_REQUEST_HEADERS, добавив все указанные hop-by-hop заголовки:
connection, keep-alive, transfer-encoding, upgrade, proxy-authenticate и
proxy-authorization, сохранив существующие исключения без изменений.
src/shared/ui/code-editor/ui/code-editor.tsx (1)

30-36: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Мемоизировать allExtensions.
@uiw/react-codemirror пересобирает конфигурацию при смене ссылки на extensions, поэтому новый массив на каждом рендере будет вызывать лишний reconfigure. useMemo здесь уместен.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/code-editor/ui/code-editor.tsx` around lines 30 - 36,
Мемоизируйте массив `allExtensions` через `useMemo`, используя `extensions`,
`format`, `editorTheme`, `syntaxTheme` и `readonly` как зависимости. Сохраните
текущий порядок объединения пользовательских и базовых расширений, чтобы ссылка
на массив не менялась без изменения этих значений.
src/entities/endpoint/ui/try-it-out-form/try-it-out-form.tsx (1)

233-236: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Формат тела ответа всегда указан как json, независимо от реального Content-Type.

CodeEditor рендерится с format="json" даже если ответ — HTML/XML/текст. Логичнее определять формат из result.headers['content-type'], чтобы избежать некорректной подсветки синтаксиса.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/entities/endpoint/ui/try-it-out-form/try-it-out-form.tsx` around lines
233 - 236, Update the CodeEditor usage in the response body section to derive
its format from result.headers['content-type'] instead of always passing "json".
Preserve the existing body rendering and ensure the selected format reflects the
response Content-Type, including non-JSON responses.
src/shared/ui/input/input.tsx (1)

21-36: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Добавить ARIA-атрибуты для ошибок валидации.

<input> не получает aria-invalid и aria-describedby, указывающий на errorMessage. Скринридер не узнает о наличии ошибки — только визуальные пользователи увидят иконку/текст.

♻️ Предлагаемое исправление
       <input className={clsx(styles.input, error && styles.inputError)} id={inputId} ref={ref} {...rest} />
+      <input
+        className={clsx(styles.input, error && styles.inputError)}
+        id={inputId}
+        ref={ref}
+        aria-invalid={!!error}
+        aria-describedby={error ? `${inputId}-error` : undefined}
+        {...rest}
+      />

       {(error || withErrorPlug) && (
         <div className={clsx(styles.errorContainer, withErrorPlug && styles.withPlug)}>
           {error && (
             <>
               <AlertIcon className={styles.errorIcon} />
-              <span className={styles.errorMessage}>{error}</span>
+              <span id={`${inputId}-error`} className={styles.errorMessage}>
+                {error}
+              </span>
             </>
           )}
         </div>
       )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/input/input.tsx` around lines 21 - 36, Добавьте в компоненте
Input доступные атрибуты для состояния ошибки: устанавливайте aria-invalid на
input при наличии error и aria-describedby со ссылкой на сообщение ошибки.
Присвойте span с классом styles.errorMessage стабильный идентификатор, связанный
с inputId, и используйте его только когда текст ошибки отображается. Сохраните
текущее поведение withErrorPlug и визуального отображения ошибки.
src/pages/history-page/ui/history-page.test.tsx (1)

14-20: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Мок Link не проверяет локализованный URL.

Мок на Lines 14–20 заменяет локализованный компонент обычным <a>, поэтому проверки /home на Lines 51–57 не обнаружат потерю /en или /ru. Добавьте в мок преобразование locale либо отдельно протестируйте реальный компонент навигации.

Also applies to: 51-57

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/history-page/ui/history-page.test.tsx` around lines 14 - 20,
Обновите мок Link в тесте history-page, чтобы он сохранял локаль при
формировании href, используя текущий locale из тестового контекста или ожидаемый
локализованный префикс. Убедитесь, что проверки ссылок в тесте подтверждают URL
с /en или /ru, чтобы потеря локали обнаруживалась.
src/features/auth/model/action.ts (1)

30-72: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Отсутствует серверная валидация входных данных перед вызовом Supabase.

signInWithPassword/signUp читают email/password напрямую из FormData без валидации формата/длины перед вызовом Supabase API. Поскольку server actions доступны как публичные эндпоинты, клиентская валидация (в auth-form) может быть обойдена прямым запросом. В проекте уже есть zod-схемы (src/features/auth-form/model/schemas.ts), которые можно повторно использовать здесь для defence-in-depth.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/auth/model/action.ts` around lines 30 - 72, Добавьте серверную
валидацию входных данных в signInWithPassword и signUp перед вызовом Supabase,
повторно используя zod-схемы из auth-form/model/schemas.ts. Обрабатывайте
невалидные или отсутствующие email/password через существующий AuthActionResult
и не вызывайте Supabase при ошибке валидации; сохраните текущую логику успешной
аутентификации и mapAuthError для ошибок Supabase.
app/[locale]/layout.tsx (1)

43-46: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

metadata не локализован.

Title/description захардкожены на английском, хотя приложение явно поддерживает en/ru-роутинг. Для полноценной локализации имеет смысл заменить статичный metadata на generateMetadata с getTranslations({locale}).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/`[locale]/layout.tsx around lines 43 - 46, Replace the static metadata
export with an async generateMetadata function that receives the route locale
and uses getTranslations({ locale }) to produce localized title and description
values. Preserve the Metadata return shape and existing localized routing
behavior.
src/pages/history-page/lib/format-history.ts (2)

24-32: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Ручное форматирование даты без учёта локали.

formatTimestamp вручную собирает строку YYYY-MM-DD HH:mm, игнорируя локаль пользователя (en/ru). Можно заменить на Intl.DateTimeFormat(locale, {...}) для консистентности с остальной локализацией приложения.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/history-page/lib/format-history.ts` around lines 24 - 32, Update
formatTimestamp to use Intl.DateTimeFormat with the application’s locale and
equivalent date/time options instead of manually assembling year, month, day,
hour, and minute. Preserve the existing YYYY-MM-DD HH:mm-style output where
required by the localized formatter and keep the timestamp parsing behavior
unchanged.

3-11: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

3xx-статусы помечаются как ошибка.

Диапазон 300–399 (редиректы) не является ошибкой, но getStatusLabel/getStatusColor помечают любой статус вне 2xx как "ERR"/red. Для истории запросов это может быть некорректно/вводить в заблуждение пользователя.

🛠️ Пример правки
 export function getStatusLabel(status: number): string {
   if (status >= 200 && status < 300) return `${status} OK`;
+  if (status >= 300 && status < 400) return `${status} REDIRECT`;
   return `${status} ERR`;
 }

 export function getStatusColor(status: number): BadgeColor {
   if (status >= 200 && status < 300) return 'green';
+  if (status >= 300 && status < 400) return 'gray';
   return 'red';
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/history-page/lib/format-history.ts` around lines 3 - 11, Update
getStatusLabel and getStatusColor to treat HTTP statuses from 300 through 399 as
successful/non-error outcomes alongside 2xx statuses. Preserve the existing
“OK”/green behavior for 2xx and apply the same behavior to 3xx, while retaining
“ERR”/red for all other statuses.
src/features/schema-validator/lib/codemirror-linter.ts (1)

16-20: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Отсутствует обработка ошибок вызова validateSchema.

Если асинхронная валидация схемы выбросит исключение, промис runOpenapiLinter реджектится без обработки, и линтер CodeMirror не получит диагностики штатным образом. Стоит обернуть вызов в try/catch и возвращать пустой массив при ошибке.

♻️ Предлагаемый рефакторинг
 export const runOpenapiLinter = async (view: EditorView) => {
   const text = view.state.doc.toString();

-  const results = await validateSchema(text);
+  let results;
+  try {
+    results = await validateSchema(text);
+  } catch {
+    return [];
+  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/schema-validator/lib/codemirror-linter.ts` around lines 16 - 20,
Update runOpenapiLinter to wrap the asynchronous validateSchema call in
try/catch; when validation throws, handle the error and return an empty
diagnostics array while preserving the existing successful validation result.
src/entities/endpoint/ui/request-body/request-body.test.tsx (1)

22-36: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Не покрыт fallback-путь генерации примера.

Тесты проверяют только случай с явным mediaType.example. Ветка generateExample(mediaType.schema) (когда example не передан) не покрыта тестом.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/entities/endpoint/ui/request-body/request-body.test.tsx` around lines 22
- 36, Extend the RequestBody test coverage to exercise the fallback
example-generation path by providing a media type with a schema but no explicit
example, then assert that the rendered request body uses the generated example.
Keep the existing explicit-example assertions unchanged and target the
RequestBody rendering behavior around generateExample(mediaType.schema).
src/shared/ui/button/button.tsx (1)

13-19: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Нет дефолтного type для кнопки внутри форм.

{...rest} не задаёт type по умолчанию, поэтому внутри <form> кнопка неявно получит type="submit" от браузера, если вызывающий код забудет явно указать type="button". Учитывая, что компонент используется как общий UI-кит в формах авторизации/регистрации, стоит явно задать безопасный дефолт.

♻️ Предлагаемый фикс
-export function Button({ children, className, variant = 'primary', ...rest }: IProps): ReactNode {
+export function Button({ children, className, variant = 'primary', type = 'button', ...rest }: IProps): ReactNode {
   return (
-    <button className={clsx(styles.button, styles[variant], className)} {...rest}>
+    <button type={type} className={clsx(styles.button, styles[variant], className)} {...rest}>
       {children}
     </button>
   );
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/button/button.tsx` around lines 13 - 19, Update the Button
component’s rendered button element to default its type to "button" while
preserving any explicit type supplied through rest props. Keep the existing
variant, className, children, and other prop behavior unchanged.
src/widgets/header/ui/header.tsx (1)

11-14: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Параллелизуйте независимые запросы getTranslations и getCurrentUser.

Оба вызова не зависят друг от друга, но выполняются последовательно в компоненте, который рендерится на каждой странице. Promise.all сократит суммарную задержку рендеринга хедера.

Предложение
 export async function Header() {
-  const t = await getTranslations('Header');
-  const user = await getCurrentUser();
+  const [t, user] = await Promise.all([getTranslations('Header'), getCurrentUser()]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/widgets/header/ui/header.tsx` around lines 11 - 14, Обновите компонент
Header, чтобы независимые вызовы getTranslations и getCurrentUser выполнялись
параллельно через Promise.all, сохранив их результаты в переменных t и user для
последующего рендеринга.
src/widgets/header/ui/logo/logo.tsx (1)

7-18: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Рассмотрите priority для логотипа в хедере.

Логотип рендерится на каждой странице в хедере и потенциально виден при первой загрузке. Можно добавить priority к next/image, чтобы избежать lazy-loading для элемента, который всегда виден сразу.

Предложение
-        <Image src="/logo.png" alt="AURA Editor" width={40} height={40} />
+        <Image src="/logo.png" alt="AURA Editor" width={40} height={40} priority />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/widgets/header/ui/logo/logo.tsx` around lines 7 - 18, Update the Image
component in Logo to use priority loading for the header logo, ensuring it is
fetched immediately rather than lazy-loaded while preserving the existing
source, dimensions, and alt text.
package.json (1)

24-30: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Расширьте проверки за пределы src.

Команды форматирования и ESLint не проверяют app, pages, proxy.ts, конфигурационные файлы и локализации. В результате ошибки в release-критичных маршрутах и API могут пройти CI незамеченными. Используйте явные globs или запускайте проверки для всех исходных каталогов приложения.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` around lines 24 - 30, Расширьте команды format, ci:format, lint
и lint:fix в package.json, чтобы они проверяли не только src, но также app,
pages, proxy.ts, конфигурационные файлы и локализации через явные globs или
полный набор исходных каталогов приложения. Обновите validate так, чтобы он
использовал расширенные проверки.
src/shared/ui/badge/badge.tsx (1)

8-16: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Несоответствие имени интерфейса и компонента.

Интерфейс называется StatusBadgeProps, а компонент — Badge. Для консистентности лучше переименовать в BadgeProps.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/badge/badge.tsx` around lines 8 - 16, Rename the
StatusBadgeProps interface to BadgeProps and update the Badge component’s
parameter type reference accordingly, preserving all existing props and
behavior.
src/shared/ui/badge/badge.module.scss (1)

1-18: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Убрать пустые строки перед декларациями (Stylelint).

Правило declaration-empty-line-before требует отсутствия пустой строки перед декларацией внутри блока — сработало на строках 7, 12, 16.

🔧 Предлагаемое исправление
 .statusBadge {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   gap: 0.8rem;
-
   border-radius: 4px;
   border: 1px solid var(--badge-border-color);
   background-color: var(--badge-color);
   padding: 4px 12px;
-
   font-family: var(--font-ui), monospace;
   white-space: nowrap;
   transition: color 0.3s ease;
-
   font-size: 12px;
   color: var(--badge-text-color);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/badge/badge.module.scss` around lines 1 - 18, Remove the blank
lines between declaration groups in the .statusBadge rule so every declaration
directly follows the previous declaration, satisfying the
declaration-empty-line-before Stylelint rule.

Source: Linters/SAST tools

src/widgets/footer/ui/footer.tsx (1)

23-30: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Захардкоженный год и нелокализованная строка "RS School 2026".

В отличие от остального текста, отрендеренного через t(...), эта строка не локализована, а год 2026 со временем устареет.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/widgets/footer/ui/footer.tsx` around lines 23 - 30, Update the footer
school link text in the component containing the styles.schoolName anchor to use
the existing localization mechanism via t(...) and generate the displayed year
dynamically instead of hardcoding 2026, preserving the current link attributes
and styling.
src/shared/api/supabase/middleware.ts (1)

38-39: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

startsWith без учёта границы сегмента пути.

PROTECTED_PATHS/AUTH_PATHS матчатся через pathname.startsWith(path), поэтому гипотетический маршрут вроде /history-export тоже будет считаться защищённым/auth-страницей. Сейчас конфликтующих маршрутов нет, но стоит матчить по границе сегмента (=== или startsWith(path + '/')).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/api/supabase/middleware.ts` around lines 38 - 39, Update the path
checks in the isProtected and isAuthPage calculations to match only exact paths
or descendants at a segment boundary, using equality or a path prefix followed
by "/". Preserve matching for the configured route itself and nested routes
while preventing similarly prefixed routes such as "/history-export" from
matching.
src/shared/ui/toast/toast.tsx (1)

76-99: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Отсутствует доступность для скринридеров.

Контейнер тостов не имеет role="status"/aria-live, поэтому появление уведомлений не будет анонсироваться пользователям скринридеров. Кнопка закрытия (Line 93-95) — иконка без aria-label, поэтому у неё нет доступного имени.

♿️ Предлагаемое исправление
-      <div className={styles.container}>
+      <div className={styles.container} role="status" aria-live="polite">
         {toasts.map((toast) => {
           ...
-              <button type="button" className={styles.closeButton} onClick={() => closeToast(toast.id)}>
+              <button
+                type="button"
+                className={styles.closeButton}
+                aria-label="Close"
+                onClick={() => closeToast(toast.id)}
+              >
                 <CloseIcon className={styles.closeIcon} />
               </button>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/toast/toast.tsx` around lines 76 - 99, Update the toast
container in the component rendering the `toasts.map` list with an appropriate
live-region role and `aria-live` setting so newly added notifications are
announced to screen readers. Add an accessible name to the close button
containing `CloseIcon`, while preserving its existing `closeToast(toast.id)`
behavior.
src/shared/ui/toast/toast.module.scss (1)

5-5: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Захардкоженный z-index: 7777 вместо переменной.

В остальной части стилей (например, #root { z-index: var(--z-base); } в _base.scss) z-index управляется через CSS-переменные. Магическое число 7777 здесь ломает эту конвенцию и усложняет управление слоями в будущем.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/toast/toast.module.scss` at line 5, Replace the hardcoded
z-index value in the toast styles with the established CSS z-index variable
convention, reusing the appropriate layer variable such as --z-base instead of
introducing a new magic number.
src/entities/endpoint/ui/try-it-out-form/try-it-out-form.test.tsx (1)

13-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Полная замена navigator без очистки и сохранения остальных свойств.

vi.stubGlobal('navigator', { clipboard: { writeText: mockWriteText } }) подменяет весь объект navigator целиком, теряя остальные свойства (userAgent и т.д.), которые могут использоваться React/jsdom/другими зависимостями. Стаб выполняется на уровне модуля и не откатывается через vi.unstubAllGlobals() в afterEach/afterAll.

♻️ Предлагаемое исправление
-const mockWriteText = vi.fn();
-vi.stubGlobal('navigator', {
-  clipboard: {
-    writeText: mockWriteText,
-  },
-});
+const mockWriteText = vi.fn();
+
+beforeEach(() => {
+  vi.stubGlobal('navigator', {
+    ...navigator,
+    clipboard: { writeText: mockWriteText },
+  });
+});
+
+afterEach(() => {
+  vi.unstubAllGlobals();
+});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/entities/endpoint/ui/try-it-out-form/try-it-out-form.test.tsx` around
lines 13 - 18, Update the module-level navigator mock around mockWriteText to
preserve the existing navigator properties while overriding only
clipboard.writeText, and add lifecycle cleanup that restores the global stub
after tests via the appropriate Vitest unstub mechanism. Ensure each test starts
with the original navigator state intact.

Comment thread .github/workflows/checks.yml
Comment thread .github/workflows/checks.yml
Comment thread app/api/proxy/route.ts
Comment thread app/api/proxy/route.ts
Comment thread messages/en.json
Comment thread src/entities/endpoint/ui/try-it-out-form/try-it-out-form.tsx
Comment thread src/features/auth/model/action.ts
Comment thread src/pages/about-page/ui/card/card.tsx
Comment thread src/shared/api/supabase/middleware.ts
Comment thread src/shared/api/utils/form.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 87-95: Update the fenced directory-tree block in README so it
declares the text language identifier, keeping the existing tree content
unchanged. Locate the markdown fence around the src/ directory listing and
change only the opening fence to use the same block with text specified, which
satisfies the markdownlint MD040 requirement.
- Around line 165-167: Обновите раздел Prerequisites в README: замените
минимальную версию Node.js с v18+ на v20.9+, оставив требование npm без
изменений.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 001a2e28-5e9a-4b11-aecb-b9997a69d8e8

📥 Commits

Reviewing files that changed from the base of the PR and between 880fb69 and 99ef9ac.

📒 Files selected for processing (1)
  • README.md

Comment thread README.md
Comment on lines +87 to +95
```
src/
├── app/ → Global styles (SCSS variables, mixins, constants, base reset)
├── pages/ → Page-level compositions (Home, About, History, Login, Register)
├── widgets/ → Complex UI blocks (Header, Footer, SwaggerEditor, SwaggerViewer)
├── features/ → Business logic slices (Auth, FormatConverter, SchemaValidator, History, etc.)
├── entities/ → Domain models (Endpoint — types, grouping, method badge, parameter display)
└── shared/ → Reusable UI kit, Supabase clients, i18n config, hooks, types
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Укажите язык для блока с деревом каталогов.

Fenced code block на Line 87 не содержит идентификатор языка. markdownlint сообщает MD040. Добавьте text.

Предлагаемое исправление
-```
+```text
 src/
 ├── app/
 ...
 └── shared/
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 87-87: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 87 - 95, Update the fenced directory-tree block in
README so it declares the text language identifier, keeping the existing tree
content unchanged. Locate the markdown fence around the src/ directory listing
and change only the opening fence to use the same block with text specified,
which satisfies the markdownlint MD040 requirement.

Source: Linters/SAST tools

Comment thread README.md
Comment on lines +165 to +167
### Prerequisites

- **Node.js** v18+ and **npm** v9+

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== candidate files =="
fd -a '^(README\.md|package\.json|package-lock\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb)$' . | sed 's#^\./##'

echo
echo "== README prerequisites section =="
if [ -f README.md ]; then
  nl -ba README.md | sed -n '150,200p'
fi

echo
echo "== package manifests with next =="
for f in package.json; do
  [ -f "$f" ] || continue
  echo "--- $f ---"
  python3 - <<'PY'
import json, pathlib
for p in pathlib.Path('.').rglob('package.json'):
    try:
        data=json.loads(p.read_text())
    except Exception as e:
        continue
    deps={}
    for k in ('dependencies','devDependencies','peerDependencies'):
        deps.update(data.get(k,{}) or {})
    if 'next' in deps:
        print(p, deps['next'])
PY
done

echo
echo "== lockfile next versions =="
for f in package-lock.json pnpm-lock.yaml yarn.lock bun.lockb; do
  [ -f "$f" ] && echo "--- $f ---" && rg -n '"?next"?|next@|next:|node_modules/next|/next@' "$f" | head -80 || true
done

echo
echo "== repository next config mentioning webpack (if any) =="
rg -n "webpack|reactWebpack|compiler|experimental|nextVersion|engines|nodejs|Node\.js" package.json README.md . 2>/dev/null | head -200 || true

Repository: FierceSloth/swagger-editor-app

Length of output: 365


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== README around prerequisites =="
awk 'NR>=150 && NR<=200 { printf "%d\t%s\n", NR, $0 }' README.md

echo
echo "== package.json next scripts/engines/next =="
python3 - <<'PY'
import json
from pathlib import Path
for path in [Path('package.json')]:
    data=json.loads(path.read_text())
    print("name:", data.get('name'))
    print("engines:", data.get('engines'))
    props=('scripts','dependencies','devDependencies','peerDependencies')
    next_found=False
    for prop in props:
        val=data.get(prop,{}) or {}
        for k,v in val.items():
            if k.lower() in ('next','node') or k=='node':
                next_found=True
            if k=='next':
                print(f"{prop}.next={v}")
    if 'scripts' in data:
        for k,v in data['scripts'].items():
            if any(x in v.split() for x in ('node','.next','next','webpack')):
                print(f"scripts.{k}={v}")
PY

echo
echo "== lockfile next package entries =="
python3 - <<'PY'
import json
from pathlib import Path
p=Path('package-lock.json')
if p.exists():
    data=json.loads(p.read_text())
    root=pkg=data.get('packages',{}).get('',{})
    print("root next version:", pkg.get('dependencies',{}).get('next') or pkg.get('devDependencies',{}).get('next') or pkg.get('peerDependencies',{}).get('next'))
    pkgs=data.get('packages',{})
    for k,v in pkgs.items():
        if k.endswith('node_modules/next') or k == 'node_modules/next':
            print("package",k, "version", v.get('version'), "resolved", v.get('resolved'))
PY

echo
echo "== files with next/nextjs/webpack references =="
rg -n -i "next(\.js|@|js|) v?16|nextjs 16|webpack|requires|requires node|node\.js v18|node\.js v20|engines|nodejs|supported" README.md package.json package-lock.json 2>/dev/null || true

Repository: FierceSloth/swagger-editor-app

Length of output: 25993


🌐 Web query:

Next.js 16 Node.js 20.9 minimum version Node.js support

💡 Result:

Next.js 16 requires a minimum Node.js version of 20.9.0 or higher [1][2]. This change was implemented because Node.js v18 reached its End-of-Life (EOL), prompting the move to the first Long Term Support (LTS) version of Node.js 20 [3][4]. Support for Node.js 18 has been removed in Next.js 16 [1][5].

Citations:


Исправьте минимальную версию Node.js.

README указывает Node.js v18+, но package.json использует next 16.2.9. Next.js 16 требует Node.js 20.9+; Node.js 18 больше не поддерживается. Значит, установщик с Node.js 18 получит ошибку до запуска проекта. Укажите Node.js v20.9+.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 165 - 167, Обновите раздел Prerequisites в README:
замените минимальную версию Node.js с v18+ на v20.9+, оставив требование npm без
изменений.

This branch was successfully deployed

2 active deployments
Production — 8cee7e62 Deployed Sep 6, 2026 by vercel[bot]
Preview — 8cee7e62 Deployed Sep 6, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants