fix: comprehensive security and type improvements from PR #20 review

Security Enhancements:
- Implemented proper rate limiting with automatic cleanup for /register and /forgot-password endpoints
- Added memory usage protection with MAX_ENTRIES limit (10000)
- Fixed rate limiter memory leaks by adding cleanup intervals
- Improved IP extraction with x-real-ip and x-client-ip header support

Code Quality Improvements:
- Refactored ProcessingStatusManager from individual functions to class-based architecture
- Maintained backward compatibility with singleton instance pattern
- Fixed TypeScript strict mode violations across the codebase
- Resolved all build errors and type mismatches

UI Component Fixes:
- Removed unused chart components (Charts.tsx, DonutChart.tsx)
- Fixed calendar component type issues by removing unused custom implementations
- Resolved theme provider type imports
- Fixed confetti component default options handling
- Corrected pointer component coordinate type definitions

Type System Improvements:
- Extended NextAuth types to support dual auth systems (regular and platform users)
- Fixed nullable type handling throughout the codebase
- Resolved Prisma JSON field type compatibility issues
- Corrected SessionMessage and ImportRecord interface definitions
- Fixed ES2015 iteration compatibility issues

Database & Performance:
- Updated database pool configuration for Prisma adapter compatibility
- Fixed pagination response structure in user management endpoints
- Improved error handling with proper error class usage

Testing & Build:
- All TypeScript compilation errors resolved
- ESLint warnings remain but no errors
- Build completes successfully with proper static generation
This commit is contained in:
2025-06-30 19:15:25 +02:00
parent 5042a6c016
commit 38aff21c3a
32 changed files with 1002 additions and 929 deletions

View File

@ -7,14 +7,14 @@ import {
} from "@prisma/client";
import cron from "node-cron";
import fetch from "node-fetch";
import { withRetry } from "./database-retry.js";
import { prisma } from "./prisma.js";
import { withRetry } from "./database-retry";
import { prisma } from "./prisma";
import {
completeStage,
failStage,
getSessionsNeedingProcessing,
startStage,
} from "./processingStatusManager.js";
} from "./processingStatusManager";
import { getSchedulerConfig } from "./schedulerConfig";
const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
@ -137,15 +137,19 @@ interface ProcessingResult {
interface SessionMessage {
id: string;
timestamp: Date;
timestamp: Date | null;
role: string;
content: string;
order: number;
createdAt: Date;
sessionId: string;
}
interface SessionForProcessing {
id: string;
messages: SessionMessage[];
companyId: string;
endTime: Date | null;
}
/**
@ -250,7 +254,7 @@ async function processQuestions(
});
// Filter and prepare unique questions
const uniqueQuestions = [...new Set(questions.filter((q) => q.trim()))];
const uniqueQuestions = Array.from(new Set(questions.filter((q) => q.trim())));
if (uniqueQuestions.length === 0) return;
// Batch create questions (skip duplicates)
@ -527,7 +531,7 @@ async function processSingleSession(
const transcript = session.messages
.map(
(msg: SessionMessage) =>
`[${new Date(msg.timestamp)
`[${new Date(msg.timestamp || msg.createdAt)
.toLocaleString("en-GB", {
day: "2-digit",
month: "2-digit",
@ -552,7 +556,7 @@ async function processSingleSession(
// Calculate endTime from latest Message timestamp
const calculatedEndTime = await calculateEndTime(
session.id,
session.endTime
session.endTime || new Date()
);
// Update the session with processed data
@ -710,9 +714,8 @@ async function processUnprocessedSessionsInternal(
// Filter to only sessions that have messages
const sessionsWithMessages = sessionsToProcess.filter(
(session): session is SessionForProcessing =>
session.messages && session.messages.length > 0
);
(session) => session.messages && session.messages.length > 0
) as SessionForProcessing[];
if (sessionsWithMessages.length === 0) {
process.stdout.write(