Imported from RedHatInsights/ocp-advisor-frontend (
AGENTS.md). Install upstream withnpx skills add RedHatInsights/ocp-advisor-frontend. Copyright stays with the author.
OCP Advisor Frontend - Agent Instructions
React micro-frontend for OpenShift Advisor on console.redhat.com. Displays cluster recommendations, workloads, and update risks. Runs inside Red Hat Insights Chrome shell via Module Federation.
Tech Stack
- React 18 (JavaScript — no TS files yet, but strict tsconfig exists for gradual adoption)
- Redux Toolkit + RTK Query for state and data fetching
- PatternFly 6 UI components (
@patternfly/react-core,react-table,react-icons,react-charts) - Webpack via
@redhat-cloud-services/frontend-components-config(FEC) — not a custom webpack config - Module Federation exposes:
RootApp,ClustersPdfBuild,BuildExecReport - react-intl for i18n
- axios for mutations; RTK Query
fetchBaseQueryfor reads - Unleash for feature flags
- Sentry for error tracking
- Node 22 required
Project Structure
src/
App.js # Root: auth, store provider, notifications
AppEntry.js # Module Federation entry
AppConstants.js # Constants, column defs, filter categories, labels
Messages.js # react-intl message definitions
Routes.js # React Router v6 routes (lazy-loaded)
Components/ # PascalCase directories
ComponentName/
index.js # Container: hooks, data fetching, passes props
ComponentName.js # Presentational: receives props, renders JSX
_ComponentName.scss # Scoped styles (underscore prefix)
ComponentName.cy.js # Cypress component test
ComponentName.test.js # Jest unit test
Services/ # RTK Query API definitions
SmartProxy.js # Main API: clusters, rules, recs, workloads
Acks.js # Acknowledgments API + axios mutations
Filters.js # Redux slice for filter state
Store/
index.js # configureStore combining all reducers
Utilities/
Api.js # axios wrappers: Post, Put, Delete
Helpers.js # setSearchParameter, strong()
Rule.js # getPluginName, getErrorKey, adjustOCPRule
useFeatureFlag.js # Unleash feature flag hook
intlHelper.js # Intl provider wrapper
Loaders.js # Skeleton loaders
ErrorBoundary.js # Error boundary component
cypress/
fixtures/api/ # JSON API response fixtures
utils/ # Reusable test helpers (interceptors, filters, pagination)
support/commands.js # cy.mountWithContext() and OUIA helpers
config/
setupTests.js # Jest setup: mocks react-intl
deploy/
frontend.yml # Kubernetes Frontend CRD template
First Time Setup
-
Add entries to
/etc/hosts(one-time setup per machine). Follow the initial etc/hosts setup from frontend-starter-app:127.0.0.1 <your-fqdn> localhost prod.foo.redhat.com stage.foo.redhat.com -
Make sure you have Node.js and npm installed (maintained versions).
-
Make sure you are using Red Hat proxy.
-
Install dependencies:
npm install
Running Locally
-
Stage environment:
npm run start:proxythen choosestageandprevieworstable. Available athttps://stage.foo.redhat.com:1337/openshift/insights/advisor -
Production environment:
npm run start:proxythen chooseprodandprevieworstable. Available athttps://prod.foo.redhat.com:1337/openshift/insights/advisor
Development Commands
npm ci # Install dependencies
npm run start:proxy # Dev server with API proxy to stage
npm run build # Production build
npm run test # Jest unit tests (TZ=UTC, with coverage)
npm run test:local # Jest without coverage
npm run test:ct # Cypress component tests (headless Chrome)
npm run test:openct # Cypress component tests (interactive)
npm run lint # All linters (ESLint + Stylelint)
npm run lint:js:fix # ESLint with auto-fix
npm run verify # build + lint + test
npm run translations # Extract + compile i18n messages
Code Conventions
Component Pattern
Components follow container/presentational separation:
index.js— Container. Calls RTK Query hooks, extracts route params viauseParams(), passes data as props. Uses default export.ComponentName.js— Presentational. Receives props, renders JSX. Uses named export.- Simpler components (e.g.,
RecsList) may combine both inindex.js.
Data Fetching
- Reads: RTK Query hooks from
src/Services/SmartProxy.js(useGetXQuery,useLazyGetXQuery). - Writes: Mutations via
Acks.js(useSetAckMutation) or axios calls viasrc/Utilities/Api.js(Post,Put,Delete). - API base path:
/api/insights-results-aggregator. - Never call
fetchdirectly — use RTK Query or the axios wrappers.
State Management
- Server state: RTK Query caches (SmartProxy, Acks).
- Filter state: Redux slice in
src/Services/Filters.js. - Store created via
getStore()factory insrc/Store/index.js.
Type Checking
- Use PropTypes for all component props (not TypeScript interfaces).
- Add
PropTypesimport and.propTypesstatic property on every component.
Imports
- PatternFly:
@patternfly/react-core,@patternfly/react-table. - Lodash: Import individual functions (
import get from 'lodash/get'), not the full library. - Chrome:
import useChrome from '@redhat-cloud-services/frontend-components/useChrome'. - FEC:
@redhat-cloud-services/frontend-components/ComponentName.
Internationalization
- All user-facing strings defined in
src/Messages.jsusingdefineMessages. - Use
intl.formatMessage(messages.messageId)via theuseIntl()hook. - After adding/changing messages, run
npm run translationsand commit the updatedcompiled-lang/output.
Routing
- App URL base:
/openshift/insights/advisor - Routes:
/recommendations,/clusters,/workloads, plus detail pages with:clusterId,:recommendationId,:namespaceIdparams. - All route components are lazy-loaded with
React.lazy+Suspense.
Feature Flags
- Use
useFeatureFlag(flagName)fromsrc/Utilities/useFeatureFlag.js.
Commits
- Conventional commits enforced:
type(scope): description - Types:
fix,feat,chore,refactor,test,docs,style,perf,ci
Testing Conventions
Jest Unit Tests (*.test.js)
- Co-located alongside the component.
- Use
@testing-library/react+@testing-library/jest-dom. - Jest runs with TZ=UTC — date assertions must use UTC.
- Setup:
config/setupTests.js(mocksreact-intl). - CSS/SCSS mocked via
identity-obj-proxy. - Coverage from
src/**/*.{js,jsx}, excludes*.cy.js.
Cypress Component Tests (*.cy.js)
- Co-located in the component directory.
- Mount with
cy.mountWithContext(component, options)— wraps in FlagProvider, IntlProvider, Redux Provider, MemoryRouter. - API mocking via interceptor factories from
cypress/utils/. - Fixtures: JSON files in
cypress/fixtures/api/insights-results-aggregator/. - OUIA selectors:
cy.ouiaId(),cy.ouiaType().
When to Use Which
- Jest: Pure logic, utilities, simple rendering.
- Cypress: User interaction, API integration flows, table filtering/sorting/pagination.
Styling Conventions
- SCSS only, no CSS-in-JS.
- Component SCSS uses underscore prefix:
_ComponentName.scss. - Build automatically scopes styles under
.ocp-advisor, .ocpAdvisorvia FECsassPrefix. - Use PatternFly CSS variables instead of hardcoded colors/spacing.
- No Prettier — formatting is ESLint + Stylelint only.
Gotchas
-
Route
key={Math.random()}: All route elements use random keys to force re-renders — workaround for OCPADVISOR-59. Do not remove without verifying the bug is fixed. -
Mixed API versions: SmartProxy uses
v2endpoints. Acks uses somev1endpoints. Don't accidentally mix versions. -
Rule ID format: Rule IDs use
plugin_name|ERROR_KEY(pipe-separated). Parse withgetPluginName()andgetErrorKey()fromsrc/Utilities/Rule.js. -
TZ=UTC for tests: Jest runs with
TZ=UTC. Date-related assertions must use UTC or tests will be flaky locally. -
Micro-frontend context: This app runs inside Insights Chrome. Auth, navigation, and the
<main>container are provided by Chrome. UseuseChrome()for Chrome APIs. -
Module Federation singleton:
react-router-domis shared as a singleton and excluded from the bundle. Do not add conflicting versions. -
Compiled translations committed:
compiled-lang/en.jsonis checked in. After changingsrc/Messages.js, runnpm run translationsand commit the output. -
No TypeScript files yet: All source files are
.js/.jsxdespite havingtsconfig.json. New files should follow existing.jspatterns unless intentionally starting TS migration. -
Module Federation entry points:
AppEntry.js,ClustersPdfBuild.js,BuildExecReport.jsare consumed by other apps. Changes affect downstream consumers.