widget leantime refactor
This commit is contained in:
parent
b4099d507e
commit
90bde85c5c
@ -23,10 +23,90 @@ interface TwentyTask {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Twenty CRM workspace member ID by email
|
||||
*/
|
||||
async function getTwentyCrmUserId(email: string): Promise<string | null> {
|
||||
try {
|
||||
if (!process.env.TWENTY_CRM_API_URL || !process.env.TWENTY_CRM_API_KEY) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const apiUrl = process.env.TWENTY_CRM_API_URL.endsWith('/graphql')
|
||||
? process.env.TWENTY_CRM_API_URL
|
||||
: `${process.env.TWENTY_CRM_API_URL}/graphql`;
|
||||
|
||||
// Query to find workspace member by email
|
||||
const query = `
|
||||
query GetWorkspaceMemberByEmail {
|
||||
workspaceMembers {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
user {
|
||||
email
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const response = await fetch(apiUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${process.env.TWENTY_CRM_API_KEY}`,
|
||||
},
|
||||
body: JSON.stringify({ query }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
logger.error('[TWENTY_CRM_TASKS] Failed to fetch workspace members', {
|
||||
status: response.status,
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.errors) {
|
||||
logger.error('[TWENTY_CRM_TASKS] GraphQL errors fetching workspace members', {
|
||||
errors: data.errors,
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
// Find workspace member with matching email
|
||||
const members = data.data?.workspaceMembers?.edges || [];
|
||||
const member = members.find((edge: any) =>
|
||||
edge.node?.user?.email?.toLowerCase() === email.toLowerCase()
|
||||
);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
logger.warn('[TWENTY_CRM_TASKS] Workspace member not found', {
|
||||
emailHash: Buffer.from(email.toLowerCase()).toString('base64').slice(0, 12),
|
||||
});
|
||||
return null;
|
||||
} catch (error) {
|
||||
logger.error('[TWENTY_CRM_TASKS] Error fetching workspace member', {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch tasks from Twenty CRM using GraphQL API
|
||||
*/
|
||||
async function fetchTwentyTasks(): Promise<TwentyTask[]> {
|
||||
async function fetchTwentyTasks(userId?: string): Promise<TwentyTask[]> {
|
||||
try {
|
||||
if (!process.env.TWENTY_CRM_API_URL) {
|
||||
logger.error('[TWENTY_CRM_TASKS] TWENTY_CRM_API_URL is not set in environment variables');
|
||||
@ -216,18 +296,40 @@ async function fetchTwentyTasks(): Promise<TwentyTask[]> {
|
||||
title: t.title,
|
||||
status: t.status,
|
||||
dueAt: t.dueAt,
|
||||
assigneeId: t.assigneeId,
|
||||
hasDueDate: !!t.dueAt,
|
||||
})),
|
||||
});
|
||||
|
||||
// Filter client-side for overdue tasks (dueAt < today) and not completed (status !== 'Done')
|
||||
// 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;
|
||||
});
|
||||
logger.error('[TWENTY_CRM_TASKS] Tasks after assignee filter', {
|
||||
before: allTasks.length,
|
||||
after: filteredByAssignee.length,
|
||||
userId,
|
||||
});
|
||||
}
|
||||
|
||||
// Filter client-side for overdue tasks (dueAt <= today) and not completed (status !== 'Done')
|
||||
// Use local date for comparison to avoid timezone issues
|
||||
const now = new Date();
|
||||
const todayYear = now.getFullYear();
|
||||
const todayMonth = now.getMonth();
|
||||
const todayDay = now.getDate();
|
||||
|
||||
const tasks: TwentyTask[] = allTasks
|
||||
const tasks: TwentyTask[] = filteredByAssignee
|
||||
.filter((task: TwentyTask) => {
|
||||
// Filter: only overdue tasks (dueAt < today) and not completed
|
||||
if (task.status === 'Done') {
|
||||
@ -311,7 +413,22 @@ export async function GET(request: NextRequest) {
|
||||
forceRefresh,
|
||||
});
|
||||
|
||||
const tasks = await fetchTwentyTasks();
|
||||
// Get Twenty CRM user ID from email
|
||||
const twentyCrmUserId = await getTwentyCrmUserId(session.user.email);
|
||||
|
||||
if (!twentyCrmUserId) {
|
||||
logger.warn('[TWENTY_CRM_TASKS] User not found in Twenty CRM, returning empty tasks', {
|
||||
emailHash: Buffer.from(session.user.email.toLowerCase()).toString('base64').slice(0, 12),
|
||||
});
|
||||
return NextResponse.json([]);
|
||||
}
|
||||
|
||||
logger.debug('[TWENTY_CRM_TASKS] Found Twenty CRM user ID', {
|
||||
userId: twentyCrmUserId,
|
||||
emailHash: Buffer.from(session.user.email.toLowerCase()).toString('base64').slice(0, 12),
|
||||
});
|
||||
|
||||
const tasks = await fetchTwentyTasks(twentyCrmUserId);
|
||||
|
||||
// Transform to match Leantime task format for consistency
|
||||
const transformedTasks = tasks.map((task) => ({
|
||||
|
||||
Loading…
Reference in New Issue
Block a user