feat: Enhance task filtering, smart scheduling, audit logs and translations
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
This commit is contained in:
+37
-3
@@ -32,7 +32,9 @@ export interface IStorage {
|
||||
createUserTaskAccess(access: InsertUserTaskAccess): Promise<UserTaskAccess>; // Alias
|
||||
|
||||
getSharedTasks(userId: string): Promise<SharedTask[]>; // Tasks shared WITH user
|
||||
getSharedTask(taskId: string, userId: string): Promise<SharedTask | undefined>; // Check specific share
|
||||
getUserTaskAccess(viewerId: string): Promise<UserTaskAccess[]>; // Access Viewer has to Owners
|
||||
checkUserTaskAccess(ownerId: string, viewerId: string): Promise<boolean>; // Check specific access
|
||||
getTaskSharedUsers(taskId: string): Promise<User[]>; // Get users a task is shared WITH
|
||||
unshareTask(taskId: string, userId: string): Promise<boolean>; // Unshare specific task from user
|
||||
|
||||
@@ -280,10 +282,18 @@ export class MemStorage implements IStorage {
|
||||
return Array.from(this.sharedTasks.values()).filter(st => st.sharedWithUserId === userId);
|
||||
}
|
||||
|
||||
async getSharedTask(taskId: string, userId: string): Promise<SharedTask | undefined> {
|
||||
return Array.from(this.sharedTasks.values()).find(st => st.taskId === taskId && st.sharedWithUserId === userId);
|
||||
}
|
||||
|
||||
async getUserTaskAccess(viewerId: string): Promise<UserTaskAccess[]> {
|
||||
return Array.from(this.userTaskAccess.values()).filter(uta => uta.viewerId === viewerId);
|
||||
}
|
||||
|
||||
async checkUserTaskAccess(ownerId: string, viewerId: string): Promise<boolean> {
|
||||
return Array.from(this.userTaskAccess.values()).some(uta => uta.ownerId === ownerId && uta.viewerId === viewerId);
|
||||
}
|
||||
|
||||
async getTaskSharedUsers(taskId: string): Promise<User[]> {
|
||||
const shares = Array.from(this.sharedTasks.values()).filter(st => st.taskId === taskId);
|
||||
const users: User[] = [];
|
||||
@@ -479,8 +489,13 @@ export class MemStorage implements IStorage {
|
||||
estimatedDuration: insertTask.estimatedDuration || null,
|
||||
parentTaskId: insertTask.parentTaskId || null,
|
||||
startDate: insertTask.startDate || null,
|
||||
dependencies: insertTask.dependencies || null,
|
||||
userId: insertTask.userId || null // Set ownership
|
||||
dependencies: insertTask.dependencies || [],
|
||||
userId: insertTask.userId || null, // Allow null for system/orphaned tasks support
|
||||
isRecurring: false,
|
||||
recurrenceInterval: null,
|
||||
recurrenceIntervalValue: 1,
|
||||
recurrenceDays: [],
|
||||
recurrenceEnd: null
|
||||
};
|
||||
this.tasks.set(id, task);
|
||||
return task;
|
||||
@@ -514,7 +529,8 @@ export class MemStorage implements IStorage {
|
||||
id,
|
||||
userId: event.userId || null,
|
||||
taskId: event.taskId || null,
|
||||
createdAt: new Date()
|
||||
createdAt: new Date(),
|
||||
details: event.details || null
|
||||
};
|
||||
this.xpEvents.set(id, xpEvent);
|
||||
// Also update user XP
|
||||
@@ -1085,10 +1101,28 @@ export class DbStorage implements IStorage {
|
||||
return await this.db.select().from(schema.sharedTasks).where(eq(schema.sharedTasks.sharedWithUserId, userId));
|
||||
}
|
||||
|
||||
async getSharedTask(taskId: string, userId: string): Promise<SharedTask | undefined> {
|
||||
const [share] = await this.db.select().from(schema.sharedTasks)
|
||||
.where(and(
|
||||
eq(schema.sharedTasks.taskId, taskId),
|
||||
eq(schema.sharedTasks.sharedWithUserId, userId)
|
||||
));
|
||||
return share;
|
||||
}
|
||||
|
||||
async getUserTaskAccess(viewerId: string): Promise<UserTaskAccess[]> {
|
||||
return await this.db.select().from(schema.userTaskAccess).where(eq(schema.userTaskAccess.viewerId, viewerId));
|
||||
}
|
||||
|
||||
async checkUserTaskAccess(ownerId: string, viewerId: string): Promise<boolean> {
|
||||
const [access] = await this.db.select().from(schema.userTaskAccess)
|
||||
.where(and(
|
||||
eq(schema.userTaskAccess.ownerId, ownerId),
|
||||
eq(schema.userTaskAccess.viewerId, viewerId)
|
||||
));
|
||||
return !!access;
|
||||
}
|
||||
|
||||
async getTaskSharedUsers(taskId: string): Promise<User[]> {
|
||||
const shares = await this.db.select().from(schema.sharedTasks).where(eq(schema.sharedTasks.taskId, taskId));
|
||||
if (shares.length === 0) return [];
|
||||
|
||||
Reference in New Issue
Block a user