Broaden Tasgird task lookup fallbacks
This commit is contained in:
@@ -533,16 +533,88 @@ app.get('/api/tasks/list', async (c) => {
|
||||
}
|
||||
|
||||
const baseFields = 'id,user,title,startDate,dueDate,priority,completed,content,size,status,owner,assigned_to,user_name,Username,expand.user.id,expand.user.email,expand.user.name,expand.user.username';
|
||||
const fetchTasksByRelationIds = async (userIds: string[]) => {
|
||||
const uniqueById = (records: any[]) => {
|
||||
const seen = new Map<string, any>();
|
||||
for (const record of Array.isArray(records) ? records : []) {
|
||||
const id = String(record?.id || '').trim();
|
||||
if (!id || seen.has(id)) continue;
|
||||
seen.set(id, record);
|
||||
}
|
||||
return Array.from(seen.values());
|
||||
};
|
||||
|
||||
const taskMatchesTarget = (task: any, userIds: string[], nameHints: string[]) => {
|
||||
const idSet = new Set(userIds.map((id) => String(id || '').trim()).filter(Boolean));
|
||||
const lowerHints = nameHints.map((value) => String(value || '').trim().toLowerCase()).filter(Boolean);
|
||||
|
||||
const directUsers = Array.isArray(task?.user)
|
||||
? task.user
|
||||
: (task?.user ? [task.user] : []);
|
||||
if (directUsers.some((value: any) => idSet.has(String(value || '').trim()))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const expandedUsers = Array.isArray(task?.expand?.user)
|
||||
? task.expand.user
|
||||
: (task?.expand?.user ? [task.expand.user] : []);
|
||||
if (expandedUsers.some((user: any) => idSet.has(String(user?.id || '').trim()))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const textFields = [task?.user_name, task?.Username, task?.owner, task?.assigned_to]
|
||||
.map((value) => String(value || '').trim().toLowerCase())
|
||||
.filter(Boolean);
|
||||
|
||||
return lowerHints.some((hint) => textFields.some((value) => value === hint || value.includes(hint)));
|
||||
};
|
||||
|
||||
const fetchTasksByRelationIds = async (userIds: string[], nameHints: string[]) => {
|
||||
const ids = Array.from(new Set(userIds.map((id) => String(id || '').trim()).filter(Boolean)));
|
||||
if (!ids.length) return [];
|
||||
const relationFilter = ids.map((id) => `user = "${id.replace(/"/g, '\\"')}"`).join(' || ');
|
||||
return taskPb.collection(PB_TASKS_COLLECTION).getFullList({
|
||||
filter: relationFilter,
|
||||
sort: '-startDate,-created',
|
||||
expand: 'user',
|
||||
fields: baseFields,
|
||||
});
|
||||
if (!ids.length) return { records: [], lookupMethod: 'no_user_ids' };
|
||||
|
||||
const filterAttempts = [
|
||||
{
|
||||
lookupMethod: 'relation_eq',
|
||||
filter: ids.map((id) => `user = "${id.replace(/"/g, '\\"')}"`).join(' || '),
|
||||
},
|
||||
{
|
||||
lookupMethod: 'relation_any_eq',
|
||||
filter: ids.map((id) => `user ?= "${id.replace(/"/g, '\\"')}"`).join(' || '),
|
||||
},
|
||||
];
|
||||
|
||||
let lastError: unknown = null;
|
||||
for (const attempt of filterAttempts) {
|
||||
try {
|
||||
const records = await taskPb.collection(PB_TASKS_COLLECTION).getFullList({
|
||||
filter: attempt.filter,
|
||||
sort: '-startDate,-created',
|
||||
expand: 'user',
|
||||
fields: baseFields,
|
||||
});
|
||||
if (records.length) {
|
||||
return { records: uniqueById(records), lookupMethod: attempt.lookupMethod };
|
||||
}
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const accessibleTasks = await taskPb.collection(PB_TASKS_COLLECTION).getFullList({
|
||||
sort: '-startDate,-created',
|
||||
expand: 'user',
|
||||
fields: baseFields,
|
||||
});
|
||||
const filtered = accessibleTasks.filter((task: any) => taskMatchesTarget(task, ids, nameHints));
|
||||
return {
|
||||
records: uniqueById(filtered),
|
||||
lookupMethod: 'accessible_fallback',
|
||||
};
|
||||
} catch (error) {
|
||||
if (lastError) throw lastError;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
const resolveUserIdsByName = async (name: string): Promise<string[]> => {
|
||||
@@ -587,6 +659,7 @@ app.get('/api/tasks/list', async (c) => {
|
||||
let warning = '';
|
||||
let effectiveUserId = requestedUserId || meId;
|
||||
let effectiveUserName = targetUserName;
|
||||
let lookupMethod = 'unresolved';
|
||||
try {
|
||||
if (targetUserName) {
|
||||
const targetUserIds = Array.from(new Set([
|
||||
@@ -598,7 +671,9 @@ app.get('/api/tasks/list', async (c) => {
|
||||
warning = `No Users record matched name "${targetUserName}".`;
|
||||
records = [];
|
||||
} else {
|
||||
records = await fetchTasksByRelationIds(targetUserIds);
|
||||
const result = await fetchTasksByRelationIds(targetUserIds, [targetUserName, meName]);
|
||||
records = result.records;
|
||||
lookupMethod = result.lookupMethod;
|
||||
if (!records.length) {
|
||||
warning = `No accessible Tasgird tasks matched Users.name "${targetUserName}".`;
|
||||
}
|
||||
@@ -606,7 +681,9 @@ app.get('/api/tasks/list', async (c) => {
|
||||
}
|
||||
} else if (requestedUserId || meId) {
|
||||
const fallbackId = String(requestedUserId || meId).trim();
|
||||
records = await fetchTasksByRelationIds([fallbackId]);
|
||||
const result = await fetchTasksByRelationIds([fallbackId], [meName]);
|
||||
records = result.records;
|
||||
lookupMethod = result.lookupMethod;
|
||||
if (!records.length) {
|
||||
warning = 'No accessible Tasgird tasks matched the current user relation.';
|
||||
}
|
||||
@@ -628,7 +705,13 @@ app.get('/api/tasks/list', async (c) => {
|
||||
success: true,
|
||||
userId: effectiveUserId,
|
||||
userName: effectiveUserName,
|
||||
authUser: {
|
||||
id: meId,
|
||||
email: meRecord?.email || '',
|
||||
name: meName,
|
||||
},
|
||||
count: records.length,
|
||||
lookupMethod,
|
||||
warning: warning || undefined,
|
||||
tasks: records.map((task: any) => ({
|
||||
id: task.id,
|
||||
|
||||
Reference in New Issue
Block a user