Fondation
This commit is contained in:
parent
0bfa26838a
commit
c341468996
@ -68,7 +68,6 @@ async function getLeantimeUserId(email: string): Promise<number | null> {
|
||||
|
||||
if (user) {
|
||||
logger.debug('[LEANTIME_TASKS] Found Leantime user', {
|
||||
id: user.id,
|
||||
emailHash: Buffer.from(email.toLowerCase()).toString('base64').slice(0, 12),
|
||||
});
|
||||
} else {
|
||||
@ -102,7 +101,7 @@ export async function GET(request: NextRequest) {
|
||||
const cachedTasks = await getCachedTasksData(session.user.id);
|
||||
if (cachedTasks) {
|
||||
logger.debug('[LEANTIME_TASKS] Using cached tasks data', {
|
||||
userId: session.user.id,
|
||||
emailHash: Buffer.from(session.user.email.toLowerCase()).toString('base64').slice(0, 12),
|
||||
taskCount: Array.isArray(cachedTasks) ? cachedTasks.length : undefined,
|
||||
});
|
||||
return NextResponse.json(cachedTasks);
|
||||
@ -121,8 +120,8 @@ export async function GET(request: NextRequest) {
|
||||
return NextResponse.json({ error: "User not found in Leantime" }, { status: 404 });
|
||||
}
|
||||
|
||||
logger.debug('[LEANTIME_TASKS] Fetching tasks for Leantime user ID', {
|
||||
userId,
|
||||
logger.debug('[LEANTIME_TASKS] Fetching tasks for Leantime user', {
|
||||
emailHash: Buffer.from(session.user.email.toLowerCase()).toString('base64').slice(0, 12),
|
||||
});
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
@ -115,7 +115,6 @@ async function getTwentyCrmUserId(email: string): Promise<string | null> {
|
||||
|
||||
if (member) {
|
||||
logger.debug('[TWENTY_CRM_TASKS] Found workspace member', {
|
||||
memberId: member.node.id,
|
||||
emailHash: Buffer.from(email.toLowerCase()).toString('base64').slice(0, 12),
|
||||
});
|
||||
return member.node.id;
|
||||
@ -230,12 +229,11 @@ async function fetchTwentyTasks(userId?: string): Promise<TwentyTask[]> {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Log raw response for debugging (using error level to ensure visibility)
|
||||
logger.error('[TWENTY_CRM_TASKS] Raw GraphQL response', {
|
||||
// Log raw response metadata (no sensitive data)
|
||||
logger.debug('[TWENTY_CRM_TASKS] Raw GraphQL response received', {
|
||||
hasData: !!data.data,
|
||||
dataKeys: data.data ? Object.keys(data.data) : [],
|
||||
tasksEdgesCount: data.data?.tasks?.edges?.length || 0,
|
||||
sampleResponse: JSON.stringify(data.data).substring(0, 1000),
|
||||
});
|
||||
|
||||
// Try different possible response structures
|
||||
@ -270,21 +268,12 @@ async function fetchTwentyTasks(userId?: string): Promise<TwentyTask[]> {
|
||||
if (!activitiesData) {
|
||||
logger.warn('[TWENTY_CRM_TASKS] Unexpected response format from Twenty CRM', {
|
||||
dataKeys: Object.keys(data.data || {}),
|
||||
fullData: JSON.stringify(data.data).substring(0, 2000),
|
||||
});
|
||||
return [];
|
||||
}
|
||||
|
||||
logger.debug('[TWENTY_CRM_TASKS] Activities data extracted', {
|
||||
count: activitiesData.length,
|
||||
sample: activitiesData.length > 0 ? {
|
||||
firstTask: {
|
||||
id: activitiesData[0]?.node?.id || activitiesData[0]?.id,
|
||||
title: activitiesData[0]?.node?.title || activitiesData[0]?.title,
|
||||
status: activitiesData[0]?.node?.status || activitiesData[0]?.status,
|
||||
dueAt: activitiesData[0]?.node?.dueAt || activitiesData[0]?.dueAt,
|
||||
}
|
||||
} : null,
|
||||
});
|
||||
|
||||
// Transform Twenty CRM tasks to match our Task interface
|
||||
@ -318,37 +307,20 @@ async function fetchTwentyTasks(userId?: string): Promise<TwentyTask[]> {
|
||||
};
|
||||
});
|
||||
|
||||
// Log all tasks before filtering for debugging (using error level to ensure visibility)
|
||||
logger.error('[TWENTY_CRM_TASKS] All tasks before filtering', {
|
||||
// Log task count before filtering (no sensitive data)
|
||||
logger.debug('[TWENTY_CRM_TASKS] Tasks before filtering', {
|
||||
count: allTasks.length,
|
||||
tasks: allTasks.map(t => ({
|
||||
id: t.id,
|
||||
title: t.title,
|
||||
status: t.status,
|
||||
dueAt: t.dueAt,
|
||||
assigneeId: t.assigneeId,
|
||||
hasDueDate: !!t.dueAt,
|
||||
})),
|
||||
});
|
||||
|
||||
// Filter by assignee if userId is provided
|
||||
let filteredByAssignee = allTasks;
|
||||
if (userId) {
|
||||
filteredByAssignee = allTasks.filter((task: TwentyTask) => {
|
||||
const isAssignedToUser = task.assigneeId === userId;
|
||||
if (!isAssignedToUser) {
|
||||
logger.debug('[TWENTY_CRM_TASKS] Filtering out task not assigned to user', {
|
||||
id: task.id,
|
||||
assigneeId: task.assigneeId,
|
||||
userId,
|
||||
});
|
||||
}
|
||||
return isAssignedToUser;
|
||||
return task.assigneeId === userId;
|
||||
});
|
||||
logger.error('[TWENTY_CRM_TASKS] Tasks after assignee filter', {
|
||||
logger.debug('[TWENTY_CRM_TASKS] Tasks after assignee filter', {
|
||||
before: allTasks.length,
|
||||
after: filteredByAssignee.length,
|
||||
userId,
|
||||
});
|
||||
}
|
||||
|
||||
@ -363,12 +335,10 @@ async function fetchTwentyTasks(userId?: string): Promise<TwentyTask[]> {
|
||||
.filter((task: TwentyTask) => {
|
||||
// Filter: only overdue tasks (dueAt < today) and not completed
|
||||
if (task.status === 'Done') {
|
||||
logger.debug('[TWENTY_CRM_TASKS] Filtering out Done task', { id: task.id, status: task.status });
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!task.dueAt) {
|
||||
logger.debug('[TWENTY_CRM_TASKS] Filtering out task without due date', { id: task.id });
|
||||
return false; // Exclude tasks without due date
|
||||
}
|
||||
|
||||
@ -386,14 +356,6 @@ async function fetchTwentyTasks(userId?: string): Promise<TwentyTask[]> {
|
||||
(taskYear === todayYear && taskMonth < todayMonth) ||
|
||||
(taskYear === todayYear && taskMonth === todayMonth && taskDay <= todayDay);
|
||||
|
||||
logger.error('[TWENTY_CRM_TASKS] Task date check', {
|
||||
id: task.id,
|
||||
dueAt: task.dueAt,
|
||||
taskDate: `${taskYear}-${String(taskMonth + 1).padStart(2, '0')}-${String(taskDay).padStart(2, '0')}`,
|
||||
todayDate: `${todayYear}-${String(todayMonth + 1).padStart(2, '0')}-${String(todayDay).padStart(2, '0')}`,
|
||||
isOverdueOrDueToday,
|
||||
});
|
||||
|
||||
return isOverdueOrDueToday; // Include overdue tasks and tasks due today
|
||||
})
|
||||
.sort((a: TwentyTask, b: TwentyTask) => {
|
||||
@ -406,12 +368,6 @@ async function fetchTwentyTasks(userId?: string): Promise<TwentyTask[]> {
|
||||
|
||||
logger.debug('[TWENTY_CRM_TASKS] Tasks after filtering', {
|
||||
count: tasks.length,
|
||||
tasks: tasks.map(t => ({
|
||||
id: t.id,
|
||||
title: t.title,
|
||||
status: t.status,
|
||||
dueAt: t.dueAt,
|
||||
})),
|
||||
});
|
||||
|
||||
logger.debug('[TWENTY_CRM_TASKS] Successfully fetched tasks from Twenty CRM', {
|
||||
@ -463,7 +419,6 @@ export async function GET(request: NextRequest) {
|
||||
}
|
||||
|
||||
logger.debug('[TWENTY_CRM_TASKS] Found Twenty CRM user ID', {
|
||||
userId: twentyCrmUserId,
|
||||
emailHash: Buffer.from(session.user.email.toLowerCase()).toString('base64').slice(0, 12),
|
||||
});
|
||||
|
||||
|
||||
43
lib/redis.ts
43
lib/redis.ts
@ -1,5 +1,6 @@
|
||||
import Redis from 'ioredis';
|
||||
import CryptoJS from 'crypto-js';
|
||||
import { logger } from './logger';
|
||||
|
||||
// Initialize Redis client
|
||||
let redisClient: Redis | null = null;
|
||||
@ -518,9 +519,14 @@ export async function cacheCalendarData(
|
||||
|
||||
try {
|
||||
await redis.set(key, JSON.stringify(data), 'EX', TTL.CALENDAR);
|
||||
console.log(`Calendar data cached for user ${userId}`);
|
||||
logger.debug('[REDIS] Calendar data cached', {
|
||||
userIdHash: Buffer.from(userId).toString('base64').slice(0, 12),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Error caching calendar data for user ${userId}:`, error);
|
||||
logger.error('[REDIS] Error caching calendar data', {
|
||||
userIdHash: Buffer.from(userId).toString('base64').slice(0, 12),
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -641,9 +647,14 @@ export async function cacheTasksData(
|
||||
|
||||
try {
|
||||
await redis.set(key, JSON.stringify(data), 'EX', TTL.TASKS);
|
||||
console.log(`Tasks data cached for user ${userId}`);
|
||||
logger.debug('[REDIS] Tasks data cached', {
|
||||
userIdHash: Buffer.from(userId).toString('base64').slice(0, 12),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Error caching tasks data for user ${userId}:`, error);
|
||||
logger.error('[REDIS] Error caching tasks data', {
|
||||
userIdHash: Buffer.from(userId).toString('base64').slice(0, 12),
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -664,7 +675,10 @@ export async function getCachedTasksData(
|
||||
|
||||
return JSON.parse(cachedData);
|
||||
} catch (error) {
|
||||
console.error(`Error getting cached tasks data for user ${userId}:`, error);
|
||||
logger.error('[REDIS] Error getting cached tasks data', {
|
||||
userIdHash: Buffer.from(userId).toString('base64').slice(0, 12),
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -680,9 +694,14 @@ export async function invalidateTasksCache(
|
||||
|
||||
try {
|
||||
await redis.del(key);
|
||||
console.log(`Tasks cache invalidated for user ${userId}`);
|
||||
logger.debug('[REDIS] Tasks cache invalidated', {
|
||||
userIdHash: Buffer.from(userId).toString('base64').slice(0, 12),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Error invalidating tasks cache for user ${userId}:`, error);
|
||||
logger.error('[REDIS] Error invalidating tasks cache', {
|
||||
userIdHash: Buffer.from(userId).toString('base64').slice(0, 12),
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -698,10 +717,14 @@ export async function cacheMessagesData(
|
||||
|
||||
try {
|
||||
await redis.set(key, JSON.stringify(data), 'EX', TTL.MESSAGES);
|
||||
// Debug-only; safe to be silent in production
|
||||
// logger.debug('[REDIS] Messages data cached', { userId });
|
||||
logger.debug('[REDIS] Messages data cached', {
|
||||
userIdHash: Buffer.from(userId).toString('base64').slice(0, 12),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Error caching messages data for user ${userId}:`, error);
|
||||
logger.error('[REDIS] Error caching messages data', {
|
||||
userIdHash: Buffer.from(userId).toString('base64').slice(0, 12),
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user