Redesign sales goals and forecast with typed targets and live progress.
Match desktop/mobile mockups and compute current amounts, status, and KPIs from real CRM data. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,13 +1,30 @@
|
||||
import {
|
||||
IsIn,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Max,
|
||||
MaxLength,
|
||||
Min,
|
||||
MinLength,
|
||||
} from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
|
||||
const SALES_GOAL_TYPES = [
|
||||
'sales',
|
||||
'customer',
|
||||
'revenue',
|
||||
'deal',
|
||||
'activity',
|
||||
'quality',
|
||||
] as const;
|
||||
|
||||
const SALES_GOAL_STATUSES = [
|
||||
'in_progress',
|
||||
'completed',
|
||||
'needs_attention',
|
||||
] as const;
|
||||
|
||||
export class CreateSalesGoalDto {
|
||||
@IsString()
|
||||
@MinLength(2)
|
||||
@@ -25,6 +42,24 @@ export class CreateSalesGoalDto {
|
||||
@Min(0)
|
||||
targetAmount!: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@IsIn(SALES_GOAL_TYPES)
|
||||
type?: string;
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
forecastAmount?: number | null;
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
@Max(100)
|
||||
probability?: number | null;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(8)
|
||||
@@ -61,6 +96,24 @@ export class UpdateSalesGoalDto {
|
||||
@Min(0)
|
||||
targetAmount?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@IsIn(SALES_GOAL_TYPES)
|
||||
type?: string;
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
forecastAmount?: number | null;
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
@Max(100)
|
||||
probability?: number | null;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(8)
|
||||
@@ -102,4 +155,18 @@ export class ListGoalsQueryDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
userId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
q?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@IsIn(SALES_GOAL_STATUSES)
|
||||
status?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@IsIn(SALES_GOAL_TYPES)
|
||||
type?: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user