Skip to content

Commit

Permalink
Fix: add due date, remind at in task
Browse files Browse the repository at this point in the history
  • Loading branch information
saimanoj committed Feb 8, 2025
1 parent 0fee730 commit 0df0840
Show file tree
Hide file tree
Showing 27 changed files with 1,177 additions and 30 deletions.
15 changes: 15 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,18 @@ PUBLIC_ATTACHMENT_URL=http://localhost:8000/api
# You can add your sentry to get the errors from the application
NEXT_PUBLIC_SENTRY_DSN=http://localhost:8000

############# Trigger.dev ###############
TRIGGER_PORT=3030
TRIGGER_COMMON_ID=clyofc7dn0000o33e4sup590l

TRIGGER_TOKEN=27192e6432564f4788d55c15131bd5ac
TRIGGER_ACCESS_TOKEN=tr_pat_${TRIGGER_TOKEN}
TRIGGER_API_URL=http://localhost:3030

TRIGGER_DB=trigger
TRIGGER_DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DB_HOST}/${TRIGGER_DB}

V3_ENABLED=true
HTTP_SERVER_PORT=9020
COORDINATOR_HOST=host.docker.internal
COORDINATOR_PORT=${HTTP_SERVER_PORT}
1 change: 1 addition & 0 deletions apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"execa": "^9.3.0",
"jsonwebtoken": "^9.0.2",
"jwks-rsa": "^3.1.0",
"knex": "^3.1.0",
"marked": "^14.1.2",
"nest-winston": "^1.9.7",
"nestjs-prisma": "0.22.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "Task" ADD COLUMN "dueDate" TIMESTAMP(3),
ADD COLUMN "remindAt" TIMESTAMP(3);
2 changes: 2 additions & 0 deletions apps/server/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ model Task {
endTime DateTime?
recurrence String[]
recurrenceText String?
dueDate DateTime?
remindAt DateTime?
page Page @relation(fields: [pageId], references: [id])
pageId String
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { ReplicationModule } from 'modules/replication/replication.module';
import { SyncActionsModule } from 'modules/sync-actions/sync-actions.module';
import { TaskOccurenceModule } from 'modules/task-occurence/task-occurence.model';
import { TasksModule } from 'modules/tasks/tasks.module';
import { TriggerdevModule } from 'modules/triggerdev/triggerdev.module';
import { UsersModule } from 'modules/users/users.module';
import { WebhookModule } from 'modules/webhook/webhook.module';
import { WorkspacesModule } from 'modules/workspaces/workspaces.module';
Expand Down Expand Up @@ -94,6 +95,7 @@ import { AppService } from './app.service';
TaskOccurenceModule,
AIRequestsModule,
PromptsModule,
TriggerdevModule,
],
controllers: [AppController],
providers: [
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/modules/tasks/tasks.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import AIRequestsService from 'modules/ai-requests/ai-requests.services';
import { ConversationModule } from 'modules/conversation/conversation.module';
import { IntegrationsService } from 'modules/integrations/integrations.service';
import { TaskOccurenceService } from 'modules/task-occurence/task-occurence.service';
import { TriggerdevService } from 'modules/triggerdev/triggerdev.service';
import { UsersService } from 'modules/users/users.service';

import { TasksAIController } from './tasks-ai.controller';
Expand All @@ -23,6 +24,7 @@ import { TasksService } from './tasks.service';
TasksAIService,
AIRequestsService,
IntegrationsService,
TriggerdevService,
],
exports: [TasksService],
})
Expand Down
16 changes: 16 additions & 0 deletions apps/server/src/modules/tasks/tasks.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { PrismaService } from 'nestjs-prisma';

import { IntegrationsService } from 'modules/integrations/integrations.service';
import { TaskOccurenceService } from 'modules/task-occurence/task-occurence.service';
import { Env } from 'modules/triggerdev/triggerdev.interface';
import { TriggerdevService } from 'modules/triggerdev/triggerdev.service';
import { UsersService } from 'modules/users/users.service';

import { handleCalendarTask } from './tasks.utils';

Expand All @@ -13,6 +16,8 @@ export class TasksService {
private prisma: PrismaService,
private taskOccurenceService: TaskOccurenceService,
private integrationService: IntegrationsService,
private triggerDevService: TriggerdevService,
private usersService: UsersService,
) {}

async getTaskBySourceId(sourceId: string): Promise<Task | null> {
Expand Down Expand Up @@ -141,6 +146,17 @@ export class TasksService {
);
}

const pat = this.usersService.getOrCreatePat(userId, workspaceId);
await this.triggerDevService.triggerTaskAsync(
'common',
'beautify-task',
{
taskId: task.id,
pat,
},
Env.PROD,
);

return task;
}

Expand Down
170 changes: 170 additions & 0 deletions apps/server/src/modules/triggerdev/trigger.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import { JsonValue } from '@sigma/types';

// Used to parse the logs - This is taken directly from the
// https://github.dev/triggerdotdev/trigger.dev - triggerdotdev/trigger.dev/apps/webapp/app/v3/eventRepository.server.ts,
// triggerdotdev/trigger.dev/apps/webapp/app/routes/resources.runs.$runParam.logs.download.ts

