Skip to content

Commit

Permalink
Feat: add task to a list while beautifying the task
Browse files Browse the repository at this point in the history
  • Loading branch information
saimanoj committed Mar 7, 2025
1 parent 64cc683 commit 8fea223
Show file tree
Hide file tree
Showing 19 changed files with 309 additions and 178 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- AlterEnum
ALTER TYPE "ModelName" ADD VALUE 'AgentWorklog';

-- CreateTable
CREATE TABLE "AgentWorklog" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"deleted" TIMESTAMP(3),
"modelName" TEXT NOT NULL,
"modelId" TEXT NOT NULL,
"state" TEXT NOT NULL,
"type" TEXT NOT NULL,

CONSTRAINT "AgentWorklog_pkey" PRIMARY KEY ("id")
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Warnings:
- Added the required column `workspaceId` to the `AgentWorklog` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "AgentWorklog" ADD COLUMN "workspaceId" TEXT NOT NULL;

-- AddForeignKey
ALTER TABLE "AgentWorklog" ADD CONSTRAINT "AgentWorklog_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
30 changes: 24 additions & 6 deletions apps/server/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,21 @@ model AIRequest {
successful Boolean @default(false)
}

model AgentWorklog {
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deleted DateTime?
modelName String
modelId String
state String
type String
workspace Workspace @relation(fields: [workspaceId], references: [id])
workspaceId String
}

model Attachment {
id String @id @default(uuid())
createdAt DateTime @default(now())
Expand Down Expand Up @@ -430,21 +445,24 @@ model Workspace {
aIRequest AIRequest[]
Prompt Prompt[]
List List[]
agentWorklog AgentWorklog[]
}

enum ModelName {
AgentWorklog
Attachment
Conversation
ConversationHistory
IntegrationAccount
IntegrationDefinitionV2
Task
List
Page
Status
SyncAction
Task
TaskOccurrence
User
Workspace
Page
Conversation
ConversationHistory
List
TaskOccurrence
}

enum ActionType {
Expand Down
32 changes: 23 additions & 9 deletions apps/server/src/modules/pages/pages.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,15 +416,29 @@ export class PagesService {
const endTime = new Date(pageDate);
endTime.setHours(23, 59, 59, 999);

await this.prisma.taskOccurrence.createMany({
data: addedTaskIds.map((taskId) => ({
taskId,
pageId,
workspaceId: page.workspaceId,
startTime,
endTime,
})),
});
await Promise.all(
addedTaskIds.map((taskId) =>
this.prisma.taskOccurrence.upsert({
where: {
taskId_pageId: {
taskId,
pageId,
},
},
create: {
taskId,
pageId,
workspaceId: page.workspaceId,
startTime,
endTime,
status: 'Todo',
},
update: {
deleted: null,
},
}),
),
);
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions apps/server/src/modules/replication/replication.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ export interface logType {
}

export const tablesToSendMessagesFor = new Map([
[ModelNameEnum.Workspace, true],
[ModelNameEnum.IntegrationAccount, true],
[ModelNameEnum.Page, true],
[ModelNameEnum.Task, true],
[ModelNameEnum.AgentWorklog, true],
[ModelNameEnum.Conversation, true],
[ModelNameEnum.ConversationHistory, true],
[ModelNameEnum.IntegrationAccount, true],
[ModelNameEnum.List, true],
[ModelNameEnum.Page, true],
[ModelNameEnum.Task, true],
[ModelNameEnum.TaskOccurrence, true],
[ModelNameEnum.Workspace, true],
]);

export const tableHooks = new Map([[ModelNameEnum.Page, true]]);
15 changes: 15 additions & 0 deletions apps/server/src/modules/sync-actions/sync-actions.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,19 @@ export async function getWorkspaceId(
});
return conversationHistoryEntity.conversation.workspaceId;

case ModelName.TaskOccurrence:
const taskOccurence = await prisma.taskOccurrence.findUnique({
where: { id: modelId },
});

return taskOccurence.workspaceId;

case ModelName.AgentWorklog:
const agentWorklog = await prisma.agentWorklog.findUnique({
where: { id: modelId },
});

return agentWorklog.workspaceId;
default:
return undefined;
}
Expand Down Expand Up @@ -116,6 +129,8 @@ export async function getModelData(
},
}),
},
TaskOccurence: prisma.taskOccurrence,
AgentWorklog: prisma.agentWorklog,
};

