perf(tasks): лимиты/пагинация /api/tasks и дельта-синк в SQL
Шаги 0.10 и 0.9 плана production-готовности: - дефолт limit 50, кап 200; списковые ответы без description - курсорная пагинация (updated_at, id) + nextCursor - since-фильтр дельта-синка перенесён в SQL (updated_at >= since) - embedding pre-count через COUNT(*) вместо выгрузки миллиона строк - 11 новых юнит-тестов (56/56 зелёные) Инвариант поиска сохранён: search-ветка /api/tasks?search= не изменена
This commit is contained in:
@@ -258,7 +258,6 @@ export function registerSyncRoutes(app: import("express").Express): void {
|
||||
const changedTasks: any[] = [];
|
||||
const changedFieldValues: any[] = [];
|
||||
const deletedTaskIds: number[] = [];
|
||||
const changedUsers: any[] = [];
|
||||
|
||||
for (const formId of accessibleFormIds) {
|
||||
const form = await storage.getForm(formId, organizationId);
|
||||
@@ -274,13 +273,13 @@ export function registerSyncRoutes(app: import("express").Express): void {
|
||||
|
||||
// Honor the form's offline-cache strategy for delta sync as well.
|
||||
const offlineCache = (form as any)?.offlineCache as { enabled?: boolean; strategy?: string; maxTasks?: number } | null | undefined;
|
||||
const taskOptions: { assignedTo?: number } = {};
|
||||
const taskOptions: { assignedTo?: number; since?: Date } = { since };
|
||||
if (offlineCache?.strategy === 'assigned') {
|
||||
taskOptions.assignedTo = userId;
|
||||
}
|
||||
// Фильтр по updated_at — на уровне SQL (раньше грузились ВСЕ задачи формы + JS-фильтр)
|
||||
const { tasks: formTasks } = await storage.getTasksWithFieldsByFormOptimized(formId, organizationId, taskOptions);
|
||||
const recentTasks = (formTasks as any[]).filter(t => !t.updatedAt || new Date(t.updatedAt) >= since);
|
||||
for (const task of recentTasks) {
|
||||
for (const task of formTasks as any[]) {
|
||||
const fieldValues = task.fieldValues || {};
|
||||
delete task.fieldValues;
|
||||
changedTasks.push(task);
|
||||
@@ -292,12 +291,8 @@ export function registerSyncRoutes(app: import("express").Express): void {
|
||||
// TODO: deleted tasks tracking через task_audit_log
|
||||
}
|
||||
|
||||
const allUsers = await storage.getUsersByOrganization(organizationId);
|
||||
for (const user of allUsers) {
|
||||
if (!user.updatedAt || new Date(user.updatedAt) >= since) {
|
||||
changedUsers.push(user);
|
||||
}
|
||||
}
|
||||
// Фильтр по updated_at — на уровне SQL (раньше: полная выгрузка + JS-фильтр)
|
||||
const changedUsers = await storage.getUsersByOrganization(organizationId, { since });
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
|
||||
Reference in New Issue
Block a user