Skip to content

feat: complete roadmap — Automation & Workflow + Enhanced Analytics + build fixes - #119

Merged
hotlong merged 11 commits into
mainfrom
copilot/complete-roadmap-automation-analytics
Feb 8, 2026
Merged

hotlong merged 11 commits into
mainfrom
copilot/complete-roadmap-automation-analytics

Conversation

Copilot AI commented Feb 8, 2026 •

Copy link
Copy Markdown
Contributor

Description

Implements the Phase 2 roadmap items for Automation & Workflow and Enhanced Analytics across 5 packages. Also fixes all build errors across the repository (both new and pre-existing) caused by @objectstack/spec types being used as classes with .create() when they are Zod-inferred types.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Code refactoring
  • Performance improvement
  • CI/CD update

Related Issues

Related to the Phase 2 roadmap in content/docs/roadmap.mdx

Changes Made

⚡ Automation & Workflow

  • Advanced Approvals (packages/products/src/approval.workflow.ts) — 4 workflow rules: parallel approval chains, OOO smart delegation, SLA-based escalation, auto-resolve for low-risk requests (AI score < 20, discount < 5%)
  • HR Workflows (packages/hr/src/hr.workflow.ts) — 5 workflow rules: onboarding task creation, time-off manager routing, auto-approval for ≤1 day leaves, quarterly review cycle generation, overdue review reminders
  • Contract Renewals (packages/finance/src/hooks/contract_renewal.hook.ts) — 2 hooks: auto-create renewal opportunity at T-90 days, urgent expiration alert at T-30 days

🎯 Enhanced Analytics

  • Revenue Dashboards (packages/finance/src/actions/revenue_dashboard.action.ts) — calculateTCV (distribution, growth trend), calculateARR (MRR normalization, new/expansion/churn movement), calculateQuoteToClose (funnel, revision analysis)
  • Sales Performance (packages/crm/src/actions/sales_performance.action.ts) — analyzePipeline (stage velocity, aging, health score), analyzeWinRates (by segment/source/trend), analyzeForecastAccuracy (bias, accuracy by rep/stage)
  • Service Metrics (packages/support/src/actions/service_metrics.action.ts) — analyzeFirstResponseTime (avg/median/P90/P95 by priority/channel), analyzeCSAT (NPS, satisfaction drivers), analyzeSLACompliance (scorecards, breach patterns)
  • HR Analytics (packages/hr/src/actions/hr_analytics.action.ts) — analyzeTimeToHire (stage durations, bottlenecks, cost-per-hire), analyzeAttrition (voluntary/involuntary, cohort retention, risk factors), analyzePerformanceTrends (rating distribution, flight risk)

Integration

  • Registered ContractRenewalCheck and ContractExpirationAlert triggers in FinancePlugin
  • Updated index exports for products, hr, finance, crm, support
  • Updated roadmap.mdx — marked Automation & Workflow and Enhanced Analytics sections as completed

🔧 Build Fixes (14 files across 5 packages)

Fixed all build errors caused by @objectstack/spec v1.1.0 types (WorkflowRule, Agent, ListView, Dashboard, RAGPipelineConfig, StateMachineConfig) being Zod-inferred types, not classes with .create() methods:

  • CRM: lead.workflow.ts, account.page.ts, account.view.ts, sales.dashboard.ts, sales_copilot.agent.ts, sales_assistant.agent.ts — changed .create() to plain object literals; added ../ai reference in tsconfig.json
  • Support: case.statemachine.ts (fixed StateMachine → StateMachineConfig), inbox.agent.ts, knowledge.rag.ts
  • HR: performance_coach.agent.ts, recruitment_assistant.agent.ts
  • Products: approval.workflow.ts
  • HR: hr.workflow.ts

Testing

  • Unit tests pass (npm test)
  • Linting passes (npm run lint)
  • Build succeeds (npm run build)
  • Manual testing completed
  • New tests added (if applicable)

