Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Prefer small explicit repetition over premature abstraction
When duplication is tiny and low-risk, keep it explicit and clear instead of adding an abstraction whose indirection hurts readability.
Bad example
| 1 | // Abstraction added to avoid declaring noindex on two routes |
| 2 | function withNoindex(source: string) { |
| 3 | return { source, headers: [{ key: 'X-Robots-Tag', value: 'noindex' }] }; |
| 4 | } |
| 5 |
|
| 6 | const headers = ['/product/:slug/app/:path*', '/product/:slug/appView'].map(withNoindex); |
Explanation (EN)
The helper and map add indirection for only two near-trivial entries. A reader now has to jump to withNoindex to understand what each route gets; the abstraction costs more clarity than the repetition it removes.
Objašnjenje (HR)
Pomocna funkcija i map dodaju neizravnost za samo dva gotovo trivijalna unosa. Citatelj sada mora skociti na withNoindex da bi razumio sto svaka ruta dobiva; apstrakcija kosta vise jasnoce nego sto uklanja ponavljanja.
Good example
| 1 | const headers = [ |
| 2 | { |
| 3 | source: '/product/:slug/app/:path*', |
| 4 | headers: [{ key: 'X-Robots-Tag', value: 'noindex' }], |
| 5 | }, |
| 6 | { |
| 7 | source: '/product/:slug/appView', |
| 8 | headers: [{ key: 'X-Robots-Tag', value: 'noindex' }], |
| 9 | }, |
| 10 | ]; |
Explanation (EN)
The two entries are spelled out explicitly. It reads top-to-bottom with no indirection, and the minor duplication is cheaper than the abstraction it would otherwise need.
Objašnjenje (HR)
Dva unosa su ispisana eksplicitno. Cita se odozgo prema dolje bez neizravnosti, a manje ponavljanje jeftinije je od apstrakcije koja bi inace bila potrebna.
Exceptions / Tradeoffs (EN)
Abstract when the repetition is large, must stay in sync across many places to avoid bugs, or is clearly going to grow; then the helper earns its indirection. Balance against extract-duplicated-logic-shared-across-services: keep duplication only when it is tiny and low-risk; once the logic is substantial or genuinely shared, extract it. Balance against extract-duplicated-route-validators: keep a one-line parse inline when it appears in only a couple of routes and carries no shared contract. Balance against inject-data-provider-over-nested-fetch-branching: a small one-time if/else is fine; introduce the provider abstraction only when branching recurs or paths are complex. Balance against extract-duplicated-ui-primitives: leave a tiny markup snippet duplicated when it appears once or twice and isn't a meaningful shared primitive. Balance against extract-shared-frontend-utilities: keep a trivial one-liner duplicated rather than spawning a shared util for near-zero logic. Balance against prefer-config-maps-for-tabular-ui-variants: keep two or three explicit variants inline rather than building a config-map indirection. Balance against replace-repetitive-switch-rendering-with-configuration-maps: keep a small switch when there are few cases or they diverge meaningfully in structure. Balance against extract-complex-mapping-logic: keep a short, single-use map callback inline rather than naming a helper for trivial logic.
Iznimke / Tradeoffi (HR)
Apstrahirajte kad je ponavljanje veliko, mora ostati sinkronizirano na mnogo mjesta kako bi se izbjegle greske, ili ce ocito rasti; tada pomocna funkcija opravdava svoju neizravnost.