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:
@@ -42,7 +42,7 @@ export interface IStorage {
|
||||
getUserWithOrganization(id: number): Promise<UserWithOrganization | undefined>;
|
||||
getUserByEmail(email: string, organizationId?: number): Promise<User | undefined>;
|
||||
getUserByEmailAndSlug(email: string, slug: string): Promise<UserWithOrganization | undefined>;
|
||||
getUsersByOrganization(organizationId: number): Promise<SafeUser[]>;
|
||||
getUsersByOrganization(organizationId: number, options?: { since?: Date }): Promise<SafeUser[]>;
|
||||
listUsers(organizationId: number, options?: import('./storage/users.storage').ListUsersOptions): Promise<import('./storage/users.storage').ListUsersResult>;
|
||||
getLinkedTasksForUser(userId: number, organizationId: number): Promise<
|
||||
Array<{
|
||||
@@ -182,7 +182,7 @@ export interface IStorage {
|
||||
} | null>;
|
||||
getTasksByForm(formId: number, organizationId: number): Promise<Task[]>;
|
||||
getTasksWithFieldsByForm(formId: number, organizationId: number): Promise<Task[]>;
|
||||
getTasksWithFieldsByFormOptimized(formId: number, organizationId: number, options?: { limit?: number; offset?: number; assignedTo?: number }): Promise<{ tasks: Task[]; total: number }>;
|
||||
getTasksWithFieldsByFormOptimized(formId: number, organizationId: number, options?: { limit?: number; offset?: number; assignedTo?: number; since?: Date }): Promise<{ tasks: Task[]; total: number }>;
|
||||
getTasksByOrganization(organizationId: number, options?: {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
@@ -191,7 +191,10 @@ export interface IStorage {
|
||||
statusId?: number;
|
||||
assignedTo?: number;
|
||||
minimal?: boolean;
|
||||
excludeDescription?: boolean;
|
||||
cursor?: import('./utils/task-pagination').TasksCursor | null;
|
||||
}): Promise<Task[] | Partial<Task>[]>;
|
||||
getTasksCountByOrganization(organizationId: number): Promise<number>;
|
||||
createTask(insertTask: InsertTask): Promise<Task>;
|
||||
updateTask(id: number, organizationId: number, updates: Partial<Task>): Promise<Task>;
|
||||
updateTaskIfNotModified(id: number, organizationId: number, updates: Partial<Task>, requiredUpdatedAt: Date): Promise<Task | null>;
|
||||
|
||||
Reference in New Issue
Block a user