Refactor ProgressModal and API logging

- Removed AI request logging from `autoGenerateIdeas`, `generateSingleIdea`, `autoGenerateContent`, and `autoGenerateImages` functions to streamline API calls.
- Updated `useProgressModal` to enhance step logging by directly processing request and response steps, improving clarity and performance.
- Cleaned up deprecated logging imports in `TablePageTemplate` to reflect the removal of frontend debug logging.
This commit is contained in:
Desktop
2025-11-10 23:55:12 +05:00
parent 14beeed75c
commit 727c999413
3 changed files with 32 additions and 336 deletions

View File

@@ -496,33 +496,6 @@ export function useProgressModal(): UseProgressModalReturn {
// Sort by step number and update state
allSteps.sort((a, b) => a.stepNumber - b.stepNumber);
setStepLogs(allSteps);
// Also update AI request logs store
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
const logs = useAIRequestLogsStore?.getState().logs || [];
const log = logs.find(l => l.response?.data?.task_id === taskId);
if (log) {
const addRequestStep = useAIRequestLogsStore?.getState().addRequestStep;
const addResponseStep = useAIRequestLogsStore?.getState().addResponseStep;
if (meta.request_steps && Array.isArray(meta.request_steps)) {
meta.request_steps.forEach((step: any) => {
// Only add if not already present
if (!log.requestSteps.find(s => s.stepNumber === step.stepNumber)) {
addRequestStep?.(log.id, step);
}
});
}
if (meta.response_steps && Array.isArray(meta.response_steps)) {
meta.response_steps.forEach((step: any) => {
// Only add if not already present
if (!log.responseSteps.find(s => s.stepNumber === step.stepNumber)) {
addResponseStep?.(log.id, step);
}
});
}
}
}
} else if (response.state === 'SUCCESS') {
const meta = response.meta || {};
@@ -586,32 +559,6 @@ export function useProgressModal(): UseProgressModalReturn {
// Sort by step number and update state
allSteps.sort((a, b) => a.stepNumber - b.stepNumber);
setStepLogs(allSteps);
// Also update AI request logs store
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
const logs = useAIRequestLogsStore?.getState().logs || [];
// Find log by task_id in response data or by matching the most recent log
const log = logs.find(l => l.response?.data?.task_id === taskId) || logs[0];
if (log) {
const addRequestStep = useAIRequestLogsStore?.getState().addRequestStep;
const addResponseStep = useAIRequestLogsStore?.getState().addResponseStep;
if (meta.request_steps && Array.isArray(meta.request_steps)) {
meta.request_steps.forEach((step: any) => {
if (!log.requestSteps.find(s => s.stepNumber === step.stepNumber)) {
addRequestStep?.(log.id, step);
}
});
}
if (meta.response_steps && Array.isArray(meta.response_steps)) {
meta.response_steps.forEach((step: any) => {
if (!log.responseSteps.find(s => s.stepNumber === step.stepNumber)) {
addResponseStep?.(log.id, step);
}
});
}
}
}
// Stop polling on SUCCESS
@@ -634,29 +581,40 @@ export function useProgressModal(): UseProgressModalReturn {
// Update step logs from failure response
if (meta.request_steps || meta.response_steps) {
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
const logs = useAIRequestLogsStore?.getState().logs || [];
const log = logs.find(l => l.response?.data?.task_id === taskId);
if (log) {
const addRequestStep = useAIRequestLogsStore?.getState().addRequestStep;
const addResponseStep = useAIRequestLogsStore?.getState().addResponseStep;
if (meta.request_steps && Array.isArray(meta.request_steps)) {
meta.request_steps.forEach((step: any) => {
if (!log.requestSteps.find(s => s.stepNumber === step.stepNumber)) {
addRequestStep?.(log.id, step);
}
const allSteps: Array<{
stepNumber: number;
stepName: string;
status: string;
message: string;
timestamp?: number;
}> = [];
if (meta.request_steps && Array.isArray(meta.request_steps)) {
meta.request_steps.forEach((step: any) => {
allSteps.push({
stepNumber: step.stepNumber || 0,
stepName: step.stepName || 'Unknown',
status: step.status || 'error',
message: step.message || '',
timestamp: step.timestamp,
});
}
if (meta.response_steps && Array.isArray(meta.response_steps)) {
meta.response_steps.forEach((step: any) => {
if (!log.responseSteps.find(s => s.stepNumber === step.stepNumber)) {
addResponseStep?.(log.id, step);
}
});
}
});
}
if (meta.response_steps && Array.isArray(meta.response_steps)) {
meta.response_steps.forEach((step: any) => {
allSteps.push({
stepNumber: step.stepNumber || 0,
stepName: step.stepName || 'Unknown',
status: step.status || 'error',
message: step.message || '',
timestamp: step.timestamp,
});
});
}
allSteps.sort((a, b) => a.stepNumber - b.stepNumber);
setStepLogs(allSteps);
}
// Stop polling on FAILURE

View File

@@ -596,165 +596,33 @@ export async function autoClusterKeywords(keywordIds: number[], sectorId?: numbe
}
export async function autoGenerateIdeas(clusterIds: number[]): Promise<{ success: boolean; task_id?: string; ideas_created?: number; message?: string; error?: string }> {
const startTime = Date.now();
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
const addLog = useAIRequestLogsStore?.getState().addLog;
const endpoint = `/v1/planner/clusters/auto_generate_ideas/`;
const requestBody = { ids: clusterIds };
addLog?.({
function: 'autoGenerateIdeas',
endpoint,
request: {
method: 'POST',
body: requestBody,
},
status: 'pending',
});
try {
const response = await fetchAPI(endpoint, {
method: 'POST',
body: JSON.stringify(requestBody),
});
const duration = Date.now() - startTime;
addLog({
function: 'autoGenerateIdeas',
endpoint,
request: {
method: 'POST',
body: requestBody,
},
response: {
status: 200,
data: response,
},
status: 'success',
duration,
});
return response;
} catch (error: any) {
const duration = Date.now() - startTime;
// Parse error message to extract error type
let errorType = 'UNKNOWN_ERROR';
let errorMessage = error.message || 'Unknown error';
if (errorMessage.includes('OperationalError')) {
errorType = 'DATABASE_ERROR';
errorMessage = errorMessage.replace(/API Error \(\d+\): /, '').replace(/ - .*OperationalError.*/, ' - Database operation failed');
} else if (errorMessage.includes('ValidationError')) {
errorType = 'VALIDATION_ERROR';
} else if (errorMessage.includes('PermissionDenied')) {
errorType = 'PERMISSION_ERROR';
} else if (errorMessage.match(/API Error \(\d+\): ([^-]+)/)) {
const match = errorMessage.match(/API Error \(\d+\): ([^-]+)/);
if (match) {
errorType = match[1].trim();
errorMessage = errorMessage.replace(/API Error \(\d+\): [^-]+ - /, '');
}
}
addLog?.({
function: 'autoGenerateIdeas',
endpoint,
request: {
method: 'POST',
body: requestBody,
},
response: {
status: 500,
error: errorMessage,
errorType,
},
status: 'error',
duration,
});
throw error;
}
}
export async function generateSingleIdea(ideaId: string | number, clusterId: number): Promise<{ success: boolean; task_id?: string; idea_created?: number; message?: string; error?: string }> {
const startTime = Date.now();
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
const addLog = useAIRequestLogsStore?.getState().addLog;
const endpoint = `/v1/planner/ideas/${ideaId}/generate_idea/`;
const requestBody = { cluster_id: clusterId };
addLog?.({
function: 'generateSingleIdea',
endpoint,
request: {
method: 'POST',
body: requestBody,
},
status: 'pending',
});
try {
const response = await fetchAPI(endpoint, {
method: 'POST',
body: JSON.stringify(requestBody),
});
const duration = Date.now() - startTime;
addLog?.({
function: 'generateSingleIdea',
endpoint,
request: {
method: 'POST',
body: requestBody,
},
response: {
status: 200,
data: response,
},
status: 'success',
duration,
});
return response;
} catch (error: any) {
const duration = Date.now() - startTime;
// Parse error message to extract error type
let errorType = 'UNKNOWN_ERROR';
let errorMessage = error.message || 'Unknown error';
if (errorMessage.includes('OperationalError')) {
errorType = 'DATABASE_ERROR';
errorMessage = errorMessage.replace(/API Error \(\d+\): /, '').replace(/ - .*OperationalError.*/, ' - Database operation failed');
} else if (errorMessage.includes('ValidationError')) {
errorType = 'VALIDATION_ERROR';
} else if (errorMessage.includes('PermissionDenied')) {
errorType = 'PERMISSION_ERROR';
} else if (errorMessage.match(/API Error \(\d+\): ([^-]+)/)) {
const match = errorMessage.match(/API Error \(\d+\): ([^-]+)/);
if (match) {
errorType = match[1].trim();
errorMessage = errorMessage.replace(/API Error \(\d+\): [^-]+ - /, '');
}
}
addLog?.({
function: 'generateSingleIdea',
endpoint,
request: {
method: 'POST',
body: requestBody,
},
response: {
status: 500,
error: errorMessage,
errorType,
},
status: 'error',
duration,
});
throw error;
}
}
@@ -1051,161 +919,33 @@ export async function bulkUpdateTasksStatus(ids: number[], status: string): Prom
}
export async function autoGenerateContent(ids: number[]): Promise<{ success: boolean; task_id?: string; tasks_updated?: number; message?: string; error?: string }> {
const startTime = Date.now();
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
const addLog = useAIRequestLogsStore?.getState().addLog;
const endpoint = `/v1/writer/tasks/auto_generate_content/`;
const requestBody = { ids };
addLog?.({
function: 'autoGenerateContent',
endpoint,
request: {
method: 'POST',
body: requestBody,
},
status: 'pending',
});
try {
const response = await fetchAPI(endpoint, {
method: 'POST',
body: JSON.stringify(requestBody),
});
const duration = Date.now() - startTime;
addLog({
function: 'autoGenerateContent',
endpoint,
request: {
method: 'POST',
body: requestBody,
},
response: {
status: 200,
data: response,
},
status: 'success',
duration,
});
return response;
} catch (error: any) {
const duration = Date.now() - startTime;
// Parse error message to extract error type
let errorType = 'UNKNOWN_ERROR';
let errorMessage = error.message || 'Unknown error';
if (errorMessage.includes('OperationalError')) {
errorType = 'DATABASE_ERROR';
errorMessage = errorMessage.replace(/API Error \(\d+\): /, '').replace(/ - .*OperationalError.*/, ' - Database operation failed');
} else if (errorMessage.includes('ValidationError')) {
errorType = 'VALIDATION_ERROR';
} else if (errorMessage.match(/API Error \(\d+\): ([^-]+)/)) {
const match = errorMessage.match(/API Error \(\d+\): ([^-]+)/);
if (match) {
errorType = match[1].trim();
errorMessage = errorMessage.replace(/API Error \(\d+\): [^-]+ - /, '');
}
}
addLog?.({
function: 'autoGenerateContent',
endpoint,
request: {
method: 'POST',
body: requestBody,
},
response: {
status: 500,
error: errorMessage,
errorType,
},
status: 'error',
duration,
});
throw error;
}
}
export async function autoGenerateImages(taskIds: number[]): Promise<{ success: boolean; task_id?: string; images_created?: number; message?: string; error?: string }> {
const startTime = Date.now();
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
const addLog = useAIRequestLogsStore?.getState().addLog;
const endpoint = `/v1/writer/tasks/auto_generate_images/`;
const requestBody = { task_ids: taskIds };
addLog?.({
function: 'autoGenerateImages',
endpoint,
request: {
method: 'POST',
body: requestBody,
},
status: 'pending',
});
try {
const response = await fetchAPI(endpoint, {
method: 'POST',
body: JSON.stringify(requestBody),
});
const duration = Date.now() - startTime;
addLog({
function: 'autoGenerateImages',
endpoint,
request: {
method: 'POST',
body: requestBody,
},
response: {
status: 200,
data: response,
},
status: 'success',
duration,
});
return response;
} catch (error: any) {
const duration = Date.now() - startTime;
// Parse error message to extract error type
let errorType = 'UNKNOWN_ERROR';
let errorMessage = error.message || 'Unknown error';
if (errorMessage.includes('OperationalError')) {
errorType = 'DATABASE_ERROR';
errorMessage = errorMessage.replace(/API Error \(\d+\): /, '').replace(/ - .*OperationalError.*/, ' - Database operation failed');
} else if (errorMessage.includes('ValidationError')) {
errorType = 'VALIDATION_ERROR';
} else if (errorMessage.match(/API Error \(\d+\): ([^-]+)/)) {
const match = errorMessage.match(/API Error \(\d+\): ([^-]+)/);
if (match) {
errorType = match[1].trim();
errorMessage = errorMessage.replace(/API Error \(\d+\): [^-]+ - /, '');
}
}
addLog?.({
function: 'autoGenerateImages',
endpoint,
request: {
method: 'POST',
body: requestBody,
},
response: {
status: 500,
error: errorMessage,
errorType,
},
status: 'error',
duration,
});
throw error;
}
}

View File

@@ -40,8 +40,6 @@ import BulkStatusUpdateModal from '../components/common/BulkStatusUpdateModal';
import { CompactPagination } from '../components/ui/pagination';
import SectorSelector from '../components/common/SectorSelector';
import { usePageSizeStore } from '../store/pageSizeStore';
// DEPRECATED: Frontend debug logging removed - now using backend console logging
// import { useAIRequestLogsStore } from '../store/aiRequestLogsStore';
import ToggleTableRow, { ToggleButton } from '../components/common/ToggleTableRow';
interface ColumnConfig {