41 new tests across 3 test files:

  • packages/finance/__tests__/unit/hooks/contract_renewal.hook.test.ts (11 tests)
  • packages/crm/__tests__/unit/actions/sales_performance.action.test.ts (16 tests)
  • packages/support/__tests__/unit/actions/service_metrics.action.test.ts (14 tests)

496 total tests passing (455 existing + 41 new). All 10 packages build successfully with pnpm -r build.

Screenshots

N/A — backend business logic only.

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published

Additional Notes

  • All new action files follow the established pattern: typed Request/Response interfaces, db.find() queries, in-memory calculation, default object export
  • All new workflow files and pre-existing workflow/agent/view/page/dashboard files use plain object literals instead of Type.create() — this is because @objectstack/spec v1.1.0 exports these as Zod-inferred types (z.infer<typeof Schema>), not classes with factory methods
  • All new hooks use the Hook type from @objectstack/spec/data consistent with contract.hook.ts
  • Marketing ROI and SLA Enforcement were already implemented — no changes needed

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@vercel

vercel Bot commented Feb 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hotcrm Ready Ready Preview, Comment Feb 8, 2026 9:17am

Request Review

…and smart delegation

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI and others added 2 commits February 8, 2026 07:50
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
… accuracy analytics

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
… Compliance analytics

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
… trend analysis

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
… analytics

- Advanced Approvals: parallel approval chains and smart delegation workflow
- HR Workflows: onboarding automation, time-off approvals, performance review cycles
- Contract Renewals: auto-create renewal opportunity 90 days before expiration
- Revenue Dashboards: TCV, ARR, Quote-to-Close analytics
- Sales Performance: pipeline metrics, win rates, forecast accuracy
- Service Metrics: First Response Time, CSAT, SLA compliance
- HR Analytics: time-to-hire, attrition rates, performance trends
- Updated plugin registrations and index exports
- Updated roadmap documentation

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…nd service_metrics action

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Complete roadmap for automation and enhanced analytics feat: complete roadmap — Automation & Workflow + Enhanced Analytics Feb 8, 2026
Copilot AI requested a review from hotlong February 8, 2026 08:22
} from '../../../src/actions/service_metrics.action';

// Helper: build a date string N minutes ago
function minutesAgo(min: number): string {

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note test

Unused function minutesAgo.

Copilot Autofix

AI 8 months ago

The general fix for an unused function in a test file is to either remove it or start using it where appropriate. To avoid changing existing behavior, the safest approach is to remove the unused helper entirely, as it currently has no effect on the tests. There is no indication that future tests depend on it, and no references appear in the visible code.

Concretely, in packages/support/__tests__/unit/actions/service_metrics.action.test.ts, delete the minutesAgo function definition (lines 16–19 in the snippet), leaving the daysAgo helper and all tests unchanged. No new imports or other definitions are required.

Suggested changeset 1
packages/support/__tests__/unit/actions/service_metrics.action.test.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/support/__tests__/unit/actions/service_metrics.action.test.ts b/packages/support/__tests__/unit/actions/service_metrics.action.test.ts
--- a/packages/support/__tests__/unit/actions/service_metrics.action.test.ts
+++ b/packages/support/__tests__/unit/actions/service_metrics.action.test.ts
@@ -13,11 +13,7 @@
   analyzeSLACompliance
 } from '../../../src/actions/service_metrics.action';
 
-// Helper: build a date string N minutes ago
-function minutesAgo(min: number): string {
-  return new Date(Date.now() - min * 60 * 1000).toISOString();
-}
-
+// Helper: build a date string N days ago
 function daysAgo(days: number): string {
   return new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
 }
EOF
@@ -13,11 +13,7 @@
analyzeSLACompliance
} from '../../../src/actions/service_metrics.action';

// Helper: build a date string N minutes ago
function minutesAgo(min: number): string {
return new Date(Date.now() - min * 60 * 1000).toISOString();
}

// Helper: build a date string N days ago
function daysAgo(days: number): string {
return new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
}
Copilot is powered by AI and may make mistakes. Always verify output.
return new Date(Date.now() - min * 60 * 1000).toISOString();
}

