Remove console.log debug calls from frontend browser console

Removes all debug/verbose console.log calls across frontend to prevent
sensitive data exposure (session IDs, tokens) and reduce console noise.
Keeps only console.error and console.warn for genuine errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vadym Samoilenko 2026-03-23 14:30:56 +00:00
parent f60d86e8cb
commit 770bdee829
20 changed files with 55 additions and 472 deletions

View file

@ -177,19 +177,12 @@ const FolderTree = ({
const handleDragStart = (event: DragStartEvent) => {
const draggedFolderId = event.active.id as string;
setActiveId(draggedFolderId);
console.log('🖱️ Drag started:', draggedFolderId);
};
const handleDragEnd = (event: DragEndEvent) => {
const { active, over } = event;
setActiveId(null);
console.log('🖱️ Drag ended:', {
activeId: active.id,
overId: over?.id,
overType: over?.data.current?.type,
});
if (!over || active.id === over.id) return;
const draggedFolder = folders.find(f => f._id === active.id);
@ -203,7 +196,6 @@ const FolderTree = ({
// Special case: All Personas folder (move to root level)
if (targetFolder._id === 'all-personas-root') {
console.log('🖱️ Dropping to root level via All Personas');
newParentId = null;
parentName = null;
} else {
@ -277,13 +269,6 @@ const FolderTree = ({
sensors={sensors}
collisionDetection={rectIntersection}
onDragStart={handleDragStart}
onDragOver={(event) => {
console.log('🖱️ Drag over:', {
activeId: event.active.id,
overId: event.over?.id,
overData: event.over?.data.current,
});
}}
onDragEnd={handleDragEnd}
>
<div className="space-y-1">

View file

@ -9,12 +9,6 @@ export default function ProtectedRoute({ children }: ProtectedRouteProps) {
const { isAuthenticated, isLoading } = useAuth();
const location = useLocation();
console.log('ProtectedRoute check:', {
isAuthenticated,
isLoading,
path: location.pathname
});
if (isLoading) {
// Show a loading spinner while authentication state is being determined
return (
@ -25,11 +19,9 @@ export default function ProtectedRoute({ children }: ProtectedRouteProps) {
}
if (!isAuthenticated) {
console.log('Not authenticated, redirecting to login');
// Redirect to the login page, but save the current location they were trying to access
return <Navigate to="/login" state={{ from: location.pathname }} replace />;
}
console.log('User is authenticated, showing protected content');
return <>{children}</>;
}

View file

@ -147,14 +147,11 @@ export default function UserCreator({ targetFolderId, targetFolderName }: UserCr
setIsAutoLoginInProgress(true);
try {
console.log('Attempting auto login with default credentials');
await login('user', 'pass');
console.log('Auto login successful');
// Verify the token was stored
const storedToken = localStorage.getItem('auth_token');
if (storedToken) {
console.log('Token successfully stored:', storedToken.substring(0, 10) + '...');
toastService.success('Logged in automatically with default account');
} else {
console.error('Token not stored after successful login');
@ -322,7 +319,6 @@ export default function UserCreator({ targetFolderId, targetFolderName }: UserCr
async function onSubmit(values: z.infer<typeof formSchema>, isRetry = false) {
// Prevent infinite loops by limiting retries
if (isRetry && retryCount >= 1) {
console.log('Max retry attempts reached, stopping retry loop');
toastService.error("Authentication failed after multiple attempts", {
description: "Please try logging in manually (user/pass)"
});
@ -333,7 +329,6 @@ export default function UserCreator({ targetFolderId, targetFolderName }: UserCr
if (isRetry) {
setRetryCount(prevCount => prevCount + 1);
console.log(`Retry attempt ${retryCount + 1}`);
} else {
setRetryCount(0); // Reset retry count for new submissions
}
@ -344,9 +339,7 @@ export default function UserCreator({ targetFolderId, targetFolderName }: UserCr
// If not authenticated, try to log in with default credentials
if (!isAuthenticated) {
try {
console.log('Not authenticated, attempting login with default credentials before submission');
await login('user', 'pass');
console.log('Login successful before persona creation');
} catch (loginError) {
console.error('Login failed before persona creation:', loginError);
toastService.error("Authentication required", {
@ -362,8 +355,7 @@ export default function UserCreator({ targetFolderId, targetFolderName }: UserCr
const generationToastId = `persona-generation-${Date.now()}`;
const folderText = targetFolderId && targetFolderName ? ` in "${targetFolderName}" folder` : '';
const personaText = userCount > 1 ? `${userCount} personas` : 'persona';
console.log(`UserCreator - Creating ${personaText}${folderText}`);
toastService.createPersistent({
id: generationToastId,
title: `Generating ${personaText}...`,
@ -408,24 +400,20 @@ export default function UserCreator({ targetFolderId, targetFolderName }: UserCr
const token = localStorage.getItem('auth_token');
if (!token) {
console.error("No authentication token found");
toastService.error("Authentication required", {
description: "No valid token found. Please log in again."
toastService.error("Authentication required", {
description: "No valid token found. Please log in again."
});
// Force a new login
try {
console.log('No token found, attempting new login');
await login('user', 'pass');
console.log('Login successful, token:', localStorage.getItem('auth_token')?.substring(0, 10) + '...');
} catch (loginError) {
console.error('Login retry failed:', loginError);
throw new Error('Authentication failed after retry');
}
}
console.log("Sending persona creation request to API with auth token");
const result = await personasApi.create(personaData);
console.log("Persona created successfully:", result);
// Update persistent toast with success
toastService.updatePersistent(generationToastId, {
@ -473,24 +461,20 @@ export default function UserCreator({ targetFolderId, targetFolderName }: UserCr
const token = localStorage.getItem('auth_token');
if (!token) {
console.error("No authentication token found");
toastService.error("Authentication required", {
description: "No valid token found. Please log in again."
toastService.error("Authentication required", {
description: "No valid token found. Please log in again."
});
// Force a new login
try {
console.log('No token found, attempting new login');
await login('user', 'pass');
console.log('Login successful, token:', localStorage.getItem('auth_token')?.substring(0, 10) + '...');
} catch (loginError) {
console.error('Login retry failed:', loginError);
throw new Error('Authentication failed after retry');
}
}
console.log("Sending batch persona creation request to API with auth token");
const result = await personasApi.createBatch(batch);
console.log("Batch personas created successfully:", result);
// Update persistent toast with success
toastService.updatePersistent(generationToastId, {
@ -513,7 +497,6 @@ export default function UserCreator({ targetFolderId, targetFolderName }: UserCr
}
}
console.log("Persona creation successful (database storage)");
form.reset();
// Remove temp data since we succeeded
@ -532,15 +515,13 @@ export default function UserCreator({ targetFolderId, targetFolderName }: UserCr
retryCount < 1) {
// Try to log in again with default credentials
try {
console.log('Got auth error, attempting login retry with default credentials');
// Force clear any existing tokens that might be invalid
localStorage.removeItem('auth_token');
const response = await authApi.login('user', 'pass');
if (response?.data?.access_token) {
localStorage.setItem('auth_token', response.data.access_token);
localStorage.setItem('user', JSON.stringify(response.data.user));
console.log('Manual login successful, got new token:', response.data.access_token.substring(0, 10) + '...');
// If login succeeds, retry submission with retry flag
toastService.info("Logged in with default account, retrying submission...");

View file

@ -112,25 +112,20 @@ const AutonomousDashboard = ({
fetchAllData();
if (useWebSocketEnabled && wsConnected) {
console.log('📊 Setting up STABLE WebSocket event listeners for dashboard');
// Handle analytics updates
const handleAnalyticsUpdate = (data: any) => {
console.log('📊 Received analytics update:', data);
setAnalytics(data.analytics);
setLastUpdated(new Date());
};
// Handle conversation state updates
const handleStateUpdate = (data: any) => {
console.log('📊 Received conversation state update:', data);
setConversationState(data.state);
setLastUpdated(new Date());
};
// Handle AI status updates for autonomous dashboard
const handleAiStatusUpdate = (data: any) => {
console.log('📊 Received AI status update in dashboard:', data);
setAutonomousStatus(data.status);
setLastUpdated(new Date());
};
@ -138,16 +133,13 @@ const AutonomousDashboard = ({
// GPT-5 FIX: Would need window event listeners here like in FocusGroupSession
// For now, just commenting out to avoid the error
// const cleanupFunctions = [...];
console.log('📊 Dashboard WebSocket listeners temporarily disabled for GPT-5 fix');
// Cleanup using returned functions
return () => {
console.log('📊 Cleaning up STABLE dashboard WebSocket listeners');
// cleanupFunctions.forEach(cleanup => cleanup?.());
};
} else {
// Fallback to polling when WebSocket is not available
console.log('📊 Using polling for dashboard updates (WebSocket not available)');
const interval = setInterval(fetchAllData, 30000);
return () => clearInterval(interval);
}

View file

@ -289,15 +289,12 @@ const DiscussionPanel = ({
formData.append('assets', selectedFile);
const uploadResponse = await focusGroupsApi.uploadAssets(focusGroupId, formData);
console.log('Upload response:', uploadResponse?.data);
// Parse the actual backend response structure
const responseData = uploadResponse?.data;
if (responseData && responseData.assets && responseData.assets.length > 0) {
// Backend returns: { assets: [{ filename: 'fg-...', original_name: '...', ... }] }
uploadedFilename = responseData.assets[0].filename;
console.log('Successfully got filename from upload response:', uploadedFilename);
} else {
console.error('Invalid upload response structure:', responseData);
}
@ -331,9 +328,7 @@ const DiscussionPanel = ({
// Format message text to include the display reference instead of filename
finalMessageText = `Please review ${displayReference}. ${userInput}`;
console.log('Using display reference in message:', displayReference);
} catch (assetError) {
console.error('Error fetching asset metadata:', assetError);
// Fallback to generic reference
@ -383,8 +378,6 @@ const DiscussionPanel = ({
const response = await focusGroupsApi.sendMessage(focusGroupId, messageData);
console.log('Message sent to API:', response);
// Message will be handled by WebSocket system with correct server timestamp
// No need to manually create and add message here
@ -724,11 +717,8 @@ const DiscussionPanel = ({
const startAutonomousConversation = async () => {
if (!focusGroupId) return;
console.log('Starting AI Mode: setting autonomousLoading to true');
setAutonomousLoading(true);
try {
console.log('Starting AI Mode: calling API...');
// Add a timeout wrapper to the API call
const apiCallWithTimeout = Promise.race([
focusGroupAiApi.startAutonomousConversation(focusGroupId), // No initial prompt - let AI generate based on discussion guide
@ -738,8 +728,7 @@ const DiscussionPanel = ({
]);
const response = await apiCallWithTimeout;
console.log('Starting AI Mode: API response received:', response);
if (response.data.error) {
toast.error('Failed to start autonomous conversation', {
description: response.data.error
@ -757,17 +746,14 @@ const DiscussionPanel = ({
// Notify parent component of status change and wait for it to complete
try {
console.log('Starting AI Mode: calling onStatusChange...');
if (onStatusChange) {
await onStatusChange();
console.log('Starting AI Mode: onStatusChange completed successfully');
}
} catch (statusError) {
console.error('Starting AI Mode: onStatusChange failed:', statusError);
}
// Reset loading state after status has been updated
console.log('Starting AI Mode: resetting autonomousLoading to false');
setAutonomousLoading(false);
// GPT-5 FIX: Don't clear AI mode state - this was tearing down WebSocket listeners
@ -801,7 +787,6 @@ const DiscussionPanel = ({
const stopAutonomousConversation = async () => {
if (!focusGroupId) return;
console.log('Stopping AI Mode: setting autonomousLoading to true');
setAutonomousLoading(true);
try {
const response = await focusGroupAiApi.stopAutonomousConversation(focusGroupId, 'manual_stop');
@ -825,17 +810,14 @@ const DiscussionPanel = ({
// Notify parent component of status change and wait for it to complete
try {
console.log('Stopping AI Mode: calling onStatusChange...');
if (onStatusChange) {
await onStatusChange();
console.log('Stopping AI Mode: onStatusChange completed successfully');
}
} catch (statusError) {
console.error('Stopping AI Mode: onStatusChange failed:', statusError);
}
// Reset loading state after status has been updated
console.log('Stopping AI Mode: resetting autonomousLoading to false');
setAutonomousLoading(false);
// GPT-5 FIX: Don't clear AI mode state - this was tearing down WebSocket listeners
@ -946,8 +928,6 @@ const DiscussionPanel = ({
);
if (response?.data?.response) {
console.log('Generated response from mentioned participant:', response.data);
const aiMessage: Message = {
id: response.data.message_id || `msg-${Date.now()}-${participantId}`,
senderId: participantId,
@ -1074,8 +1054,6 @@ const DiscussionPanel = ({
}
} else {
// AI decided on a different action - handle or fall back to round-robin
console.log("AI suggested different action:", decision.action);
if (decision.action === 'moderator_speak') {
toast.info("AI suggests moderator intervention", {
description: `AI reasoning: ${decision.reasoning.substring(0, 100)}${decision.reasoning.length > 100 ? '...' : ''}`

View file

@ -282,7 +282,6 @@ export default function PersonaEditor({ persona, onSave, onCancel }: PersonaEdit
// Save to backend - handle local IDs specially
if (personaId && typeof personaId === 'string' && personaId.startsWith('local-')) {
console.log('Creating new persona instead of updating local ID');
response = await personasApi.create(personaToSave);
toast.success("Persona saved to database");
@ -333,7 +332,6 @@ export default function PersonaEditor({ persona, onSave, onCancel }: PersonaEdit
if (error.response && error.response.status === 401) {
// Check if we're already authenticated according to context
if (isAuthenticated && token) {
console.log("Auth error despite having token - token likely invalid");
toast.error("Authentication error - saving locally instead");
// Just save locally without showing login
onSave(editedPersona);

View file

@ -104,8 +104,6 @@ export default function PersonaProfile() {
// Use the persona's MongoDB _id or fallback to id
const personaId = currentPersona._id || currentPersona.id;
console.log(`🔽 Frontend: Exporting profile for persona ${currentPersona.name} (ID: ${personaId})`);
// Call the export API with GPT-4.1
const response = await personasApi.exportProfile(personaId, {
llm_model: 'gpt-4.1',

View file

@ -16,7 +16,6 @@ export const msalConfig: Configuration = {
loggerOptions: {
loggerCallback: (level, message, containsPii) => {
if (containsPii) return;
console.log(message);
},
logLevel: LogLevel.Error,
piiLoggingEnabled: false,

View file

@ -73,7 +73,6 @@ export function AuthProvider({ children }: { children: ReactNode }) {
// For persona creation errors, don't clear session or redirect
if (details.isPersonaCreation) {
import.meta.env.DEV && console.log('Ignoring auth error from persona creation', details);
return;
}
@ -87,9 +86,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
const handleWebSocketAuthError = (event: Event) => {
const customEvent = event as CustomEvent<any>;
const errorData = customEvent.detail || {};
import.meta.env.DEV && console.log('WebSocket authentication error:', errorData);
// Clear auth data and redirect to login
clearAuthData();
toast.error('Session expired', {
@ -132,30 +129,21 @@ export function AuthProvider({ children }: { children: ReactNode }) {
// Check if user is already logged in
const storedToken = localStorage.getItem('auth_token');
const storedUser = localStorage.getItem('user');
import.meta.env.DEV && console.log('AuthContext initializing - stored data check:', {
hasToken: !!storedToken,
hasUser: !!storedUser
});
if (storedToken && storedUser) {
// Check if token is expired
if (isTokenExpired(storedToken)) {
import.meta.env.DEV && console.log('Stored token is expired, clearing authentication data');
clearAuthData();
toast.error('Session expired', { description: 'Please log in again' });
} else {
try {
setToken(storedToken);
setUser(JSON.parse(storedUser));
import.meta.env.DEV && console.log('User session restored from localStorage');
} catch (error) {
console.error('Failed to parse stored user data:', error);
clearAuthData();
}
}
} else {
import.meta.env.DEV && console.log('No stored authentication data found');
}
setIsLoading(false);
@ -164,21 +152,17 @@ export function AuthProvider({ children }: { children: ReactNode }) {
// Verify token is valid by fetching user profile
useEffect(() => {
if (token) {
import.meta.env.DEV && console.log('Verifying token...');
// Set a flag to avoid unnecessary token validation on every render
const validationKey = `token_validated_${token.substring(0, 10)}`;
const alreadyValidated = sessionStorage.getItem(validationKey);
if (alreadyValidated === 'true' && user) {
import.meta.env.DEV && console.log('Token already validated this session, skipping validation');
return;
}
authApi.getProfile()
.then(response => {
if (response && 'data' in response) {
import.meta.env.DEV && console.log('Profile verified successfully');
setUser(response.data);
// Mark this token as validated for this session
sessionStorage.setItem(validationKey, 'true');
@ -196,19 +180,15 @@ export function AuthProvider({ children }: { children: ReactNode }) {
// Do not mark as validated on non-401 errors; allow retry on next render
}
});
} else {
import.meta.env.DEV && console.log('No token available, not validating profile');
}
}, [token, user]);
const login = async (username: string, password: string) => {
setIsLoading(true);
import.meta.env.DEV && console.log('Attempting login for user:', username);
try {
const response = await authApi.login(username, password);
import.meta.env.DEV && console.log('Login API response received');
if (!response.data.access_token) {
throw new Error('No access token received from server');
}
@ -220,8 +200,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
// Update state
setToken(response.data.access_token);
setUser(response.data.user);
import.meta.env.DEV && console.log('Authentication state updated');
toast.success('Login successful!');
// Return the token to indicate successful login
@ -240,7 +219,6 @@ export function AuthProvider({ children }: { children: ReactNode }) {
const loginWithMicrosoft = async () => {
setIsMsalLoading(true);
try {
import.meta.env.DEV && console.log('Starting Microsoft authentication (redirect)...');
await instance.loginRedirect(loginRequest);
// Page navigates away — execution stops here
} catch (error: any) {

View file

@ -585,7 +585,6 @@ export function usePersonaDetails() {
const data = response.data;
if (isMounted) {
console.log('Found persona in database:', data);
// If we get a valid response, use it
setCurrentPersona({
...data,
@ -687,8 +686,7 @@ export function usePersonaDetails() {
if (isExistingDbPersona && id && id.length === 24 && /^[0-9a-f]{24}$/i.test(id)) {
// Update existing database persona
const updateResult = await personasApi.update(id, personaToSend);
console.log('Updated persona in database:', updateResult);
// Update the local state with the edited persona
const updatedDbPersona = {
...updatedPersona,
@ -700,8 +698,7 @@ export function usePersonaDetails() {
} else {
// Create new persona in database
const createResponse = await personasApi.create(personaToSend);
console.log('Created new persona in database:', createResponse.data);
// Update the persona with database ID
const dbPersona = {
...updatedPersona,

View file

@ -20,8 +20,7 @@ export function usePersonaStorage() {
}
const result = await personasApi.create(personaToSave);
console.log('Persona saved to database:', result.data);
// Add the database ID to the persona
savedPersonas.push({
...persona,
@ -37,7 +36,6 @@ export function usePersonaStorage() {
const loadPersonas = async (): Promise<Persona[]> => {
const response = await personasApi.getAll();
if (response && response.data && Array.isArray(response.data)) {
console.log('Personas loaded from database:', response.data.length);
return response.data.map(p => ({
...p,
id: p._id || p.id,

View file

@ -33,7 +33,6 @@ export function useWebSocket(
): UseWebSocketReturn {
const instanceId = useRef(Math.random().toString(36).substr(2, 9));
console.log(`[WebSocket-${instanceId.current}] Hook initialized`);
const {
autoConnect = true,
maxReconnectAttempts = 5,
@ -52,10 +51,7 @@ export function useWebSocket(
const reconnectTimeoutRef = useRef<NodeJS.Timeout>();
const currentFocusGroupRef = useRef<string | null>(null);
const log = useCallback((message: string, ...args: any[]) => {
if (enableLogging) {
console.log(`[WebSocket-${instanceId.current}] ${message}`, ...args);
}
const log = useCallback((_message: string, ..._args: any[]) => {
}, [enableLogging]);
const updateState = useCallback((updates: Partial<WebSocketState>) => {
@ -175,14 +171,6 @@ export function useWebSocket(
// Disconnection
socket.on('disconnect', (reason) => {
log('Disconnected:', reason);
console.log(`🔌 [WebSocket-${instanceId.current}] DISCONNECT DEBUG:`, {
reason,
wasIntentional: reason === 'io client disconnect',
reconnectAttempts: state.reconnectAttempts,
maxAttempts: maxReconnectAttempts,
timestamp: new Date().toISOString()
});
updateState({
isConnected: false,
isConnecting: false,
@ -217,13 +205,6 @@ export function useWebSocket(
updateState({ error: error.message || 'WebSocket error occurred' });
});
// DEBUG: Listen for ALL events
const originalEmit = socket.onevent;
socket.onevent = function(packet) {
console.log(`🔥 [WebSocket-${instanceId.current}] RAW EVENT RECEIVED:`, packet);
return originalEmit.call(this, packet);
};
}, [token, log, updateState, maxReconnectAttempts, reconnectDelay, state.reconnectAttempts]);
const disconnect = useCallback(() => {

View file

@ -33,7 +33,6 @@ api.interceptors.request.use(
if (token) {
// Check if token is expired before making request
if (isTokenExpired(token)) {
import.meta.env.DEV && console.log('Token expired, clearing auth data before request');
localStorage.removeItem('auth_token');
localStorage.removeItem('user');
localStorage.removeItem('auth_type');
@ -48,27 +47,6 @@ api.interceptors.request.use(
config.headers.Authorization = `Bearer ${token}`;
}
if (import.meta.env.DEV) {
if (config.method === 'put' && config.url?.includes('/focus-groups/')) {
import.meta.env.DEV && console.log('🌐 API Request:', {
method: config.method,
url: config.url,
baseURL: config.baseURL,
fullURL: `${config.baseURL}${config.url}`,
data: config.data
});
}
if (config.url?.includes('/folders/')) {
import.meta.env.DEV && console.log('🌐 API Folder Request:', {
method: config.method,
url: config.url,
baseURL: config.baseURL,
fullURL: `${config.baseURL}${config.url}`,
data: config.data
});
}
}
return config;
},
(error) => Promise.reject(error)
@ -112,11 +90,6 @@ api.interceptors.response.use(
error.config.url?.includes('/personas/batch') ||
(error.config.method && error.config.url?.startsWith('/personas')));
import.meta.env.DEV && console.log('API Error:', {
url: error.config?.url,
method: error.config?.method,
isPersonaRequest: isPersonaRequest
});
// For persona-related requests, don't automatically log out
// Let the component handle the auth error
@ -163,7 +136,6 @@ export const personasApi = {
update: (id: string, personaData: any) => {
// Don't try to update with local-prefixed IDs - they won't work
if (id && id.startsWith('local-')) {
import.meta.env.DEV && console.log('Cannot update with local ID, creating new instead:', id);
return api.post('/personas', personaData);
}
return api.put(`/personas/${id}`, personaData);
@ -171,8 +143,6 @@ export const personasApi = {
modifyWithAI: (id: string, modificationData: any) => {
const personaId = typeof id === 'object' && id !== null ? (id as any)._id || id : id;
const mode = modificationData.preview_only ? 'Previewing' : 'Modifying';
import.meta.env.DEV && console.log(`${mode} persona with AI, ID: ${personaId}`);
return api.post(`/personas/${personaId}/modify-with-ai`, modificationData);
},
@ -181,7 +151,6 @@ export const personasApi = {
// If the ID is an object with an _id property, use that
// Otherwise, use the provided ID string
const personaId = typeof id === 'object' && id !== null ? (id as any)._id || id : id;
import.meta.env.DEV && console.log(`Deleting persona with ID: ${personaId}`);
return api.delete(`/personas/${personaId}`);
},
@ -295,10 +264,6 @@ export const aiPersonasApi = {
onTaskIdReceived?: (taskId: string) => void
) => {
try {
// Log the API call with model information
import.meta.env.DEV && console.log(`📡 API call to generate-basic-profiles with model: ${llmModel || 'gemini-2.5-pro'}`);
import.meta.env.DEV && console.log('🔥 onTaskIdReceived callback provided:', !!onTaskIdReceived);
// First stage: Generate basic profiles
const basicProfilesResponse = await api.post('/ai-personas/generate-basic-profiles', {
audience_brief: audienceBrief,
@ -311,26 +276,18 @@ export const aiPersonasApi = {
timeout: 180000 // 3 minutes for basic profile generation
});
import.meta.env.DEV && console.log('🔥 First stage response:', basicProfilesResponse.data);
const basicProfiles = basicProfilesResponse.data.profiles;
const taskId = basicProfilesResponse.data.task_id; // Extract task_id from first call
import.meta.env.DEV && console.log('🔥 Extracted taskId:', taskId);
// Call the callback immediately with the task ID
if (taskId && onTaskIdReceived) {
import.meta.env.DEV && console.log('🔥 Calling onTaskIdReceived with taskId:', taskId);
onTaskIdReceived(taskId);
} else {
import.meta.env.DEV && console.log('🔥 Not calling callback - taskId:', taskId, 'callback:', !!onTaskIdReceived);
}
const personas = [];
const personaIds = [];
const errors = [];
// Log the second stage API calls with model information
import.meta.env.DEV && console.log(`📡 API call to complete-and-save-persona with model: ${llmModel || 'gemini-2.5-pro'}`);
// Second stage: Complete each profile in parallel
const completeRequests = basicProfiles.map(profile =>
api.post('/ai-personas/complete-and-save-persona', {
@ -401,9 +358,6 @@ export const aiPersonasApi = {
// Batch generate summaries for download
batchGenerateSummaries: (personaIds: string[], temperature: number = 0.7, llmModel?: string) => {
// Log the API call with model information
import.meta.env.DEV && console.log(`📡 Frontend: API call to batch-generate-summaries with model: ${llmModel || 'gemini-2.5-pro'}`);
return api.post('/ai-personas/batch-generate-summaries', {
persona_ids: personaIds,
temperature,
@ -442,8 +396,6 @@ export const aiPersonasApi = {
llmModel?: string,
targetFolderId?: string
) => {
import.meta.env.DEV && console.log(`📡 API call to generate-personas-full with model: ${llmModel || 'gemini-2.5-pro'}`);
return api.post('/ai-personas/generate-personas-full', {
audience_brief: audienceBrief,
research_objective: researchObjective,
@ -717,8 +669,7 @@ export const foldersApi = {
api.post(`/folders/${folderId}/personas/batch`, { persona_ids: personaIds }),
removePersonasBatch: (folderId: string, personaIds: string[]) => {
import.meta.env.DEV && console.log(`🌐 API removePersonasBatch: Sending POST to /folders/${folderId}/personas/remove-batch with persona_ids:`, personaIds);
return api.post(`/folders/${folderId}/personas/remove-batch`, {
return api.post(`/folders/${folderId}/personas/remove-batch`, {
persona_ids: personaIds
});
},

View file

@ -142,7 +142,6 @@ const FocusGroupSession = () => {
// Initialize singleton socket (GPT-5 fix: avoid useMemo issues)
useEffect(() => {
if (useWebSocketEnabled) {
console.log('🔧 [GPT-5 Session] Initializing WebSocket');
initSocket(getAccessToken);
}
}, [useWebSocketEnabled, getAccessToken]);
@ -152,7 +151,6 @@ const FocusGroupSession = () => {
if (!useWebSocketEnabled || !id) return;
const tryJoin = () => {
console.log('🔧 [GPT-5 Session] Joining focus group:', id);
joinFocusGroup(id);
};
@ -184,19 +182,9 @@ const FocusGroupSession = () => {
useEffect(() => {
if (!useWebSocketEnabled) return;
console.log('🔧 [GPT-5 Session] Setting up window event listeners');
// Handle message updates
const onMessageUpdate = (e: CustomEvent) => {
const data = e.detail;
console.log('🔧 [GPT-5 Session] message_update:', data);
// Debug focus group filtering
if (data.focus_group_id) {
console.log('🔧 [GPT-5] Message focus_group_id:', data.focus_group_id);
console.log('🔧 [GPT-5] Current focus group from URL:', id);
}
const newMessage = convertWebSocketMessage(data.message);
if (!newMessage) {
console.error('🔧 [GPT-5] convertWebSocketMessage returned null');
@ -207,11 +195,9 @@ const FocusGroupSession = () => {
// Check for duplicates
const exists = prev.find(m => m.id === newMessage.id);
if (exists) {
console.log('🔧 [GPT-5] Message already exists, skipping');
return prev;
}
console.log('🔧 [GPT-5] Adding new message, count:', prev.length + 1);
return [...prev, newMessage];
});
};
@ -219,9 +205,7 @@ const FocusGroupSession = () => {
// Handle AI status updates - GPT-5 fix: functional state updates
const onAiStatusUpdate = (e: CustomEvent) => {
const data = e.detail;
console.log('🔧 [GPT-5 Session] ai_status_update:', data);
// GPT-5 fix: Use functional updates to prevent stale closures during AI mode
// GPT-5 fix: Use functional updates to prevent stale closures during AI mode
setIsAiModeActive(prev => data.status.status === 'ai_mode');
setSessionStatus(prev => data.status.status);
};
@ -229,14 +213,12 @@ const FocusGroupSession = () => {
// Handle moderator status updates
const onModeratorStatusUpdate = (e: CustomEvent) => {
const data = e.detail;
console.log('🔧 [GPT-5 Session] moderator_status_update:', data);
setModeratorStatus(data.moderator_status);
};
// Handle theme updates
const onThemeUpdate = (e: CustomEvent) => {
const data = e.detail;
console.log('🔧 [GPT-5 Session] theme_update:', data);
const theme = convertWebSocketTheme(data.theme);
setThemes(prev => {
@ -254,14 +236,12 @@ const FocusGroupSession = () => {
// Handle focus group updates
const onFocusGroupUpdate = (e: CustomEvent) => {
const data = e.detail;
console.log('🔧 [GPT-5 Session] focus_group_update:', data);
setFocusGroup(prev => prev ? { ...prev, ...data } : null);
};
// Handle mode event updates
const onModeEventUpdate = (e: CustomEvent) => {
const data = e.detail;
console.log('🔧 [GPT-5 Session] mode_event_update:', data);
// Convert timestamp to Date object
const modeEvent = {
@ -274,22 +254,17 @@ const FocusGroupSession = () => {
setModeEvents(prev => {
const existingIndex = prev.findIndex(event => event.id === modeEvent.id);
if (existingIndex >= 0) {
console.log('🔧 [GPT-5 Session] Mode event already exists, skipping:', modeEvent.id);
return prev; // Don't add duplicate
}
console.log('🔧 [GPT-5 Session] Adding new mode event:', modeEvent.id);
return [...prev, modeEvent];
});
};
// Handle room join confirmations
const onJoinedFocusGroup = (e: CustomEvent) => {
const data = e.detail;
console.log('🔧 [GPT-5 Session] joined_focus_group:', data);
const onJoinedFocusGroup = (_e: CustomEvent) => {
};
// Add window event listeners
console.log('🔧 [GPT-5 Session] ADDING window event listeners');
window.addEventListener('ws:message_update', onMessageUpdate as any);
window.addEventListener('ws:ai_status_update', onAiStatusUpdate as any);
window.addEventListener('ws:moderator_status_update', onModeratorStatusUpdate as any);
@ -297,11 +272,9 @@ const FocusGroupSession = () => {
window.addEventListener('ws:focus_group_update', onFocusGroupUpdate as any);
window.addEventListener('ws:mode_event_update', onModeEventUpdate as any);
window.addEventListener('ws:joined_focus_group', onJoinedFocusGroup as any);
console.log('🔧 [GPT-5 Session] ADDED all window event listeners');
// Cleanup window event listeners
return () => {
console.log('🔧 [GPT-5 Session] Cleaning up window event listeners');
window.removeEventListener('ws:message_update', onMessageUpdate as any);
window.removeEventListener('ws:ai_status_update', onAiStatusUpdate as any);
window.removeEventListener('ws:moderator_status_update', onModeratorStatusUpdate as any);
@ -564,7 +537,6 @@ const FocusGroupSession = () => {
try {
const response = await focusGroupsApi.getMessages(id);
console.log('🔍 [FetchMessages] Raw API response:', response?.data);
// Handle both old (array) and new (object with messages/mode_events) response formats
let messagesData: any[] = [];
@ -597,15 +569,6 @@ const FocusGroupSession = () => {
visualAsset: msg.visualAsset // Include visual asset metadata for image display
}));
console.log('🔍 [FetchMessages] Formatted messages with visual assets:',
formattedMessages.filter(m => m.visualAsset).map(m => ({
id: m.id,
senderId: m.senderId,
hasVisualAsset: !!m.visualAsset,
visualAsset: m.visualAsset
}))
);
// Convert dates and format mode events
const formattedModeEvents = modeEventsData.map((event: any) => ({
id: event._id || event.id || `event-${Date.now()}`,
@ -719,8 +682,7 @@ const FocusGroupSession = () => {
if (response && response.data) {
const data = response.data;
console.log("Focus group data from API:", data);
// Process focus group data
const focusGroupData = {
id: data._id || data.id,
@ -747,18 +709,12 @@ const FocusGroupSession = () => {
id: p._id || p.id
})));
} else if (focusGroupData.participants && Array.isArray(focusGroupData.participants)) {
console.log("Matching participants from DB:", {
focusGroupParticipants: focusGroupData.participants,
allPersonas: allPersonas.map(p => ({ id: p._id || p.id, name: p.name }))
});
// Otherwise use real personas from the database
const groupParticipants = allPersonas.filter(persona => {
const personaId = persona._id || persona.id;
return focusGroupData.participants.includes(personaId);
});
console.log("Matched participants:", groupParticipants.map(p => p.name));
setParticipants(groupParticipants);
}
@ -786,10 +742,7 @@ const FocusGroupSession = () => {
// Function to update the LLM model for this focus group
const updateFocusGroupModel = async (newModel: string, reasoningEffort?: string, verbosity?: string) => {
console.log('🔧 updateFocusGroupModel called with:', { id, focusGroup: !!focusGroup, newModel, reasoningEffort, verbosity });
if (!id || !focusGroup) {
console.log('❌ updateFocusGroupModel: Missing id or focusGroup', { id, focusGroup: !!focusGroup });
return;
}
@ -803,11 +756,8 @@ const FocusGroupSession = () => {
updateData.verbosity = verbosity || selectedVerbosity;
}
console.log('🔧 Making API call to update focus group model:', { id, updateData });
const response = await focusGroupsApi.update(id, updateData);
console.log('🔧 API response:', response);
if (response && response.data) {
setFocusGroup(prev => prev ? {
...prev,
@ -823,9 +773,6 @@ const FocusGroupSession = () => {
} for AI responses`
});
setShowModelSettings(false);
console.log('✅ Model update successful');
} else {
console.log('❌ API response missing data:', response);
}
} catch (error) {
console.error('❌ Error updating focus group model:', error);
@ -838,8 +785,6 @@ const FocusGroupSession = () => {
};
useEffect(() => {
console.log("Looking for focus group with ID:", id);
// Fetch all personas from the database first
const fetchAllPersonas = async () => {
try {
@ -858,8 +803,7 @@ const FocusGroupSession = () => {
if (response && response.data) {
const data = response.data;
console.log("Focus group data from API:", data);
// Process focus group data
const focusGroupData = {
id: data._id || data.id,
@ -886,18 +830,12 @@ const FocusGroupSession = () => {
id: p._id || p.id
})));
} else if (focusGroupData.participants && Array.isArray(focusGroupData.participants)) {
console.log("Matching participants from DB:", {
focusGroupParticipants: focusGroupData.participants,
allPersonas: allPersonas.map(p => ({ id: p._id || p.id, name: p.name }))
});
// Otherwise use real personas from the database
const groupParticipants = allPersonas.filter(persona => {
const personaId = persona._id || persona.id;
return focusGroupData.participants.includes(personaId);
});
console.log("Matched participants:", groupParticipants.map(p => p.name));
setParticipants(groupParticipants);
}
@ -928,7 +866,6 @@ const FocusGroupSession = () => {
const shouldUsePolling = !useWebSocketEnabled || (useWebSocketEnabled && wsConnectionFailed);
if (shouldUsePolling) {
console.log(useWebSocketEnabled ? '📡 WebSocket connection failed, falling back to polling' : '📡 WebSocket disabled, using polling for updates');
const startDynamicPolling = () => {
const pollMessages = () => {
fetchMessages();
@ -944,22 +881,12 @@ const FocusGroupSession = () => {
// Set new interval based on current AI mode status
const interval = isAiModeActive ? 3000 : 10000; // 3s when AI active, 10s when inactive
// DEBUG: Log polling setup
console.log('📡 Setting up message polling:', {
aiModeActive: isAiModeActive,
pollInterval: interval,
timestamp: new Date().toISOString()
});
messageRefreshInterval = window.setInterval(() => {
// Skip polling when editing discussion guide to prevent focus loss
if (!isEditingDiscussionGuideRef.current) {
console.log('📡 Polling for messages...', new Date().toISOString());
fetchMessages();
fetchModeratorStatus();
} else {
console.log('📡 Skipping poll - editing discussion guide');
}
}, interval);
};
@ -1003,8 +930,6 @@ const FocusGroupSession = () => {
};
startDynamicPolling();
} else {
console.log('📡 WebSocket enabled, skipping polling setup');
}
} else {
console.error("Focus group not found with ID:", id);
@ -1114,12 +1039,9 @@ const FocusGroupSession = () => {
const hasExistingPosition = currentStatus?.data?.status?.moderator_position;
if (!hasExistingPosition) {
await focusGroupAiApi.setModeratorPosition(id,
await focusGroupAiApi.setModeratorPosition(id,
focusGroup?.discussionGuide?.sections?.[0]?.id || 'welcome'
);
console.log('🚀 Moderator position initialized to start of discussion guide (first time)');
} else {
console.log('📍 Preserving existing moderator position:', hasExistingPosition);
}
} catch (error) {
console.warn('Failed to check/initialize moderator position:', error);
@ -1141,12 +1063,6 @@ const FocusGroupSession = () => {
type: 'question'
});
console.log('🚀 Initial moderator message created:', {
content: firstDiscussionItem.content,
sectionId: firstDiscussionItem.sectionId,
itemId: firstDiscussionItem.itemId
});
} catch (messageError) {
console.warn('Failed to create initial moderator message:', messageError);
// Don't fail the entire session start if message creation fails
@ -1196,11 +1112,9 @@ const FocusGroupSession = () => {
// Check for duplicates
const exists = prevMessages.find(m => m.id === message.id);
if (exists) {
console.log('🔧 [handleNewMessage] Message already exists, skipping:', message.id);
return prevMessages;
}
console.log('🔧 [handleNewMessage] Adding new message:', message.id);
return [...prevMessages, message];
});
};
@ -1227,8 +1141,6 @@ const FocusGroupSession = () => {
// Don't attempt to update local test messages in the database
if (!messageId.startsWith('local-') && !messageId.startsWith('msg-')) {
await focusGroupsApi.updateMessageHighlight(id, messageId, newHighlightState);
} else {
console.log('Skipping database update for local message:', messageId);
}
} catch (error) {
console.error('Error updating message highlight state:', error);
@ -1401,16 +1313,6 @@ const FocusGroupSession = () => {
}
if (matchingMessage) {
// Log successful match for debugging
console.log(`Quote match found using strategy: ${matchReason}`, {
quoteType: isQuoteData ? 'QuoteData' : 'string',
providedMessageId: messageId,
extractedText: quoteText,
matchedMessage: matchingMessage.text.substring(0, 100),
matchedMessageId: matchingMessage.id,
originalQuote: originalQuote.substring(0, 100)
});
// Switch to discussion tab
setActiveTab('chat');
@ -1509,12 +1411,6 @@ const FocusGroupSession = () => {
// Handler for saving discussion guide changes
const handleDiscussionGuideSave = useCallback(async (updatedGuide: any) => {
console.log('💾 handleDiscussionGuideSave called:', {
hasId: !!id,
isEditingGuideContent,
timestamp: new Date().toISOString()
});
if (!id) return;
try {
@ -1524,7 +1420,6 @@ const FocusGroupSession = () => {
// Only update local state if we're not currently editing to prevent focus loss
if (!isEditingGuideContent) {
console.log('🔄 Updating focus group state (not editing)');
setFocusGroup(prev => prev ? {
...prev,
discussionGuide: updatedGuide
@ -1537,7 +1432,6 @@ const FocusGroupSession = () => {
discussionGuide: updatedGuide
};
}
console.log('⚠️ Skipping focus group state update during editing to preserve focus');
}
} catch (error) {
@ -1548,19 +1442,12 @@ const FocusGroupSession = () => {
// Handle editing state changes from DiscussionGuideViewer
const handleGuideEditingStateChange = useCallback((editing: boolean) => {
console.log('🔄 handleGuideEditingStateChange called:', {
editing,
timestamp: new Date().toISOString(),
currentIsEditingGuideContent: isEditingGuideContent
});
// Update both editing states
setIsEditingDiscussionGuide(editing); // For scroll prevention
setIsEditingGuideContent(editing); // For focus preservation
// When editing ends, update the focus group state with the latest version
if (!editing && focusGroupRef.current) {
console.log('📝 Updating focus group state after editing ended');
setFocusGroup(focusGroupRef.current);
}
}, [isEditingGuideContent]);
@ -1586,8 +1473,6 @@ const FocusGroupSession = () => {
// Helper function to extract asset filename from creative review content
const extractAssetFilename = (content: string): string | null => {
console.log('🔍 EXTRACT ASSET FILENAME DEBUG - Input content:', content);
// Look for patterns like "titled 'filename.jpg'" or similar
const patterns = [
/'([^']*\.[a-zA-Z]{3,4})'/g, // 'filename.ext'
@ -1601,24 +1486,18 @@ const FocusGroupSession = () => {
for (let i = 0; i < patterns.length; i++) {
const pattern = patterns[i];
console.log(`🔍 Testing pattern ${i + 1}:`, pattern.source);
const matches = Array.from(content.matchAll(pattern));
console.log(`🔍 Pattern ${i + 1} matches:`, matches.length, matches);
if (matches.length > 0) {
// Get the first capture group from the first match
const filename = matches[0][1];
console.log(`🔍 Pattern ${i + 1} extracted filename:`, filename);
if (filename && filename.includes('.')) {
console.log('✅ EXTRACT ASSET FILENAME - Found:', filename);
return filename;
}
}
}
console.warn('❌ EXTRACT ASSET FILENAME - No filename found in content');
return null;
};
@ -2161,34 +2040,13 @@ const FocusGroupSession = () => {
const hasImageAttached = !!visualAsset?.filename;
const assetFilename = visualAsset?.filename;
console.log('🔍 MANUAL POSITION DEBUG:', {
itemType: setPositionDialog.itemType,
hasImageAttached,
visualAsset,
assetFilename,
content: setPositionDialog.content,
sectionTitle: setPositionDialog.sectionTitle,
itemTitle: setPositionDialog.itemTitle,
contentLength: setPositionDialog.content?.length
});
if (hasImageAttached && setPositionDialog.content && assetFilename) {
console.log('🔍 VISUAL ASSET DEBUG:', {
originalContent: setPositionDialog.content,
visualAsset,
displayReference: visualAsset?.display_reference,
filename: assetFilename,
contentLength: setPositionDialog.content.length
});
if (assetFilename) {
attachedAssets = [assetFilename];
activatesVisualContext = true;
console.log('🎨 MANUAL POSITION: Creative review detected, will activate visual context for:', assetFilename);
// Generate AI description and enhance the question
try {
console.log('🎨 MANUAL MODE: Requesting AI description for', assetFilename);
const descriptionResponse = await focusGroupsApi.describeAsset(id, assetFilename);
@ -2200,9 +2058,6 @@ const FocusGroupSession = () => {
`${displayRef} - ${descriptionResponse.data.description}`
);
console.log('✅ MANUAL MODE: Enhanced question with AI description');
console.log('🔍 Original:', setPositionDialog.content);
console.log('🔍 Enhanced:', enhancedMessageText);
}
} catch (descError) {
@ -2224,18 +2079,10 @@ const FocusGroupSession = () => {
description: 'Using original question text. Image will still be available to participants.'
});
}
} else {
console.warn('⚠️ MANUAL POSITION: Creative review detected but no asset filename extracted from content');
}
}
// Send the moderator message to API - it will be added back via websocket/polling with server timestamp
console.log('📤 Sending moderator message to API:', {
text: enhancedMessageText,
attachedAssets,
activatesVisualContext
});
try {
const msgResponse = await focusGroupsApi.sendMessage(id, {
senderId: 'moderator',
@ -2249,7 +2096,6 @@ const FocusGroupSession = () => {
} : undefined
});
console.log('✅ Message API call successful:', msgResponse?.data);
} catch (msgError) {
console.error('❌ Failed to save message to API:', msgError);
toastService.warning('Message not saved', {
@ -2260,10 +2106,6 @@ const FocusGroupSession = () => {
// Close dialog first for immediate feedback
setSetPositionDialog({ isOpen: false });
// Don't fetch moderator status immediately to avoid race condition
// The status will update via WebSocket or next polling cycle
console.log('✅ Set position complete, moderator message added to UI');
toastService.success('Moderator position set', {
description: `Position set to "${setPositionDialog.itemTitle}" in "${setPositionDialog.sectionTitle}"`
});
@ -2310,7 +2152,6 @@ const FocusGroupSession = () => {
<div>
<label className="text-sm font-medium">Select AI Model:</label>
<Select value={selectedModel} onValueChange={(value) => {
console.log('🔧 Model selection changed:', { from: selectedModel, to: value });
setSelectedModel(value);
}}>
<SelectTrigger className="mt-1">
@ -2387,18 +2228,8 @@ Controls how thoroughly GPT-5.2 thinks and how detailed responses are
>
Cancel
</Button>
<Button
<Button
onClick={() => {
console.log('🔧 Update button clicked:', {
selectedModel,
selectedReasoningEffort,
selectedVerbosity,
currentModel: focusGroup?.llm_model,
isDisabled: isUpdatingModel || (selectedModel === focusGroup?.llm_model &&
(selectedModel !== 'gpt-5.2' ||
(selectedReasoningEffort === focusGroup?.reasoning_effort &&
selectedVerbosity === focusGroup?.verbosity)))
});
updateFocusGroupModel(selectedModel, selectedReasoningEffort, selectedVerbosity);
}}
disabled={isUpdatingModel || (selectedModel === focusGroup?.llm_model &&

View file

@ -91,7 +91,6 @@ interface FocusGroup {
}
const FocusGroups = () => {
console.log('FocusGroups component rendering');
const [mode, setMode] = useState<'view' | 'create'>('view');
const [searchTerm, setSearchTerm] = useState('');
const [focusGroups, setFocusGroups] = useState<FocusGroup[]>([]);
@ -109,21 +108,14 @@ const FocusGroups = () => {
// Create a function to fetch focus groups that can be called when needed
const fetchFocusGroups = async (isMountedCheck = true) => {
console.log('fetchFocusGroups called with isMountedCheck:', isMountedCheck);
console.log('isMounted.current:', isMounted.current);
// Skip if component is not mounted (when called from useEffect cleanup)
if (isMountedCheck && !isMounted.current) {
console.log('Exiting early: component not mounted');
return;
}
console.log('Setting loading to true and making API call');
setIsLoading(true);
try {
console.log('Calling focusGroupsApi.getAll()');
const response = await focusGroupsApi.getAll();
console.log('API response received:', response);
if (!isMountedCheck || isMounted.current) {
// Process the data to ensure consistent format
const processedGroups = response.data.map((group: FocusGroup) => ({
@ -166,22 +158,18 @@ const FocusGroups = () => {
};
useEffect(() => {
console.log('useEffect running - about to fetch focus groups');
// Fetch focus groups on initial load
fetchFocusGroups();
// Cleanup function to prevent memory leaks
return () => {
console.log('useEffect cleanup - setting isMounted to false');
isMounted.current = false;
};
}, []);
// Refetch when mode changes from create back to view
useEffect(() => {
console.log('Mode change useEffect running, mode:', mode);
if (mode === 'view') {
console.log('Mode is view, calling fetchFocusGroups');
fetchFocusGroups();
}
}, [mode]);
@ -308,16 +296,13 @@ const FocusGroups = () => {
</div>
<div className="mt-4 sm:mt-0">
<Button
<Button
onClick={() => {
console.log('Create New Focus Group button clicked, current mode:', mode);
try {
if (mode === 'view') {
console.log('Setting draft to null and switching to create mode');
setDraftToEdit(null); // Clear any draft when creating new
setMode('create');
} else {
console.log('Switching back to view mode');
setMode('view');
}
} catch (error) {
@ -513,7 +498,6 @@ const FocusGroups = () => {
)}
onClick={() => {
const focusGroupId = group.id || group._id;
console.log("Navigating to focus group:", focusGroupId);
navigate(`/focus-groups/${focusGroupId}`);
}}
>

View file

@ -30,14 +30,10 @@ export default function Login() {
// Get the intended destination from state, or default to home page
const from = location.state?.from || '/';
// Debug the location state
console.log('Login page - destination path:', from);
// Redirect if already logged in
useEffect(() => {
if (isAuthenticated) {
console.log('User already authenticated, redirecting from login page');
navigate('/', { replace: true });
}
}, [isAuthenticated, navigate]);
@ -58,8 +54,6 @@ export default function Login() {
const token = await login(values.username, values.password);
if (token) {
console.log('Login successful, received token, navigating to:', from);
// Use React Router navigation to preserve state
navigate(from, { replace: true });
} else {

View file

@ -76,7 +76,6 @@ const SyntheticUsers = () => {
// Helper function ONLY to ensure the body is interactive - memoized with useCallback
const ensureBodyInteractive = useCallback(() => {
if (document.body.style.pointerEvents === 'none') {
console.log('ensureBodyInteractive: Fixing body pointer-events...'); // Optional log
document.body.style.pointerEvents = 'auto';
}
}, []); // Empty dependency array because it has no external dependencies
@ -320,7 +319,6 @@ const SyntheticUsers = () => {
try {
const loadStoredPersonas = async () => {
const storedPersonas = await loadPersonas();
console.log('Loaded stored personas (for debugging only):', storedPersonas ? storedPersonas.length : 0);
};
loadStoredPersonas();
} catch (e) {
@ -377,13 +375,6 @@ const SyntheticUsers = () => {
useEffect(() => {
if (mode === 'view') {
fetchPersonas();
} else if (mode === 'create') {
// Log selected folder when switching to create mode
console.log(`Switching to create mode with folder: ${selectedFolder}, ${selectedFolder !== DEFAULT_FOLDER_ID ? 'NOT default' : 'IS default'}`);
if (selectedFolder !== DEFAULT_FOLDER_ID) {
const folderName = folders.find(f => f.id === selectedFolder)?.name;
console.log(`Selected folder for creation: ${selectedFolder} (${folderName})`);
}
}
}, [mode]);
@ -397,21 +388,18 @@ const SyntheticUsers = () => {
// Create an event listener for route changes within the app
const handleRouteChange = () => {
// Check if we're on the synthetic users page
if (window.location.pathname.includes('/synthetic-users') &&
if (window.location.pathname.includes('/synthetic-users') &&
!window.location.pathname.includes('/synthetic-users/')) {
console.log('Navigation to synthetic users page detected, refreshing data');
fetchPersonas();
}
};
// Listen for the custom event from the Navigation component
const handleSyntheticUsersNavigation = () => {
console.log('Synthetic users navigation event detected, refreshing data');
fetchPersonas();
};
// --- ADD MutationObserver LOGIC ---
console.log('Setting up MutationObserver for body style');
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (
@ -420,7 +408,6 @@ const SyntheticUsers = () => {
document.body.style.pointerEvents === 'none'
) {
// Use the memoized function ensureBodyInteractive
console.log('MutationObserver detected pointer-events: none, fixing...');
ensureBodyInteractive();
}
});
@ -445,7 +432,6 @@ const SyntheticUsers = () => {
window.removeEventListener('syntheticUsersNavigation', handleSyntheticUsersNavigation);
// --- ADD Observer Cleanup ---
console.log('Disconnecting MutationObserver');
observer.disconnect();
// --- END ADD Observer Cleanup ---
};
@ -705,13 +691,6 @@ const SyntheticUsers = () => {
return persona?._id || persona?.id || personaId;
}).filter(Boolean);
console.log('Removing personas from folder:', {
selectedFolder,
selectedIds,
mongoIds,
folderName: folders.find(f => f._id === selectedFolder)?.name
});
try {
// Remove personas from the current folder using the batch API
await foldersApi.removePersonasBatch(selectedFolder, mongoIds);
@ -785,7 +764,6 @@ const SyntheticUsers = () => {
idToUse = persona._id.toString();
}
console.log(`Attempting to delete persona: ${idToUse}`);
await personasApi.delete(idToUse);
successfulDeletes.push(id);
} catch (error) {
@ -971,9 +949,6 @@ const SyntheticUsers = () => {
// Extract persona IDs, using _id for database personas or id as fallback
const personaIds = filteredPersonas.map(persona => persona._id || persona.id);
// Log user's model selection
console.log(`🤖 Frontend: User selected ${selectedDownloadLlmModel} for persona summary download`);
// Close modal
setDownloadLlmModalOpen(false);
@ -1969,10 +1944,7 @@ const SyntheticUsers = () => {
</TabsList>
<TabsContent value="ai">
{/* Log detailed info about the selected folder */}
{console.log(`Rendering AIRecruiter with targetFolderId: ${selectedFolder !== DEFAULT_FOLDER_ID ? selectedFolder : 'null'}`)}
{console.log(`Current folders:`, folders.map(f => ({ id: f.id, name: f.name })))}
<AIRecruiter
<AIRecruiter
targetFolderId={selectedFolder !== DEFAULT_FOLDER_ID ? selectedFolder : null}
targetFolderName={selectedFolder !== DEFAULT_FOLDER_ID ? folders.find(f => f.id === selectedFolder)?.name : null}
/>

View file

@ -79,13 +79,11 @@ export interface WebSocketEvents {
// Helper function to convert WebSocket message to frontend message format
export function convertWebSocketMessage(wsMessage: WebSocketEvents['message_update']['message']) {
console.log('🔍 [GPT-5 CONVERTER] Input wsMessage:', JSON.stringify(wsMessage, null, 2));
if (!wsMessage) {
console.error('🔍 [GPT-5 CONVERTER] ERROR: wsMessage is null/undefined');
return null;
}
const converted = {
id: wsMessage.id,
senderId: wsMessage.senderId,
@ -97,8 +95,7 @@ export function convertWebSocketMessage(wsMessage: WebSocketEvents['message_upda
activates_visual_context: wsMessage.activates_visual_context || false,
visualAsset: wsMessage.visualAsset
};
console.log('🔍 [GPT-5 CONVERTER] Output converted:', JSON.stringify(converted, null, 2));
return converted;
}
@ -174,7 +171,6 @@ export function getWebSocketUrl(): string {
// Add ?direct=1 to URL to test direct connection
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('direct') === '1') {
console.log('🔧 USING DIRECT WEBSOCKET CONNECTION (bypassing Apache)');
return 'https://optical-dev.oliver.solutions:5137';
}

View file

@ -96,8 +96,7 @@ export function initSocket(getToken: () => string): Socket {
console.error('[WebSocket] Connect error:', error.message);
});
socket.on("disconnect", (reason) => {
if (import.meta.env.DEV) console.log('[WebSocket] Disconnected:', reason);
socket.on("disconnect", (_reason) => {
});
return socket;

View file

@ -167,7 +167,6 @@ export class WebSocketTester {
messageTest: WebSocketTestResult;
metrics: WebSocketPerformanceMetrics;
}> {
console.log('🧪 Starting WebSocket test suite...');
const connectionTest = await this.testConnection(token);
let messageTest: WebSocketTestResult = {
@ -213,16 +212,6 @@ export class WebSocketTester {
* Log performance metrics
*/
private logPerformanceMetrics(): void {
console.log('📊 WebSocket Performance Metrics:', {
averageLatency: `${this.metrics.averageLatency.toFixed(2)}ms`,
connectionTime: `${this.metrics.connectionTime}ms`,
messagesSent: this.metrics.messagesSent,
messagesReceived: this.metrics.messagesReceived,
reconnections: this.metrics.reconnections,
errors: this.metrics.errors,
uptime: this.connectionStartTime ?
`${Math.round((Date.now() - this.connectionStartTime) / 1000)}s` : '0s'
});
}
/**
@ -277,17 +266,7 @@ export async function runWebSocketDiagnostics(token: string, focusGroupId: strin
return;
}
console.log('🔧 Running WebSocket diagnostics...');
const results = await websocketTester.runTestSuite(token, focusGroupId);
console.log('📋 WebSocket Test Results:', {
connection: results.connectionTest.success ? '✅ PASS' : '❌ FAIL',
message: results.messageTest.success ? '✅ PASS' : '❌ FAIL',
connectionLatency: results.connectionTest.latency ?
`${results.connectionTest.latency}ms` : 'N/A',
messageLatency: results.messageTest.latency ?
`${results.messageTest.latency}ms` : 'N/A'
});
if (!results.connectionTest.success) {
console.error('❌ Connection Error:', results.connectionTest.error);