Best practices for AI coding agents on NetObserv Web Console.
Note: Symlinked as CLAUDE.md for Claude Code auto-loading.
NetObserv Web Console - OpenShift Console dynamic plugin for network observability visualization (also deployable as standalone app).
Stack:
- Frontend: TypeScript, React 18, PatternFly 6, React Router 7, i18next 25
- Plugin SDK:
@openshift-console/dynamic-plugin-sdk4.22+ (plugin mode only) - Backend: Go HTTP server for Loki queries, Kubernetes resources, Prometheus metrics
Deployment Modes:
- Plugin: Integrated into OpenShift Console (OCP 4.22+)
- Standalone: Independent web application
PatternFly Version Support Matrix:
| OCP Version | Branch | PatternFly |
|---|---|---|
| ≥ 4.22 | main |
PF6 |
| 4.19-4.21 | main or main-pf5 |
PF6 or PF5 |
| 4.15-4.18 | main-pf5 |
PF5 |
| ≤ 4.14 | main-pf4 |
PF4 |
See OpenShift Console PatternFly documentation for plugin compatibility details.
Key Directories:
web/src/components/: React components (forms, tables, topology, etc.)web/src/api/: Backend API clientweb/src/model/: Data models, transformations, and context providersweb/src/utils/: Utility functions and custom React hooksweb/src/standalone/: Standalone mode application entry pointpkg/handler/: HTTP request handlerspkg/loki/: Loki client and query builderspkg/kubernetes/: Kubernetes API clientpkg/prometheus/: Prometheus clientweb/cypress/e2e/: Cypress E2E tests on mock dataweb/cypress/integration-tests/: Integration tests with OpenShift
- Plugin mode must use
@openshift-console/dynamic-plugin-sdkAPIs - Plugin mode must follow OpenShift Console conventions for navigation, extensions, theming
- Standalone mode uses the same codebase but without Console integration
- Test both plugin and standalone modes
- Node.js 24 (source of truth:
Dockerfile.front) .npmrccontainslegacy-peer-deps=truefor dependency resolution- Use nvm for version management
Dockerfile: Production multi-stage build (frontend + backend)Dockerfile.front: Frontend build (Node.js version source of truth)Dockerfile.downstream: Downstream/productized buildsDockerfile.ci: CI environment buildsDockerfile.e2e,Dockerfile.cypress: Test runner images
- All user-facing strings must use react-i18next
- Run
make i18nto update translation files - Never hardcode English strings in UI
Be specific about file paths, existing patterns, and testing requirements.
Good: "Add dnslatency to ColumnsId enum in web/src/utils/columns.ts. Define in config/sample-config.yaml. Update Loki query in pkg/loki/flow_query.go. Test both modes."
Bad: "Add DNS latency column"
Key Principles:
- Exact file paths (
web/src/components/, not "frontend") - Reference existing patterns (columns, filters, Loki queries)
- i18n for UI strings, dual-mode testing
- Check package.json before adding dependencies
- Column workflow: columns.ts enum → sample-config.yaml → optional RecordField rendering
Add new API endpoint for zone filtering:
1. Add route in pkg/server/routes.go:
- Register route with api.HandleFunc()
2. Add handler implementation in pkg/handler/ (e.g., resources.go):
- Create handler function on Handlers struct
- Validate query parameters
- Use existing error handling patterns
3. Update pkg/loki/flow_query.go if Loki query needed
4. Update web/src/api/routes.ts with new endpoint
5. Add Go unit tests in pkg/handler/*_test.go
6. Test with both real Loki and mocks (see pkg/handler/lokiclientmock/)
FlowCollector CRD field changed in operator:
1. Follow instructions in README.md#updating-schemas
2. Update web/src/components/forms/config/uiSchema.ts with new field display rules
3. Update web/src/model/flow-query.ts if query params change
4. Update web/src/components/tabs/netflow-overview/ if overview UI changes
5. Regenerate schemas using scripts/generate-schemas.sh (requires running cluster)
6. Test with both old and new FlowCollector versions
- Custom Hooks: Logic extracted into focused hooks in
web/src/utils/*-hook.ts(capabilities, URL sync, fetching, theme, storage, etc.) - Context:
NetflowContextinweb/src/model/netflow-context.tsshares config/capabilities across components - React Router: v7, centralized in
web/src/utils/url.ts
- Plugin mode: Console integration (localhost:9001), requires Console clone for dev
- Standalone mode: Independent app (
make start-standaloneormake start-standalone-mock), build withSTANDALONE=true make images - FLAVOR=
enduserlimits production standalone to Network Traffic/Health tabs
- Limit time ranges, prefer
=over=~matchers, push aggregations to LogQL - Check
/api/loki/config/limitsfor query constraints - Mock mode:
make start-standalone-mockormake serve-mock
- Operator-Generated (Production): ConfigMap from FlowCollector CR, fetched via
/api/frontend-config- Source: static-frontend-config.yaml (operator repo) + FlowCollector spec
- Critical: Changes to
config/sample-config.yamlfrontend section MUST be synced to operator'sstatic-frontend-config.yaml
- Development:
config/sample-config.yamlfor local testing only
- Version: v6.4+ (see
web/package.json) - Follow PatternFly patterns, test light/dark themes
- Docs: patternfly.org/v6
Support: amd64, arm64, ppc64le, s390x. Frontend built once, backend per arch.
Build: MULTIARCH_TARGETS="amd64 arm64" make images
Review for:
1. TypeScript type safety (no 'any' types without justification)
2. PatternFly component usage consistency
3. i18n strings for all user-facing text
4. Error handling (proper error messages and patterns)
5. Unit tests (React Testing Library for frontend, Go tests for backend)
6. Loki query efficiency (time ranges, label matchers)
7. Both plugin and standalone mode testing
8. Accessibility (ARIA labels, keyboard navigation)
9. Performance (avoid unnecessary re-renders, optimize queries)
10. Usability and user experience (intuitive workflows, clear feedback)
- Unit: Jest 30 + React Testing Library 16 (
web/src/**/__tests__/), Go tests (pkg/*_test.go) - E2E:
web/cypress/e2e/- runs on mock data - Integration:
web/cypress/integration-tests/- requires OpenShift cluster (main branch: OCP 4.19+) - Run Cypress:
make cypressorcd web && npm run cypress:open
Essential Commands:
make build # Build backend and frontend
make frontend # Build, lint, test frontend
make backend # Build, lint, test backend
make start-standalone # Start standalone mode (requires Loki)
make start-standalone-mock # Start standalone with mocked data
make bridge # Bridge plugin to OpenShift Console
make i18n # Update i18n translation files
make image-build image-push # Build and push imageKey Files:
- Frontend config: web/src/model/config.ts
- API routes: web/src/api/routes.ts
- Loki queries: pkg/loki/flow_query.go, pkg/loki/topology_query.go
- Backend routes: pkg/server/routes.go
- Backend handlers: pkg/handler/handlers.go
- Table columns: web/src/utils/columns.ts
- UI schema: web/src/components/forms/config/uiSchema.ts
- Sample config: config/sample-config.yaml
1. Research: "Explain how topology view fetches and renders network flows"
2. Plan: "Add edge highlighting for high-latency flows - suggest component changes"
3. Implement: "Implement with proper data filtering and PatternFly styling"
4. Review: "Review for performance impact and edge cases"
5. i18n: "Run make i18n to update translation files"
6. Test: "Provide Cypress test scenarios for edge highlighting"
Before commit:
- AI code review
- Add unit tests (React Testing Library for frontend, Go tests for backend)
- Add Cypress tests for UI features
make build lint test(both frontend and backend)make i18n(if UI strings changed)- Test both plugin and standalone modes
- Update README.md (if new features added)
- Conventional commit messages
- README.md - Setup, build, test, deploy, run locally
- CONTRIBUTING.md - Contribution guidelines
Remember: AI agents need clear context. Always review generated code, test thoroughly in both plugin and standalone modes, and follow project conventions.