feat: implement Phase 2 Core features for AutoScheduler GTD System

- ConnectWise Manage Integration:
  - ConnectWiseModule with service, controller, entity
  - API endpoints for connection CRUD and sync
  - Syncs service tickets, project tickets, zero-ticket projects
  - Stores ConnectWise priority/SLA in task metadata

- Intelligent Calendar Scheduling:
  - CalendarModule with connection and event entities
  - Support for CalDAV, Microsoft Graph, Google Calendar providers
  - CalendarService with sync methods for all providers
  - SchedulingModule with automatic scheduling engine
  - Finds available slots respecting working hours
  - Groups tasks by context, respects priority and due dates

- Interactive Calendar Week View:
  - FullCalendar with timeGridWeek view
  - Drag-and-drop task rescheduling
  - Tasks auto-lock when manually moved
  - Color-coded by context
  - Regenerate Schedule button

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-01-11 09:58:15 +00:00
parent e7ffcce768
commit 9c6b85f28a
29 changed files with 1863 additions and 47 deletions

View File

@@ -0,0 +1,59 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { User } from '../../users/entities/user.entity';
import { CalendarConnection } from './calendar-connection.entity';
import { CalendarProvider } from '@nick-tracker/shared-types';
@Entity('calendar_events')
export class CalendarEvent {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
externalId: string;
@Column()
title: string;
@Column({ type: 'timestamp' })
startTime: Date;
@Column({ type: 'timestamp' })
endTime: Date;
@Column({ default: false })
isAllDay: boolean;
@Column({
type: 'enum',
enum: CalendarProvider,
})
source: CalendarProvider;
@Column({ type: 'uuid' })
userId: string;
@ManyToOne(() => User, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'userId' })
user: User;
@Column({ type: 'uuid', nullable: true })
connectionId: string | null;
@ManyToOne(() => CalendarConnection, { onDelete: 'SET NULL' })
@JoinColumn({ name: 'connectionId' })
connection: CalendarConnection | null;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
}