fix: resolve critical Biome linting issues and document code quality standards

- Add biome-ignore comments for security-critical non-null assertions
- Fix unused variables and parameter ordering issues
- Reduce complexity in integration functions via helper extraction
- Replace problematic 'any' type casts with proper type definitions
- Document code quality and linting standards in CLAUDE.md

Build verification:  TypeScript compilation passes
Security verification:  Critical auth contexts preserved

Note: Some remaining Biome warnings for performance utility classes
and decorator patterns are acceptable given architectural constraints.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-07-13 17:30:44 +02:00
parent b946bdc803
commit 42ad5b7c80
10 changed files with 133 additions and 95 deletions

View File

@ -222,7 +222,7 @@ export function requireAllPermissions(permissions: Permission[]) {
export function validateCompanyAccess(
context: APIContext,
targetCompanyId: string,
resourceType?: ResourceType
_resourceType?: ResourceType
): CompanyAccessResult {
if (!context.user) {
return {

View File

@ -248,7 +248,7 @@ export function asyncErrorHandler<T extends readonly unknown[], R>(
/**
* Error boundary for API route handlers
*/
export function withErrorHandling<T extends readonly unknown[], R>(
export function withErrorHandling<T extends readonly unknown[], _R>(
handler: (...args: T) => Promise<NextResponse> | NextResponse
) {
return async (...args: T): Promise<NextResponse> => {

View File

@ -10,11 +10,9 @@ import { type NextRequest, NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import type { z } from "zod";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { rateLimiter } from "@/lib/rateLimiter";
import type { UserSession } from "@/lib/types";
import {
APIError,
AuthenticationError,
AuthorizationError,
handleAPIError,
@ -247,16 +245,16 @@ function validateQuery<T>(request: NextRequest, schema: z.ZodSchema<T>): T {
* Log API access for audit purposes
*/
async function logAPIAccess(
context: APIContext,
outcome: "success" | "error",
endpoint: string,
error?: Error
_context: APIContext,
_outcome: "success" | "error",
_endpoint: string,
_error?: Error
): Promise<void> {
try {
// Only log if audit logging is enabled for this endpoint
// TODO: Integrate with security audit logger service
// Production logging should use proper logging service instead of console.log
} catch (logError) {
} catch (_logError) {
// Don't fail the request if logging fails
// TODO: Send to error tracking service
}

View File

@ -151,6 +151,85 @@ async function executeWithDeduplication<T extends unknown[], R>(
);
}
/**
* Helper function to start monitoring if enabled
*/
function startMonitoringIfEnabled(enabled?: boolean): void {
if (enabled) {
try {
performanceMonitor.start();
} catch {
// Monitoring may already be running
}
}
}
/**
* Helper function to record request metrics if enabled
*/
function recordRequestIfEnabled(timer: ReturnType<typeof PerformanceUtils.createTimer>, isError: boolean, enabled?: boolean): void {
if (enabled) {
performanceMonitor.recordRequest(timer.end(), isError);
}
}
/**
* Helper function to execute request with caching/deduplication optimizations
*/
async function executeRequestWithOptimizations(
req: NextRequest,
opts: ReturnType<typeof mergeOptions>,
routeName: string,
originalHandler: (req: NextRequest) => Promise<NextResponse>
): Promise<NextResponse> {
if (opts.cache?.enabled || opts.deduplication?.enabled) {
return executeWithCacheOrDeduplication(req, opts, originalHandler);
}
// Direct execution with monitoring
const { result } = await PerformanceUtils.measureAsync(routeName, () =>
originalHandler(req)
);
return result;
}
/**
* Helper function to execute with cache or deduplication
*/
async function executeWithCacheOrDeduplication(
req: NextRequest,
opts: ReturnType<typeof mergeOptions>,
originalHandler: (req: NextRequest) => Promise<NextResponse>
): Promise<NextResponse> {
const url = new URL(req.url);
const method = req.method;
const params = url.searchParams.toString();
const cacheKey = `${method}:${url.pathname}:${params}`;
if (opts.cache?.enabled) {
const cache =
caches[opts.cache.cacheName as keyof typeof caches] ||
caches.apiResponses;
return cache.getOrCompute(
cacheKey,
() => originalHandler(req),
opts.cache.ttl
);
}
// Deduplication only
const deduplicator =
deduplicators[
opts.deduplication?.deduplicatorName as keyof typeof deduplicators
] || deduplicators.api;
return deduplicator.execute(
cacheKey,
() => originalHandler(req),
{ ttl: opts.deduplication?.ttl }
);
}
/**
* Enhance an API route handler with performance optimizations
*/
@ -167,63 +246,12 @@ export function enhanceAPIRoute(
const timer = PerformanceUtils.createTimer(`api.${routeName}`);
try {
// Start monitoring if not already running
if (opts.monitoring?.enabled) {
try {
performanceMonitor.start();
} catch {
// Monitoring may already be running
}
}
let response: NextResponse;
if (opts.cache?.enabled || opts.deduplication?.enabled) {
// Generate cache key from request
const url = new URL(req.url);
const method = req.method;
const params = url.searchParams.toString();
const cacheKey = `${method}:${url.pathname}:${params}`;
if (opts.cache?.enabled) {
const cache =
caches[opts.cache.cacheName as keyof typeof caches] ||
caches.apiResponses;
response = await cache.getOrCompute(
cacheKey,
() => originalHandler(req),
opts.cache.ttl
);
} else {
// Deduplication only
const deduplicator =
deduplicators[
opts.deduplication!.deduplicatorName as keyof typeof deduplicators
] || deduplicators.api;
response = await deduplicator.execute(
cacheKey,
() => originalHandler(req),
{ ttl: opts.deduplication!.ttl }
);
}
} else {
// Direct execution with monitoring
const { result } = await PerformanceUtils.measureAsync(routeName, () =>
originalHandler(req)
);
response = result;
}
if (opts.monitoring?.recordRequests) {
performanceMonitor.recordRequest(timer.end(), false);
}
startMonitoringIfEnabled(opts.monitoring?.enabled);
const response = await executeRequestWithOptimizations(req, opts, routeName, originalHandler);
recordRequestIfEnabled(timer, false, opts.monitoring?.recordRequests);
return response;
} catch (error) {
if (opts.monitoring?.recordRequests) {
performanceMonitor.recordRequest(timer.end(), true);
}
recordRequestIfEnabled(timer, true, opts.monitoring?.recordRequests);
throw error;
}
};
@ -292,7 +320,7 @@ export function PerformanceOptimized(
* Simple caching decorator
*/
export function Cached(
cacheName = "default",
_cacheName = "default",
ttl: number = 5 * 60 * 1000,
keyGenerator?: (...args: unknown[]) => string
) {

View File

@ -6,7 +6,6 @@
*/
import { PerformanceObserver, performance } from "node:perf_hooks";
import { TIME } from "../constants";
import { cacheManager } from "./cache";
import { deduplicationManager } from "./deduplication";
@ -223,7 +222,7 @@ export class PerformanceMonitor {
console.log(
"[Performance Monitor] Started monitoring with interval:",
intervalMs + "ms"
`${intervalMs}ms`
);
}
@ -286,7 +285,7 @@ export class PerformanceMonitor {
const eventLoopDelay = performance.now() - start;
// Event loop utilization (approximated)
const eventLoopUtilization = Math.min(
const _eventLoopUtilization = Math.min(
100,
(eventLoopDelay / 16.67) * 100
); // 16.67ms = 60fps
@ -778,7 +777,7 @@ export class PerformanceUtils {
}
descriptor.value = async function (...args: unknown[]) {
const { result, duration } = await PerformanceUtils.measureAsync(
const { result } = await PerformanceUtils.measureAsync(
metricName,
() => originalMethod.apply(this, args)
);

View File

@ -247,7 +247,7 @@ export class PerformanceOptimizer {
* Optimize caching performance
*/
private async optimizeCaching(
metrics: PerformanceMetrics
_metrics: PerformanceMetrics
): Promise<OptimizationResult[]> {
const results: OptimizationResult[] = [];
@ -284,7 +284,7 @@ export class PerformanceOptimizer {
* Optimize response times
*/
private async optimizeResponseTime(
metrics: PerformanceMetrics
_metrics: PerformanceMetrics
): Promise<OptimizationResult[]> {
const results: OptimizationResult[] = [];
@ -510,7 +510,7 @@ export class PerformanceOptimizer {
* Handle memory bottleneck
*/
private async handleMemoryBottleneck(
bottleneck: Bottleneck
_bottleneck: Bottleneck
): Promise<OptimizationResult[]> {
const results: OptimizationResult[] = [];
@ -534,7 +534,7 @@ export class PerformanceOptimizer {
* Handle event loop bottleneck
*/
private async handleEventLoopBottleneck(
bottleneck: Bottleneck
_bottleneck: Bottleneck
): Promise<OptimizationResult[]> {
return [
{
@ -555,7 +555,7 @@ export class PerformanceOptimizer {
* Handle cache bottleneck
*/
private async handleCacheBottleneck(
bottleneck: Bottleneck
_bottleneck: Bottleneck
): Promise<OptimizationResult[]> {
// Could implement cache warming or size adjustments
return [
@ -623,7 +623,7 @@ export class PerformanceOptimizer {
// Calculate average improvement
const improvementRates = this.optimizationHistory
.filter((r) => r.result.metrics?.improvement)
.filter((r) => r.result.metrics?.improvement !== undefined)
.map((r) => r.result.metrics!.improvement);
const averageImprovementRate =

View File

@ -5,13 +5,6 @@
* into existing services using decorators and integration utilities.
*/
import {
Cached,
Deduplicated,
Monitored,
PerformanceEnhanced,
PerformanceOptimized,
} from "../performance/integration";
import { AuditOutcome, AuditSeverity } from "../securityAuditLogger";
import { AlertChannel, type MonitoringConfig } from "../securityMonitoring";
import type { Alert, SecurityEvent } from "../types/security";
@ -202,7 +195,7 @@ export class EnhancedSecurityService {
// monitoring: { enabled: true },
// })
private async generateAlertsIfNeeded(
event: SecurityEvent,
_event: SecurityEvent,
threatLevel: ThreatLevel
): Promise<Alert[]> {
if (threatLevel === ThreatLevel.LOW) {
@ -388,7 +381,7 @@ export class EnhancedSecurityService {
}
// Private helper methods (would be implemented based on actual data access)
private async getSecurityEvents(timeRange: {
private async getSecurityEvents(_timeRange: {
start: Date;
end: Date;
}): Promise<SecurityEvent[]> {
@ -397,7 +390,7 @@ export class EnhancedSecurityService {
}
private calculateThreatDistribution(
events: SecurityEvent[]
_events: SecurityEvent[]
): Record<ThreatLevel, number> {
return {
[ThreatLevel.LOW]: 0,
@ -407,7 +400,7 @@ export class EnhancedSecurityService {
};
}
private async getAlertCounts(timeRange: {
private async getAlertCounts(_timeRange: {
start: Date;
end: Date;
}): Promise<Record<string, number>> {
@ -434,7 +427,7 @@ export class EnhancedSecurityService {
return Math.floor(Math.random() * 10);
}
private async getRecentAlerts(limit: number): Promise<Alert[]> {
private async getRecentAlerts(_limit: number): Promise<Alert[]> {
return [];
}
@ -447,13 +440,13 @@ export class EnhancedSecurityService {
}
private async performSearch(
query: Record<string, unknown>
_query: Record<string, unknown>
): Promise<SecurityEvent[]> {
// Mock search implementation
return [];
}
private calculateAggregations(events: SecurityEvent[]) {
private calculateAggregations(_events: SecurityEvent[]) {
return {
byType: {},
bySeverity: {},