const model = modelMap[modelName];
Expand Down
82 changes: 57 additions & 25 deletions apps/server/src/modules/task-occurrence/task-occurrence.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,35 +203,67 @@ export class TaskOccurenceService {

async createTaskOccurenceByTask(taskId: string) {
const task = await this.prisma.task.findUnique({ where: { id: taskId } });
if (!task.recurrence || task.recurrence.length === 0 || !task.startTime) {
if (!task.recurrence.length && !task.startTime) {
return null;
}
const rrule = RRule.fromString(task.recurrence[0]);

// Set up the date range for next 2 days
const now = new Date();
const startDate = new Date(now);
const endDate = new Date(now);
endDate.setDate(endDate.getDate() + 30);
const taskStartTime = new Date(task.startTime);

// Get base occurrences for the date range
const baseOccurrences = rrule.between(startDate, endDate);
let futureOccurrences;
if (task.recurrence.length) {
// Set up the date range for next 30 days
const now = new Date();
const startDate = new Date(now);
const endDate = new Date(now);
endDate.setDate(endDate.getDate() + 30);

// Process all RRules and collect occurrences
let allOccurrences: Date[] = [];

for (const rruleString of task.recurrence) {
const rrule = RRule.fromString(rruleString);

// Get base occurrences for the date range from this rule
const baseOccurrences = rrule.between(startDate, endDate);

// Check if the RRule contains time information
const hasTimeInRRule =
rruleString.includes('BYHOUR') ||
rruleString.includes('BYMINUTE') ||
rruleString.includes('BYSECOND') ||
(rruleString.includes('DTSTART=') && rruleString.includes('T'));

// Map the base dates to include the correct time
const occurrences = baseOccurrences.map((date) => {
// If RRule already has time information, use it as is
if (hasTimeInRRule) {
return date;
}

// Otherwise, apply the time from task.startTime
const occurrence = new Date(date);
occurrence.setHours(
taskStartTime.getHours(),
taskStartTime.getMinutes(),
taskStartTime.getSeconds(),
taskStartTime.getMilliseconds(),
);
return occurrence;
});

const taskStartTime = new Date(task.startTime);
// Map the base dates to include the correct time from task.startTime
const occurrences = baseOccurrences.map((date) => {
const occurrence = new Date(date);
occurrence.setHours(
taskStartTime.getHours(),
taskStartTime.getMinutes(),
taskStartTime.getSeconds(),
taskStartTime.getMilliseconds(),
);
return occurrence;
});
// Add occurrences from this rule to the collection
allOccurrences = [...allOccurrences, ...occurrences];
}

// Filter out any occurrences that have already passed
futureOccurrences = allOccurrences.filter((date) => date > now);

// Sort occurrences by date
futureOccurrences.sort((a, b) => a.getTime() - b.getTime());
} else if (task.startTime) {
futureOccurrences = [task.startTime];
}

// Filter out any occurrences that have already passed
const futureOccurrences = occurrences.filter((date) => date > now);
if (futureOccurrences.length === 0) {
return [];
}
Expand Down Expand Up @@ -295,8 +327,6 @@ export class TaskOccurenceService {
});

// Step 4: Bulk upsert task occurrences
// Now we can use the enhanced map for more efficient operations

// Create a list of unique taskId_pageId combinations for upsert
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const upsertOperations = taskOccurrenceData.map((data: any) => {
Expand All @@ -317,6 +347,8 @@ export class TaskOccurenceService {
},
update: {
deleted: null,
startTime: data.startTime,
endTime: data.endTime,
},
});
});
Expand Down
10 changes: 5 additions & 5 deletions apps/server/src/modules/tasks-hook/tasks-hook.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export class TaskHooksService {
this.handleTitleChange(task, context),
this.handleDeleteTask(task, context),
this.handleScheduleTask(task, context),
this.handleBeautifyTask(task, context),
// this.handleCalendarTask(task, context),
// this.handleBeautifyTask(task, context),
// this.handleGenerateSummary(task, context),
]);
}
Expand Down Expand Up @@ -141,8 +141,8 @@ export class TaskHooksService {
if (
JSON.stringify(context.previousTask.recurrence) !==
JSON.stringify(task.recurrence) ||
task.startTime !== context.previousTask?.startTime ||
task.endTime !== context.previousTask?.endTime
String(task.startTime) !== String(context.previousTask?.startTime) ||
String(task.endTime) !== String(context.previousTask?.endTime)
) {
await this.taskOccurenceService.updateTaskOccurenceByTask(task.id);
}
Expand Down Expand Up @@ -176,8 +176,8 @@ export class TaskHooksService {
if (
JSON.stringify(context.previousTask.recurrence) !==
JSON.stringify(task.recurrence) ||
task.startTime !== context.previousTask?.startTime ||
task.endTime !== context.previousTask?.endTime
String(task.startTime) !== String(context.previousTask?.startTime) ||
String(task.endTime) !== String(context.previousTask?.endTime)
) {
await handleCalendarTask(
this.prisma,
Expand Down
24 changes: 0 additions & 24 deletions apps/server/src/modules/tasks/tasks-ai.controller.ts

This file was deleted.

52 changes: 0 additions & 52 deletions apps/server/src/modules/tasks/tasks-ai.service.ts

This file was deleted.

Loading

0 comments on commit 8fea223

Please sign in to comment.