function daysAgo(days: number): string {

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note test

Unused function daysAgo.

Copilot Autofix

AI 8 months ago

In general, to fix an unused function warning, either remove the function if it truly isn’t needed, or start using it where appropriate. Since daysAgo is not referenced anywhere in the snippet and there is no sign it is required for test behavior, the safest change that preserves current functionality is to delete the unused helper.

Concretely, in packages/support/__tests__/unit/actions/service_metrics.action.test.ts, remove the daysAgo function definition at lines 21–23:

21: function daysAgo(days: number): string {
22:   return new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
23: }

No additional imports or definitions are needed. All other code can remain unchanged, since no other lines reference daysAgo.

Suggested changeset 1
packages/support/__tests__/unit/actions/service_metrics.action.test.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/support/__tests__/unit/actions/service_metrics.action.test.ts b/packages/support/__tests__/unit/actions/service_metrics.action.test.ts
--- a/packages/support/__tests__/unit/actions/service_metrics.action.test.ts
+++ b/packages/support/__tests__/unit/actions/service_metrics.action.test.ts
@@ -18,10 +18,6 @@
   return new Date(Date.now() - min * 60 * 1000).toISOString();
 }
 
-function daysAgo(days: number): string {
-  return new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
-}
-
 describe('analyzeFirstResponseTime', () => {
   beforeEach(() => {
     vi.resetAllMocks();
EOF
@@ -18,10 +18,6 @@
return new Date(Date.now() - min * 60 * 1000).toISOString();
}

function daysAgo(days: number): string {
return new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
}

describe('analyzeFirstResponseTime', () => {
beforeEach(() => {
vi.resetAllMocks();
Copilot is powered by AI and may make mistakes. Always verify output.
@hotlong

hotlong commented Feb 8, 2026

Copy link
Copy Markdown
Contributor

@copilot fix all build errors

- Fix WorkflowRule.create() → plain object (WorkflowRule is a type, not a class)
- Fix Agent.create() → plain object in all agent files
- Fix ListView.create() → plain object in account.view.ts
- Fix PageSchema.create() → plain object in account.page.ts
- Fix Dashboard.create() → plain object in sales.dashboard.ts
- Fix StateMachine → StateMachineConfig (correct export name) in case.statemachine.ts
- Fix RAGPipelineConfig.create() → plain object in knowledge.rag.ts
- Add ../ai reference to CRM tsconfig.json for @hotcrm/ai resolution
- All 10 packages build successfully
- All 496 tests passing

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>

Copilot AI commented Feb 8, 2026

Copy link
Copy Markdown
Contributor Author

@copilot fix all build errors

Fixed all build errors in commit f06c36d. The root cause was that WorkflowRule, Agent, ListView, RAGPipelineConfig, etc. from @objectstack/spec are Zod-inferred types, not classes with .create() methods. Changed all usages to plain object literals. Also fixed StateMachine → StateMachineConfig (correct export name), PageSchema.create() → plain object, and added ../ai reference to CRM tsconfig.json. All 10 packages now build successfully with pnpm -r build and all 496 tests pass.

Copilot AI changed the title feat: complete roadmap — Automation & Workflow + Enhanced Analytics feat: complete roadmap — Automation & Workflow + Enhanced Analytics + build fixes Feb 8, 2026
Copilot AI requested a review from hotlong February 8, 2026 09:17
@hotlong
hotlong marked this pull request as ready for review February 8, 2026 11:10
Copilot AI review requested due to automatic review settings February 8, 2026 11:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements Phase 2 roadmap items for Automation & Workflow and Enhanced Analytics across multiple HotCRM packages, and applies build fixes related to @objectstack/spec v1.1.0 types by replacing .create() usages with plain object literals.

Changes:

  • Added new analytics action modules (Sales Performance, Revenue Dashboard, Service Metrics, HR Analytics) plus unit tests.
  • Added new automation/workflow configs (Advanced Approvals, HR Workflows) and a new Finance contract renewal hook wired into the Finance plugin.
  • Updated various UI/agent/workflow/dashboard configs to object literals for build compatibility, and marked roadmap items as completed.

Reviewed changes

Copilot reviewed 29 out of 29 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
packages/support/src/actions/service_metrics.action.ts Adds service analytics (FRT/CSAT/SLA compliance).
packages/support/tests/unit/actions/service_metrics.action.test.ts Adds unit tests for the service metrics actions.
packages/finance/src/hooks/contract_renewal.hook.ts Adds renewal opportunity creation + expiration alert hooks.
packages/finance/tests/unit/hooks/contract_renewal.hook.test.ts Adds unit tests for the renewal hooks.
packages/products/src/approval.workflow.ts Adds advanced approval workflow rules (delegation/escalation/auto-resolve).
content/docs/roadmap.mdx Marks Phase 2 items as completed.
packages/*/src/{agents,views,pages,workflows,dashboards}.ts Converts @objectstack/spec .create() usage to object literals for build fixes.

Comment on lines +60 to +68
await db.insert('task', {
subject: `Initiate renewal for Contract ${newDoc.contract_number}`,
description: `Contract ${newDoc.contract_number} expires on ${endDate.toISOString().split('T')[0]}. Please reach out to the customer to discuss renewal.`,
related_to: newDoc.account,
opportunity: opportunity._id,
status: 'Open',
priority: daysUntilExpiry <= ALERT_WINDOW_DAYS ? 'High' : 'Normal',
due_date: new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString()
});

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inserted task uses fields related_to and opportunity, but the CRM Task schema uses what_id / who_id for relationships and does not define an opportunity field. Update the task payload to match the Task schema (and ensure due_date is set since it’s required).

Copilot uses AI. Check for mistakes.
Comment on lines +108 to +109
related_to: newDoc.account,
contract: newDoc._id,

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inserted activity uses fields related_to and contract, but the CRM Activity schema uses what_id/who_id for associations and has no contract field. Align the activity payload with the Activity schema so the alert can be persisted and related correctly.

Suggested change
related_to: newDoc.account,
contract: newDoc._id,
what_id: newDoc._id,
who_id: newDoc.account,

Copilot uses AI. Check for mistakes.
original_approver: '${current_approver_id.delegated_from_id.name}',
delegate_approver: '${current_approver_id.name}',
reason: 'out_of_office',
timestamp: '${NOW()}'

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In SmartDelegation, the audit webhook payload uses timestamp: '${NOW()}'. Elsewhere in workflows, NOW() is used as a formula/value string (e.g., value: 'NOW()'). If the workflow engine doesn’t template-evaluate function calls inside ${...}, this will emit a literal string; consider using a supported date expression consistently (e.g., NOW() without ${} or a dedicated runtime token).

Suggested change
timestamp: '${NOW()}'
timestamp: 'NOW()'

Copilot uses AI. Check for mistakes.
Comment on lines +112 to +126
const cutoffDate = new Date(Date.now() - periodDays * 24 * 60 * 60 * 1000).toISOString();
const filters: any[] = [
['created_date', '>', cutoffDate],
['first_response_date', '!=', null]
];
if (priority) filters.push(['priority', '=', priority]);
if (channel) filters.push(['channel', '=', channel]);

const cases = await db.find('case', {
filters,
fields: [
'priority', 'channel', 'created_date', 'first_response_date',
'status', 'owner_id'
]
});

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

analyzeFirstResponseTime queries and computes using first_response_date and channel, but the case schema defines first_response_time and uses origin for the channel field. As written, this will return empty/incorrect analytics against the defined object fields; align the queried fields (and response-time calculation inputs) with the Case object schema.

Copilot uses AI. Check for mistakes.
Comment on lines +132 to +135
{ satisfaction_rating: 5, owner_id: 'agent_1', category: 'billing', priority: 'medium', created_date: new Date(now - 2 * 86400000).toISOString(), closed_date: new Date(now - 1 * 86400000).toISOString(), first_response_date: new Date(now - 1.5 * 86400000).toISOString(), status: 'Closed', is_escalated: false, resolution_type: 'first_contact', channel: 'chat' },
{ satisfaction_rating: 4, owner_id: 'agent_2', category: 'technical', priority: 'high', created_date: new Date(now - 3 * 86400000).toISOString(), closed_date: new Date(now - 2 * 86400000).toISOString(), first_response_date: new Date(now - 2.5 * 86400000).toISOString(), status: 'Closed', is_escalated: false, resolution_type: 'resolved', channel: 'email' },
{ satisfaction_rating: 2, owner_id: 'agent_1', category: 'billing', priority: 'low', created_date: new Date(now - 4 * 86400000).toISOString(), closed_date: new Date(now - 3 * 86400000).toISOString(), first_response_date: new Date(now - 3.5 * 86400000).toISOString(), status: 'Closed', is_escalated: true, resolution_type: 'resolved', channel: 'email' },
{ satisfaction_rating: 5, owner_id: 'agent_2', category: 'technical', priority: 'medium', created_date: new Date(now - 5 * 86400000).toISOString(), closed_date: new Date(now - 4 * 86400000).toISOString(), first_response_date: new Date(now - 4.5 * 86400000).toISOString(), status: 'Closed', is_escalated: false, resolution_type: 'first_contact', channel: 'chat' },

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit tests use satisfaction_rating and first_response_date fields, which do not match the case object schema (satisfaction_score, first_response_time, and origin). Once the action is aligned to schema fields, update these fixtures/expectations so tests validate the real contract.

Suggested change
{ satisfaction_rating: 5, owner_id: 'agent_1', category: 'billing', priority: 'medium', created_date: new Date(now - 2 * 86400000).toISOString(), closed_date: new Date(now - 1 * 86400000).toISOString(), first_response_date: new Date(now - 1.5 * 86400000).toISOString(), status: 'Closed', is_escalated: false, resolution_type: 'first_contact', channel: 'chat' },
{ satisfaction_rating: 4, owner_id: 'agent_2', category: 'technical', priority: 'high', created_date: new Date(now - 3 * 86400000).toISOString(), closed_date: new Date(now - 2 * 86400000).toISOString(), first_response_date: new Date(now - 2.5 * 86400000).toISOString(), status: 'Closed', is_escalated: false, resolution_type: 'resolved', channel: 'email' },
{ satisfaction_rating: 2, owner_id: 'agent_1', category: 'billing', priority: 'low', created_date: new Date(now - 4 * 86400000).toISOString(), closed_date: new Date(now - 3 * 86400000).toISOString(), first_response_date: new Date(now - 3.5 * 86400000).toISOString(), status: 'Closed', is_escalated: true, resolution_type: 'resolved', channel: 'email' },
{ satisfaction_rating: 5, owner_id: 'agent_2', category: 'technical', priority: 'medium', created_date: new Date(now - 5 * 86400000).toISOString(), closed_date: new Date(now - 4 * 86400000).toISOString(), first_response_date: new Date(now - 4.5 * 86400000).toISOString(), status: 'Closed', is_escalated: false, resolution_type: 'first_contact', channel: 'chat' },
{ satisfaction_score: 5, owner_id: 'agent_1', category: 'billing', priority: 'medium', created_date: new Date(now - 2 * 86400000).toISOString(), closed_date: new Date(now - 1 * 86400000).toISOString(), first_response_time: new Date(now - 1.5 * 86400000).toISOString(), status: 'Closed', is_escalated: false, resolution_type: 'first_contact', origin: 'chat' },
{ satisfaction_score: 4, owner_id: 'agent_2', category: 'technical', priority: 'high', created_date: new Date(now - 3 * 86400000).toISOString(), closed_date: new Date(now - 2 * 86400000).toISOString(), first_response_time: new Date(now - 2.5 * 86400000).toISOString(), status: 'Closed', is_escalated: false, resolution_type: 'resolved', origin: 'email' },
{ satisfaction_score: 2, owner_id: 'agent_1', category: 'billing', priority: 'low', created_date: new Date(now - 4 * 86400000).toISOString(), closed_date: new Date(now - 3 * 86400000).toISOString(), first_response_time: new Date(now - 3.5 * 86400000).toISOString(), status: 'Closed', is_escalated: true, resolution_type: 'resolved', origin: 'email' },
{ satisfaction_score: 5, owner_id: 'agent_2', category: 'technical', priority: 'medium', created_date: new Date(now - 5 * 86400000).toISOString(), closed_date: new Date(now - 4 * 86400000).toISOString(), first_response_time: new Date(now - 4.5 * 86400000).toISOString(), status: 'Closed', is_escalated: false, resolution_type: 'first_contact', origin: 'chat' },

Copilot uses AI. Check for mistakes.
Comment on lines +331 to +345
// Fetch cases with satisfaction data
const caseFilters: any[] = [
['created_date', '>', cutoffDate],
['satisfaction_rating', '!=', null]
];
if (category) caseFilters.push(['category', '=', category]);

const cases = await db.find('case', {
filters: caseFilters,
fields: [
'satisfaction_rating', 'owner_id', 'category', 'priority',
'created_date', 'closed_date', 'first_response_date', 'status',
'is_escalated', 'resolution_type', 'channel'
]
});

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

analyzeCSAT filters/reads satisfaction_rating, but the case object schema defines satisfaction_score (numeric 1–5) and customer_satisfaction (select). This will make CSAT/NPS analytics non-functional unless the field name is corrected and the query fields updated accordingly.

Copilot uses AI. Check for mistakes.
Comment on lines +641 to +654
// Fetch SLA milestones
const milestoneFilters: any[] = [
['created_date', '>', cutoffDate]
];
if (slaType) milestoneFilters.push(['type', '=', slaType]);

const milestones = await db.find('sla_milestone', {
filters: milestoneFilters,
fields: [
'type', 'target_date', 'completed_date', 'status', 'priority',
'owner_id', 'team_id', 'target_object_id', 'breach_reason',
'created_date'
]
});

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

analyzeSLACompliance queries sla_milestone using fields like type/target_date/completed_date/team_id/target_object_id/breach_reason, but the sla_milestone schema uses different field names (e.g., milestone_type, target_date_time, actual_date_time, case_id, etc.) and different status values (Completed/Violated/InProgress). This mismatch will break SLA compliance reporting; update the query + status logic to match SLAMilestone fields.

Copilot uses AI. Check for mistakes.
Comment on lines +47 to +55
const opportunity = await db.insert('opportunity', {
name: `Renewal: ${newDoc.contract_number}`,
account: newDoc.account,
source_contract: newDoc._id,
type: 'Renewal',
stage: 'Prospecting',
amount: newDoc.contract_value,
close_date: closeDate.toISOString()
});

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inserted opportunity document uses fields account and source_contract, but the CRM Opportunity schema uses account_id and does not define source_contract. This is likely to fail schema validation or produce orphaned data; use schema-defined fields (or add the necessary lookup field to the Opportunity object) to link the renewal opp back to the contract.

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +20
// Helper: build a date string N minutes ago
function minutesAgo(min: number): string {
return new Date(Date.now() - min * 60 * 1000).toISOString();
}

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused function minutesAgo.

Suggested change
// Helper: build a date string N minutes ago
function minutesAgo(min: number): string {
return new Date(Date.now() - min * 60 * 1000).toISOString();
}

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +24
function daysAgo(days: number): string {
return new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
}

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused function daysAgo.

Suggested change
function daysAgo(days: number): string {
return new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
}

Copilot uses AI. Check for mistakes.
@hotlong
hotlong merged commit d807bad into main Feb 8, 2026
13 checks passed

This branch was successfully deployed

1 active deployment
Preview — f06c36d5 Deployed Feb 8, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants