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:
2026-09-05 18:38:11 +03:30
co-authored by Cursor
parent 1c1b77e74a
commit 32af147237
8 changed files with 1287 additions and 385 deletions
@@ -0,0 +1,6 @@
-- AlterTable SalesGoal: typed goals + forecast fields
ALTER TABLE "SalesGoal" ADD COLUMN IF NOT EXISTS "type" TEXT NOT NULL DEFAULT 'sales';
ALTER TABLE "SalesGoal" ADD COLUMN IF NOT EXISTS "forecastAmount" DECIMAL(18,2);
ALTER TABLE "SalesGoal" ADD COLUMN IF NOT EXISTS "probability" DECIMAL(5,2);
CREATE INDEX IF NOT EXISTS "SalesGoal_organizationId_type_idx" ON "SalesGoal"("organizationId", "type");
+6
View File
@@ -758,9 +758,14 @@ model SalesGoal {
userId String?
user User? @relation("SalesGoalUser", fields: [userId], references: [id], onDelete: Cascade)
title String
/// sales|customer|revenue|deal|activity|quality
type String @default("sales")
periodStart DateTime
periodEnd DateTime
targetAmount Decimal @db.Decimal(18, 2)
forecastAmount Decimal? @db.Decimal(18, 2)
/// 0-100
probability Decimal? @db.Decimal(5, 2)
currency String @default("IRR")
notes String?
createdAt DateTime @default(now())
@@ -768,6 +773,7 @@ model SalesGoal {
@@index([organizationId, periodStart, periodEnd])
@@index([userId])
@@index([organizationId, type])
}
model ExchangeRate {
+2
View File
@@ -1174,6 +1174,7 @@ async function main() {
data: {
organizationId: org.id,
userId: null,
type: 'sales',
title: 'هدف فروش سازمانی ماه جاری',
periodStart,
periodEnd,
@@ -1190,6 +1191,7 @@ async function main() {
data: {
organizationId: org.id,
userId: salesUser.id,
type: 'sales',
title: 'هدف شخصی کارشناس فروش',
periodStart,
periodEnd,