export const NULL_SENTINEL = '$@null((';

function rehydrateNull(value: any): any {
if (value === NULL_SENTINEL) {
return null;
}

return value;
}

export function unflattenAttributes(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
obj: any,
): Record<string, unknown> | string | number | boolean | null | undefined {
if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
return obj;
}

if (
typeof obj === 'object' &&
obj !== null &&
Object.keys(obj).length === 1 &&
Object.keys(obj)[0] === ''
) {
return rehydrateNull(obj['']) as any;
}

if (Object.keys(obj).length === 0) {
return {};
}

const result: Record<string, unknown> = {};

for (const [key, value] of Object.entries(obj)) {
const parts = key.split('.').reduce((acc, part) => {
if (part.includes('[')) {
// Handling nested array indices
const subparts = part.split(/\[|\]/).filter((p) => p !== '');
acc.push(...subparts);
} else {
acc.push(part);
}
return acc;
}, [] as string[]);

let current: any = result;
for (let i = 0; i < parts.length - 1; i++) {
const part = parts[i];
const nextPart = parts[i + 1];
const isArray = /^\d+$/.test(nextPart);
if (isArray && !Array.isArray(current[part])) {
current[part] = [];
} else if (!isArray && current[part] === undefined) {
current[part] = {};
}
current = current[part];
}
const lastPart = parts[parts.length - 1];
current[lastPart] = rehydrateNull(value);
}

// Convert the result to an array if all top-level keys are numeric indices
if (Object.keys(result).every((k) => /^\d+$/.test(k))) {
const maxIndex = Math.max(...Object.keys(result).map((k) => parseInt(k)));
const arrayResult = Array(maxIndex + 1);
for (const key in result) {
arrayResult[parseInt(key)] = result[key];
}
return arrayResult as any;
}

return result;
}

export function prepareEvent(event: any) {
return {
...event,
duration: Number(event.duration),
events: parseEventsField(event.events),
style: parseStyleField(event.style),
};
}

function parseEventsField(events: JsonValue) {
const unsafe = events
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
(events as unknown[]).map((e: any) => ({
...e,
properties: unflattenAttributes(e.properties),
}))
: undefined;

return unsafe;
}

function parseStyleField(style: JsonValue) {
const unsafe = unflattenAttributes(style);

if (!unsafe) {
return {};
}

if (typeof unsafe === 'object') {
return {
icon: undefined,
variant: undefined,
...unsafe,
};
}

return {};
}

export function getDateFromNanoseconds(nanoseconds: bigint) {
const time = Number(nanoseconds) / 1_000_000;
return new Date(time);
}

export function formatRunEvent(event: any): string {
const entries = [];
const parts: string[] = [];

parts.push(getDateFromNanoseconds(event.startTime).toISOString());

if (event.task_slug) {
parts.push(event.task_slug);
}

parts.push(event.level);
parts.push(event.message);

if (event.level === 'TRACE') {
parts.push(`(${getDateFromNanoseconds(event.duration)})`);
}

entries.push(parts.join(' '));

if (event.events) {
for (const subEvent of event.events) {
if (subEvent.name === 'exception') {
const subEventParts: string[] = [];

subEventParts.push(new Date(subEvent.time).toISOString());

if (event.task_slug) {
subEventParts.push(event.task_slug);
}

subEventParts.push(subEvent.name);
subEventParts.push(subEvent.properties.exception.message);

if (subEvent.properties.exception.stack) {
subEventParts.push(subEvent.properties.exception.stack);
}

entries.push(subEventParts.join(' '));
}
}
}

return entries.join('\n');
}
25 changes: 25 additions & 0 deletions apps/server/src/modules/triggerdev/triggerdev.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Controller, Get, UseGuards } from '@nestjs/common';

import { AuthGuard } from 'modules/auth/auth.guard';

import { TriggerdevService } from './triggerdev.service';

@Controller({
version: '1',
path: 'triggerdev',
})
export class TriggerdevController {
constructor(private triggerdevService: TriggerdevService) {}

@Get('docker-token')
@UseGuards(AuthGuard)
async getDockerToken() {
return this.triggerdevService.getDockerToken();
}

@Get()
@UseGuards(AuthGuard)
async getRequiredKeys() {
return this.triggerdevService.getRequiredKeys();
}
}
4 changes: 4 additions & 0 deletions apps/server/src/modules/triggerdev/triggerdev.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum Env {
DEV = 'dev',
PROD = 'prod',
}
15 changes: 15 additions & 0 deletions apps/server/src/modules/triggerdev/triggerdev.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Module } from '@nestjs/common';

import { UsersService } from 'modules/users/users.service';
import WorkspacesService from 'modules/workspaces/workspaces.service';

import { TriggerdevController } from './triggerdev.controller';
import { TriggerdevService } from './triggerdev.service';

@Module({
imports: [],
controllers: [TriggerdevController],
providers: [TriggerdevService, UsersService, WorkspacesService],
exports: [TriggerdevService],
})
export class TriggerdevModule {}
Loading

0 comments on commit 0df0840

Please sign in to comment.