Skip to main content

Code Quality Standards

All code in Kingisoovitaja must adhere to ISO/IEC 25002:2024 standards and project-specific quality guidelines.

ISO/IEC 25002:2024 Compliance

Quality Characteristics

Modularity Requirements

Single Responsibility

Each file/function should have ONE clear purpose:

** Good:**

// search-orchestrator.ts
export async function orchestrateSearch(context: GiftContext) {
// Only search orchestration logic
}

** Bad:**

// everything.ts
export function doEverything() {
// Extract context + search + validate + generate response
}

Dependency Injection

** Good:**

function processProducts(
products: Product[],
scorer: (p: Product) => number
) {
return products.map(p => ({ ...p, score: scorer(p) }));
}

** Bad:**

function processProducts(products: Product[]) {
// Hardcoded dependency
return products.map(p => ({ ...p, score: defaultScorer(p) }));
}

Code Documentation

Function Documentation

Required for all exported functions:

/**
* Orchestrates the complete search pipeline from query to final products
*
* @param giftContext - Enriched context from context orchestrator
* @param excludeIds - Previously shown product IDs to exclude
* @param debug - Enable verbose logging
* @returns Search result with products, metrics, and diagnostics
*
* @throws {SearchError} When all search strategies fail
* @throws {ValidationError} When products don't meet quality threshold
*
* @example
* ```typescript
* const result = await orchestrateSearch({
* intent: 'product_search',
* productType: 'Raamat',
* budget: { max: 30 }
* }, [], true);
* ```
*/
export async function orchestrateSearch(
giftContext: GiftContext,
excludeIds: string[],
debug: boolean = false
): Promise<SearchResult> {
// Implementation
}

Type Safety

All functions must have explicit types:

//  Good
function calculateScore(product: Product): number {
return product.price / 10;
}

// Bad
function calculateScore(product) {
return product.price / 10;
}

Comments

When to comment:

  • Complex algorithms
  • Non-obvious business logic
  • Performance optimizations
  • Temporary workarounds (with TODO)

Example:

// OPTIMIZATION: Sort once and cache for multiple filters
// Saves ~50ms on average per request
const sortedProducts = useMemo(
() => products.sort((a, b) => b.score - a.score),
[products]
);

Naming Conventions

Files

// Components: PascalCase
ProductCard.tsx
UnifiedChatProvider.tsx

// Utilities: kebab-case
query-rewriting.ts
context-enrichment.ts

// Types: PascalCase with .types
GiftContext.types.ts

// Tests: .test or .spec
search-orchestrator.test.ts

Variables

// Constants: UPPER_SNAKE_CASE
const MAX_PRODUCTS = 3;
const DEFAULT_LANGUAGE = 'et';

// Variables: camelCase
const searchResults = await search();
const giftContext = extractContext();

// Booleans: is/has/should prefix
const isShowMore = checkIntent();
const hasProducts = results.length > 0;
const shouldRerank = candidates.length >= 10;

Functions

// Actions: verb + noun
function extractContext()
function generateQuery()
function validateResponse()

// Getters: get + noun
function getSystemPrompt()
function getProducts()

// Checkers: is/has/can + predicate
function isValidAuthor()
function hasRequiredFields()
function canProceed()

Error Handling Standards

Always Handle Errors

//  Good
try {
const result = await riskyOperation();
return result;
} catch (error) {
console.error('Operation failed:', error);
return fallbackValue;
}

// Bad
const result = await riskyOperation(); // Unhandled!

Typed Errors

class SearchError extends Error {
constructor(
message: string,
public code: string,
public context?: Record<string, any>
) {
super(message);
this.name = 'SearchError';
}
}

throw new SearchError(
'No products found',
'SEARCH_EMPTY',
{ query, filters }
);

Testing Requirements

Coverage Minimums

Critical paths: 95%
Services: 85%
Utilities: 90%
Components: 80%
Overall: 80%

Required Tests

// Every exported function needs:
describe('functionName', () => {
it('handles valid input', () => { /* ... */ });
it('handles invalid input', () => { /* ... */ });
it('handles edge cases', () => { /* ... */ });
it('throws expected errors', () => { /* ... */ });
});

Code Review Checklist

Before Requesting Review

  • All tests pass locally
  • Linter shows no errors
  • TypeScript compiles without warnings
  • Functions documented
  • Performance impact measured
  • No console.log left in code
  • Error handling added

Reviewer Checks

  • Code follows conventions
  • Logic is clear and maintainable
  • Edge cases considered
  • Performance acceptable
  • Security concerns addressed
  • Tests are comprehensive
  • Documentation updated

Linting Rules

ESLint configuration:

{
"extends": [
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"complexity": ["warn", 15],
"max-depth": ["warn", 4],
"no-console": "warn",
"@typescript-eslint/explicit-function-return-type": "error"
}
}

Performance Standards

Component Render Time

// Maximum 16ms per render (60 FPS)
function Component() {
useEffect(() => {
const start = performance.now();

// ... render logic

const duration = performance.now() - start;
if (duration > 16) {
console.warn('Slow render:', { component: 'Component', duration });
}
});
}

Animation Standards

// All animations must:
// 1. Use GPU-accelerated properties (transform, opacity)
// 2. Maintain 60 FPS
// 3. Use Motion.dev (never Framer Motion)
// 4. Have stutter-free playback

const ANIMATION_STANDARDS = {
minFPS: 60,
maxDuration: 500, // ms
easing: 'ease-out',
properties: ['transform', 'opacity'] // GPU-accelerated only
};