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
};
Related Documentation
- Testing Strategy - How we test quality
- Performance Monitoring - How we measure
- Pipeline Resilience - Error handling and reliability