Rules Hub
Search
Use the projects configuration in Vitest to isolate Node-based unit tests from browser-based integration tests in a single file.
Learning how to write tests meaning
Query elements by accessible roles (e.g., button, option) to ensure tests resemble user behavior and verify accessibility.
Use a dedicated utility to persist singleton instances across module reloads instead of manual globalThis assignments.
Feat/FCK-2245 - Cache Bellsheep and profile loaders with TanStack Query #343
Use invariant utilities to assert conditions and narrow types instead of verbose manual checks.
Avoid manually defining loader return types; infer them directly from the loader function using TypeScript.
Do not use typeof checks for standard global objects like AbortSignal or URL; only feature-detect new methods on them if needed.
Use instanceof checks in filter callbacks to allow TypeScript to automatically infer types and avoid manual type predicates.
Avoid unsafe type casting on event.target; use instanceof checks or invariants to guarantee type safety at runtime.
Combine multiple cancellation sources (timeouts, user actions) into a single signal using AbortSignal.any to ensure robust resource cleanup.
Cast raw data to unknown before asserting specific generic types to handle diverging type paths safely.
Pass QueryClient and query keys to fetch utilities to enable caching and deduplication instead of raw fetching.
Always create fresh instances of stateful dependencies (like QueryClient or Stores) inside test helpers to ensure test isolation.
Encapsulate caching logic (like ensureQueryData) and dependency injection within fetch helpers to reduce boilerplate and ensure consistent signal handling.
Combine cancellation signals when using async libraries (like React Query) within framework lifecycles (like React Router) to ensure redundant requests are properly aborted.
Use strict `true` and `false` literals instead of `undefined` for boolean discriminants in unions to improve clarity and type safety.
When parsing external data in generic functions, cast directly to the return type generic to avoid type mismatches or suppressed errors.
Avoid defining manual type predicates in array filter callbacks when TypeScript can infer narrowing automatically.
Include configuration data in singleton cache keys to ensure instances are recreated when settings change during Hot Module Replacement.
Avoid calling useLoaderData multiple times or manual casting to merge types; rely on automatic type inference.
Use underscores (_) as numeric separators for large numbers and time calculations to improve visual parsing and reduce errors.
Inject dependencies into loaders using React Router's context middleware instead of closures or globals to improve testability and type safety.
Use curried functions to pass arguments to event handlers instead of inline anonymous wrappers to improve JSX readability.
Adding sorting feature to the table #10
Avoid duplicating JSX elements or using complex conditionals just to change visual order; use CSS flex-direction or order instead.
Do not export types, functions, or constants that are only used locally within a module to avoid polluting the public API.
Feat/FCK-1489 - Adding aoiImage to AgendaBase #1096
Avoid simple center-cropping or scaling for editorial images; use focal-point (AOI) metadata to ensure the subject remains visible.
Avoid transforming or formatting entity data inside controllers or routes; encapsulate this logic as computed properties or methods within the entity class itself.
Use stable, unique IDs from the data instead of array indices for React keys to ensure correct reconciliation and state preservation.
Feat/FCK-1561 - Adding Invoice Table to Minside #3570
Avoid using helper functions to return JSX; extract them into standalone React components for better debugging and performance.
Pass function references directly when arguments match, avoiding unnecessary anonymous wrapper functions.
Avoid repeating identical JSX structures inside switch statements; use a configuration object to map state to visual attributes.
Avoid hardcoding initial state values that must correspond to a specific list of options; reference the options source directly.
Do not use the name 'index' for variables that hold string identifiers or keys, as it implies numeric position and order dependence.
Avoid using numeric indices to identify columns during rendering; use stable string keys or enums to ensure readability and prevent regression when reordering.
Use objects with named keys instead of arrays (tuples) to represent structured data rows to improve readability and maintainability.
Avoid performing complex data formatting or object creation inside JSX map callbacks; extract this logic into a separate helper function or prepare the data beforehand.
Move complex modal UI and its specific data transformation logic into separate components to improve readability and testability.
Use `as const` on static arrays and objects to infer literal types and read-only tuples, preventing type widening.
Avoid implementing generic UI behaviors (like Modals, Drawers, or Tooltips) inline within feature components; extract them into reusable components.
Move direct DOM manipulations like scroll locking or event listeners into named custom hooks to separate side effects from UI logic.
Define props as ReactNode or JSX.Element instead of render functions or Component types when the content does not rely on the component's internal state.
Feat/FABS-420: Adding fallback for ticker images #246
Avoid defining methods in an abstract base class if they are only used by specific subclasses.
Fix/FCK-1614 - Resolving skipped AIR review changes #1180
Do not reuse specific data transformation methods for unrelated use cases; create dedicated methods to ensure decoupling.
Use `keyof typeof` to generate union types from constant objects to ensure a single source of truth and prevent synchronization errors.
Feat/FCK-1575 - Map products to human readable for Invoice Table #3633
Avoid typing maps as `Record<string, T>` when the keys are a finite known set; use `as const` or explicit unions to enforce strict key validation.
Move data fetching, subscriptions, and complex state logic into custom hooks to keep components focused on presentation.
Feat/FCK-1623 - Adding eAvis widget to the sidebar #3643
Always define and export an explicit interface for custom hook return values using the `[HookName]Payload` naming convention.
Check for 'AbortError' explicitly in catch blocks instead of relying on signal state to handle cancellations.
Avoid manually parsing date strings with `new Date()` or `split()` due to timezone ambiguity and fragility. Use centralized utilities instead.
Centralize global type declarations in a single file and only define properties that are strictly consumed.
useEffect runs only in the browser, so checking for window is redundant. Avoid silently skipping logic if required globals are missing; rely on strict types or fail loudly.
Use null or undefined to explicitly represent missing data instead of magic strings to simplify truthiness checks and avoid ambiguity.
Prevent type narrowing to 'null' by explicitly defining the generic type when initializing state with null.
Avoid defensive feature detection for AbortController as it is supported in all modern browsers and Node.js.
Avoid explicit generic type arguments for `useState` when the type can be correctly inferred from the initial primitive value.
Use a utility function to execute inline logic immediately instead of noisy IIFE syntax inside JSX props.
Fix/FABS-441 - Fixing mobile paywall and paywall image endpoint #250
Always attach an AbortController signal to fetch requests to prevent indefinite hanging on slow networks.
Feat/FCK-1669 - Adding Job Landing Page #3656
Always add guard clauses inside useEffect to check if required dependencies exist before performing expensive operations like data fetching.
Files named '*.types.ts' should strictly contain type definitions. If they export runtime values, rename them to '*.constants.ts' or the domain name.
Always validate required arguments before using them in external requests and explicitly handle upstream 404 responses to distinguish missing data from errors.
Return a 4xx response immediately when validation fails instead of calling next(), which passes control to subsequent handlers.
Wrap `new URL()` calls in try-catch blocks to prevent runtime crashes from malformed strings.
Wrap logic that might throw errors (like URL parsing) in safe handlers outside JSX to prevent component crashes.
Always render a visual indicator (spinner or skeleton) during data fetching instead of returning null to improve user experience.
Always include relevant identifiers (IDs, slugs, keys) in error messages to facilitate debugging and reproduction.
Centralize data access and transformation logic within dedicated Provider classes instead of loose functions or inline logic.
Wrap components that must always be used together into a single parent component to enforce consistency and prevent usage errors.
Fix/FCK-1721 - Fix MWS Token bug and show Bors Top bar data #3729
Use the optional chaining operator (?.) to access deeply nested properties instead of verbose logical AND checks.
Feat/FCK-1757 - Fix search trigger on Search Page #3773
Avoid dense one-liners involving multiple logic branches or string manipulations; break them into distinct, named steps for clarity.
Feat/FCK-1783 - Add tracking for Mest lest box on FP #3780
Use named constants or enums instead of raw string literals in conditional logic to prevent typos and ease refactoring.
Feat/FCK-1867 - Add Bellsheep and Top 50 tabs as Standalone pages #1360
Use the native URL and URLSearchParams APIs to build query strings instead of manual string concatenation or array joining.
Feat/FCK-1885 - Add trigger for fake Klikaya pageview #8
Use null to explicitly represent missing values in API responses instead of ambiguous defaults like empty strings or zeroes.
Feat/FCK-1888 - Create new articles by tag endpoint #1291
Do not create specialized repository methods for specific filter combinations; rely on chainable (fluent) methods and a single terminal execution method.
Avoid manually chaining query filters and mapping logic inside controllers; extract them into specific repository methods.
Ensure primary and fallback data providers use identical matching logic (exact vs. fuzzy) to prevent unpredictable results.
Utilize method chaining when working with fluent interfaces (like query builders) to avoid unnecessary intermediate variables.
Avoid file extensions in URL paths and organize routes by access scope (public vs. private) to improve maintainability and security.
Compute derived values (like URLs, labels, or config) in the component body instead of embedding logic or anonymous functions inside JSX props.
Feat/FCK-1941 - Add Phone App modal after Enter Code form #667
If an element opens a URL or navigates the user, use an anchor tag instead of a button with an onClick handler.
Place logic triggered by user interactions directly in event handlers instead of watching state with useEffect.
Avoid hardcoding specific tracking values inside reusable UI components to ensure they remain context-agnostic.
Avoid inline interaction with third-party globals (like analytics) inside components; extract them into named service functions.
Use <a> tags for navigation instead of buttons with onClick handlers to ensure accessibility, SEO, and native browser behavior.
Check explicitly for specific variants instead of relying on negative checks against a default. This ensures a safe fallback for undefined or future values.
Feat/FCK-2004 - New Motor header and footer #693
Avoid complex nested ternary operators for value selection by using a helper function that accepts a configuration object.
Avoid defining complex UI logic inline within render props. Extract them into separate components to improve readability and maintainability.
Feat/FCK-2005 - Update Person graph UI #314
Move static visual parameters, magic numbers, and style constants into a dedicated configuration object to separate concerns and improve maintainability.
Use hooks like `useMatches` or `useMatch` with stable route IDs to detect active routes instead of manually parsing the `pathname` string.
Feat/FCK-2116 - Hide transaction disclaimer on profil tab on person profile #320
Set initial element visibility to hidden when controlling it via client-side JavaScript to avoid UI flickering.
Use stable route IDs to identify routes programmatically instead of relying on brittle URL path strings.
Calculate derived conditions in the render scope and pass primitives to useEffect to prevent unnecessary re-runs.
Variable names must describe the specific domain concept they hold. Generic terms like 'data', 'info', or 'items' fail to convey intent and make code harder to understand.
Feat/FCK-2144 - Move ranking history to the top on mobile #325
Do not specify `type="text/javascript"` for scripts or `type="text/css"` for styles, as they are implied defaults in HTML5.
Feat/FCK-2096 - Login Modal UI fixes #712
Wrap the application root in React.StrictMode to catch potential problems, unsafe lifecycles, and impure renderers during development.
Replace opaque literal values (magic strings/numbers) with named constants or enums to make code self-documenting and maintainable.
Feat/FCK-2248 - Add new vevPage and podcast to the sidebar #4126
Use logical AND (&&) instead of the ternary operator when conditionally spreading properties into an object to reduce verbosity.
Feat/FCK-2204 - Send date of birth to MC on payment init #715
When a test modifies the global environment (like prototypes or global variables), use a try-finally block to guarantee the environment is restored even if assertions fail.
Feat/FCK-2200 - Polyfill isWellFormed for Safari slugs #341
When modifying global objects (prototypes, window) in a test, use try-finally to guarantee cleanup even upon failure.
Wrap libraries that require polyfills in a dedicated module to encapsulate side effects and clarify dependencies.
Avoid manually implementing polyfills in source code; use granular imports from established libraries like core-js to ensure correctness and maintainability.
Avoid imperative DOM calls like .blur() or .stopPropagation() to control focus; use semantic HTML or accessible libraries instead.
Fix/FCK-2261 - Fix issues with the Kapital frontpage widget #4151
Attach listeners to `document` for content interactions (clicks, key presses) and reserve `window` for viewport events (resize, scroll) to maintain semantic clarity.
Do not trigger significant UI changes like opening modals on focus events to preserve keyboard navigation.
Use AbortController signals to manage and clean up event listeners instead of manually pairing addEventListener with removeEventListener.
Use battle-tested headless libraries (like Radix UI or Headless UI) for complex interactive patterns to ensure robust accessibility and focus management.
Use AbortController to manage event listener lifecycle instead of manually pairing addEventListener and removeEventListener.
Do not use event.preventDefault() if declarative HTML attributes like readOnly or disabled already enforce the desired behavior.
Use `instanceof Node` to safely narrow `event.target` types instead of unsafe casting with `as Node`.
Variables named with boolean prefixes (is, has, should) must strictly hold boolean values to ensure code clarity.
Feat/FCK-2259 - Show category label on market news articles #4152
Avoid hardcoding specific string or number literals in conditional logic. Use named arrays or Sets to define the business rule, making the code more readable and extensible.
Feat/FCK-2295 - Hide number of billionaires on 400 richest #4159
Always define `aspect-ratio` and use `max-width` for responsive images to reserve layout space and prevent Cumulative Layout Shift (CLS).
Feat/FCK-2286 - Create new Heirs Kapital list page #4161
Use max-width to ensure images respond to container size without forcing them to stretch beyond their natural resolution.
Ensure alt text accurately mirrors the image content or function without adding redundant context or filler words.
Use the `clsx` utility to construct className strings conditionally instead of manual string concatenation.
Avoid moving blocks of code unless strictly necessary for logic or scoping, as it creates noisy diffs and complicates code reviews.
Centralize domain definitions (like lists or resources) into a single shared configuration to prevent duplication and inconsistency across environments.
For images containing text, the alt attribute must mirror that text exactly to ensure equivalent access for screen readers.
Always optimize SVG files using tools like SVGO to remove unnecessary metadata and reduce bundle size.
Use `as const` for literals in conditionals to preserve their specific type, enabling cleaner type inference without manual annotations.
Use a configuration-based serializer to handle edge cases (like omitting fields) instead of hardcoding conditional logic in controllers.
Feat/FCK-2297 - Remove number of billionaires #254
Use the standardized Object.groupBy method instead of manual iteration to group array items.
Feat/FCK-2384 - Upgrade MyFa Watchlist functionality #4232
Wrap only unstable code (like I/O) in try-catch blocks, keeping data transformation logic outside.
Avoid complex inline callbacks in array methods like .map(); extract the logic into named helper functions for better readability.
Use plain objects (Record) instead of Maps for simple ID-based lookups unless specific Map features are required.
Avoid using 'let' for variables that are only reassigned during initialization; use IIFEs or helper functions to keep them 'const'.
Use flatMap to transform and filter items in a single pass instead of chaining map and filter.
Always use consistent plural nouns for resource collections in API routes to ensure predictability.
Avoid using global window events for component communication; use React Context to share state and actions instead.
Feat/FCK-2431 - Add settings modal for MyFa #4261