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

94
package-lock.json generated
View File

@@ -677,7 +677,6 @@
"version": "7.28.4",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
"integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
@@ -1437,6 +1436,51 @@
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="
},
"node_modules/@fullcalendar/core": {
"version": "6.1.20",
"resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.20.tgz",
"integrity": "sha512-1cukXLlePFiJ8YKXn/4tMKsy0etxYLCkXk8nUCFi11nRONF2Ba2CD5b21/ovtOO2tL6afTJfwmc1ed3HG7eB1g==",
"dependencies": {
"preact": "~10.12.1"
}
},
"node_modules/@fullcalendar/daygrid": {
"version": "6.1.20",
"resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.20.tgz",
"integrity": "sha512-AO9vqhkLP77EesmJzuU+IGXgxNulsA8mgQHynclJ8U70vSwAVnbcLG9qftiTAFSlZjiY/NvhE7sflve6cJelyQ==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.20"
}
},
"node_modules/@fullcalendar/interaction": {
"version": "6.1.20",
"resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.20.tgz",
"integrity": "sha512-p6txmc5txL0bMiPaJxe2ip6o0T384TyoD2KGdsU6UjZ5yoBlaY+dg7kxfnYKpYMzEJLG58n+URrHr2PgNL2fyA==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.20"
}
},
"node_modules/@fullcalendar/react": {
"version": "6.1.20",
"resolved": "https://registry.npmjs.org/@fullcalendar/react/-/react-6.1.20.tgz",
"integrity": "sha512-1w0pZtceaUdfAnxMSCGHCQalhi+mR1jOe76sXzyAXpcPz/Lf0zHSdcGK/U2XpZlnQgQtBZW+d+QBnnzVQKCxAA==",
"peerDependencies": {
"@fullcalendar/core": "~6.1.20",
"react": "^16.7.0 || ^17 || ^18 || ^19",
"react-dom": "^16.7.0 || ^17 || ^18 || ^19"
}
},
"node_modules/@fullcalendar/timegrid": {
"version": "6.1.20",
"resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.20.tgz",
"integrity": "sha512-4H+/MWbz3ntA50lrPif+7TsvMeX3R1GSYjiLULz0+zEJ7/Yfd9pupZmAwUs/PBpA6aAcFmeRr0laWfcz1a9V1A==",
"dependencies": {
"@fullcalendar/daygrid": "~6.1.20"
},
"peerDependencies": {
"@fullcalendar/core": "~6.1.20"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
@@ -2143,6 +2187,32 @@
"node-pre-gyp": "bin/node-pre-gyp"
}
},
"node_modules/@microsoft/microsoft-graph-client": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/@microsoft/microsoft-graph-client/-/microsoft-graph-client-3.0.7.tgz",
"integrity": "sha512-/AazAV/F+HK4LIywF9C+NYHcJo038zEnWkteilcxC1FM/uK/4NVGDKGrxx7nNq1ybspAroRKT4I1FHfxQzxkUw==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"tslib": "^2.2.0"
},
"engines": {
"node": ">=12.0.0"
},
"peerDependenciesMeta": {
"@azure/identity": {
"optional": true
},
"@azure/msal-browser": {
"optional": true
},
"buffer": {
"optional": true
},
"stream-browserify": {
"optional": true
}
}
},
"node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz",
@@ -8742,6 +8812,11 @@
"node": ">=10.17.0"
}
},
"node_modules/ical.js": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ical.js/-/ical.js-2.2.1.tgz",
"integrity": "sha512-yK/UlPbEs316igb/tjRgbFA8ZV75rCsBJp/hWOatpyaPNlgw0dGDmU+FoicOcwX4xXkeXOkYiOmCqNPFpNPkQg=="
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -12312,6 +12387,15 @@
"node": ">=0.10.0"
}
},
"node_modules/preact": {
"version": "10.12.1",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz",
"integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
}
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -16624,6 +16708,7 @@
"name": "@nick-tracker/backend",
"version": "1.0.0",
"dependencies": {
"@microsoft/microsoft-graph-client": "^3.0.7",
"@nestjs/common": "^10.3.0",
"@nestjs/config": "^3.1.1",
"@nestjs/core": "^10.3.0",
@@ -16635,12 +16720,14 @@
"@nestjs/typeorm": "^10.0.1",
"@nestjs/websockets": "^10.3.0",
"@nick-tracker/shared-types": "*",
"axios": "^1.13.2",
"bcrypt": "^5.1.1",
"bull": "^4.12.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"date-fns": "^3.2.0",
"helmet": "^7.1.0",
"ical.js": "^2.2.1",
"ioredis": "^5.3.2",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
@@ -16675,6 +16762,11 @@
"name": "@nick-tracker/frontend",
"version": "1.0.0",
"dependencies": {
"@fullcalendar/core": "^6.1.20",
"@fullcalendar/daygrid": "^6.1.20",
"@fullcalendar/interaction": "^6.1.20",
"@fullcalendar/react": "^6.1.20",
"@fullcalendar/timegrid": "^6.1.20",
"@nick-tracker/shared-types": "*",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",