CRM apis
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "SalesPipelineStage" AS ENUM ('negotiation', 'awaiting_catalog', 'awaiting_price', 'ready_to_order');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "OpportunityOutcome" AS ENUM ('open', 'won', 'lost');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "LostReason" AS ENUM ('price', 'product', 'supply_time', 'customer_decision', 'other');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "TimelineEventSource" AS ENUM ('manual', 'system');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "TimelineEventKind" AS ENUM ('meeting', 'call', 'note', 'reminder', 'next_action', 'order_created', 'price_announced', 'price_confirmed', 'catalog_requested');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "AssignmentRequestStatus" AS ENUM ('pending', 'approved', 'rejected');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "SalesOpportunity" (
|
||||
"id" TEXT NOT NULL,
|
||||
"customerId" TEXT NOT NULL,
|
||||
"stage" "SalesPipelineStage" NOT NULL DEFAULT 'negotiation',
|
||||
"outcome" "OpportunityOutcome" NOT NULL DEFAULT 'open',
|
||||
"lostReason" "LostReason",
|
||||
"lostNote" TEXT,
|
||||
"lostAt" TIMESTAMP(3),
|
||||
"wonOrderId" TEXT,
|
||||
"wonAt" TIMESTAMP(3),
|
||||
"assignedAgentId" TEXT,
|
||||
"ownerAdminId" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "SalesOpportunity_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CustomerTimelineEvent" (
|
||||
"id" TEXT NOT NULL,
|
||||
"customerId" TEXT NOT NULL,
|
||||
"kind" "TimelineEventKind" NOT NULL,
|
||||
"source" "TimelineEventSource" NOT NULL DEFAULT 'manual',
|
||||
"title" TEXT NOT NULL,
|
||||
"body" TEXT,
|
||||
"occurredAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"actorAdminId" TEXT,
|
||||
"actorCustomerId" TEXT,
|
||||
"relatedOrderId" TEXT,
|
||||
"relatedMeetingId" TEXT,
|
||||
"relatedActionId" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "CustomerTimelineEvent_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CrmNextAction" (
|
||||
"id" TEXT NOT NULL,
|
||||
"customerId" TEXT NOT NULL,
|
||||
"opportunityId" TEXT,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"dueAt" TIMESTAMP(3) NOT NULL,
|
||||
"completed" BOOLEAN NOT NULL DEFAULT false,
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"assigneeAdminId" TEXT,
|
||||
"assigneeAgentId" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "CrmNextAction_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CustomerAssignmentRequest" (
|
||||
"id" TEXT NOT NULL,
|
||||
"customerId" TEXT NOT NULL,
|
||||
"fromAgentId" TEXT,
|
||||
"toAgentId" TEXT NOT NULL,
|
||||
"requestedByAgentId" TEXT NOT NULL,
|
||||
"status" "AssignmentRequestStatus" NOT NULL DEFAULT 'pending',
|
||||
"reviewNote" TEXT,
|
||||
"reviewedByAdminId" TEXT,
|
||||
"reviewedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "CustomerAssignmentRequest_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "SalesOpportunity_customerId_idx" ON "SalesOpportunity"("customerId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "SalesOpportunity_stage_outcome_idx" ON "SalesOpportunity"("stage", "outcome");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "SalesOpportunity_assignedAgentId_idx" ON "SalesOpportunity"("assignedAgentId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CustomerTimelineEvent_customerId_occurredAt_idx" ON "CustomerTimelineEvent"("customerId", "occurredAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CrmNextAction_customerId_completed_idx" ON "CrmNextAction"("customerId", "completed");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CrmNextAction_dueAt_idx" ON "CrmNextAction"("dueAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CustomerAssignmentRequest_status_idx" ON "CustomerAssignmentRequest"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CustomerAssignmentRequest_customerId_idx" ON "CustomerAssignmentRequest"("customerId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "SalesOpportunity" ADD CONSTRAINT "SalesOpportunity_customerId_fkey" FOREIGN KEY ("customerId") REFERENCES "Customer"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "SalesOpportunity" ADD CONSTRAINT "SalesOpportunity_assignedAgentId_fkey" FOREIGN KEY ("assignedAgentId") REFERENCES "Customer"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "SalesOpportunity" ADD CONSTRAINT "SalesOpportunity_wonOrderId_fkey" FOREIGN KEY ("wonOrderId") REFERENCES "Order"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerTimelineEvent" ADD CONSTRAINT "CustomerTimelineEvent_customerId_fkey" FOREIGN KEY ("customerId") REFERENCES "Customer"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CrmNextAction" ADD CONSTRAINT "CrmNextAction_customerId_fkey" FOREIGN KEY ("customerId") REFERENCES "Customer"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CrmNextAction" ADD CONSTRAINT "CrmNextAction_opportunityId_fkey" FOREIGN KEY ("opportunityId") REFERENCES "SalesOpportunity"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerAssignmentRequest" ADD CONSTRAINT "CustomerAssignmentRequest_customerId_fkey" FOREIGN KEY ("customerId") REFERENCES "Customer"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerAssignmentRequest" ADD CONSTRAINT "CustomerAssignmentRequest_fromAgentId_fkey" FOREIGN KEY ("fromAgentId") REFERENCES "Customer"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerAssignmentRequest" ADD CONSTRAINT "CustomerAssignmentRequest_toAgentId_fkey" FOREIGN KEY ("toAgentId") REFERENCES "Customer"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerAssignmentRequest" ADD CONSTRAINT "CustomerAssignmentRequest_requestedByAgentId_fkey" FOREIGN KEY ("requestedByAgentId") REFERENCES "Customer"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
+164
-23
@@ -85,6 +85,50 @@ enum InteractionType {
|
||||
note
|
||||
}
|
||||
|
||||
enum SalesPipelineStage {
|
||||
negotiation
|
||||
awaiting_catalog
|
||||
awaiting_price
|
||||
ready_to_order
|
||||
}
|
||||
|
||||
enum OpportunityOutcome {
|
||||
open
|
||||
won
|
||||
lost
|
||||
}
|
||||
|
||||
enum LostReason {
|
||||
price
|
||||
product
|
||||
supply_time
|
||||
customer_decision
|
||||
other
|
||||
}
|
||||
|
||||
enum TimelineEventSource {
|
||||
manual
|
||||
system
|
||||
}
|
||||
|
||||
enum TimelineEventKind {
|
||||
meeting
|
||||
call
|
||||
note
|
||||
reminder
|
||||
next_action
|
||||
order_created
|
||||
price_announced
|
||||
price_confirmed
|
||||
catalog_requested
|
||||
}
|
||||
|
||||
enum AssignmentRequestStatus {
|
||||
pending
|
||||
approved
|
||||
rejected
|
||||
}
|
||||
|
||||
enum ProductSeason {
|
||||
summer
|
||||
winter
|
||||
@@ -240,21 +284,29 @@ model Customer {
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
company Company? @relation(fields: [companyId], references: [id], onDelete: SetNull)
|
||||
levelDef CustomerLevelDef? @relation(fields: [levelDefId], references: [id], onDelete: SetNull)
|
||||
assignedAgent Customer? @relation("AgentCustomers", fields: [assignedAgentId], references: [id], onDelete: SetNull)
|
||||
agentCustomers Customer[] @relation("AgentCustomers")
|
||||
carts Cart[]
|
||||
orders Order[]
|
||||
notifications CustomerNotification[]
|
||||
meetings MeetingInteraction[] @relation("MeetingCustomer")
|
||||
meetingsAsAgent MeetingInteraction[] @relation("MeetingAgent")
|
||||
reminders Reminder[] @relation("ReminderOwner")
|
||||
remindersAbout Reminder[] @relation("ReminderCustomer")
|
||||
favorites ProductFavorite[]
|
||||
catalogRequests CatalogRequest[]
|
||||
productSuggestions ProductSuggestion[]
|
||||
addresses CustomerAddress[]
|
||||
company Company? @relation(fields: [companyId], references: [id], onDelete: SetNull)
|
||||
levelDef CustomerLevelDef? @relation(fields: [levelDefId], references: [id], onDelete: SetNull)
|
||||
assignedAgent Customer? @relation("AgentCustomers", fields: [assignedAgentId], references: [id], onDelete: SetNull)
|
||||
agentCustomers Customer[] @relation("AgentCustomers")
|
||||
carts Cart[]
|
||||
orders Order[]
|
||||
notifications CustomerNotification[]
|
||||
meetings MeetingInteraction[] @relation("MeetingCustomer")
|
||||
meetingsAsAgent MeetingInteraction[] @relation("MeetingAgent")
|
||||
reminders Reminder[] @relation("ReminderOwner")
|
||||
remindersAbout Reminder[] @relation("ReminderCustomer")
|
||||
favorites ProductFavorite[]
|
||||
catalogRequests CatalogRequest[]
|
||||
productSuggestions ProductSuggestion[]
|
||||
addresses CustomerAddress[]
|
||||
salesOpportunities SalesOpportunity[]
|
||||
timelineEvents CustomerTimelineEvent[]
|
||||
crmNextActions CrmNextAction[]
|
||||
assignmentRequests CustomerAssignmentRequest[] @relation("AssignmentCustomer")
|
||||
assignmentFrom CustomerAssignmentRequest[] @relation("AssignmentFromAgent")
|
||||
assignmentTo CustomerAssignmentRequest[] @relation("AssignmentToAgent")
|
||||
assignmentRequested CustomerAssignmentRequest[] @relation("AssignmentRequestedBy")
|
||||
opportunitiesOwned SalesOpportunity[] @relation("OpportunityAgent")
|
||||
|
||||
@@index([companyId])
|
||||
@@index([appRole])
|
||||
@@ -363,14 +415,15 @@ model Order {
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user Customer @relation(fields: [userId], references: [id], onDelete: Restrict)
|
||||
company Company @relation(fields: [companyId], references: [id], onDelete: Restrict)
|
||||
items OrderItem[]
|
||||
checks Check[]
|
||||
cashReceipt CashPaymentReceipt?
|
||||
shipment Shipment?
|
||||
statusHistory OrderStatusHistory[]
|
||||
notifications CustomerNotification[]
|
||||
user Customer @relation(fields: [userId], references: [id], onDelete: Restrict)
|
||||
company Company @relation(fields: [companyId], references: [id], onDelete: Restrict)
|
||||
items OrderItem[]
|
||||
checks Check[]
|
||||
cashReceipt CashPaymentReceipt?
|
||||
shipment Shipment?
|
||||
statusHistory OrderStatusHistory[]
|
||||
notifications CustomerNotification[]
|
||||
wonOpportunities SalesOpportunity[]
|
||||
|
||||
@@index([userId])
|
||||
@@index([companyId])
|
||||
@@ -620,6 +673,94 @@ model Reminder {
|
||||
@@index([date])
|
||||
}
|
||||
|
||||
model SalesOpportunity {
|
||||
id String @id @default(cuid())
|
||||
customerId String
|
||||
stage SalesPipelineStage @default(negotiation)
|
||||
outcome OpportunityOutcome @default(open)
|
||||
lostReason LostReason?
|
||||
lostNote String?
|
||||
lostAt DateTime?
|
||||
wonOrderId String?
|
||||
wonAt DateTime?
|
||||
assignedAgentId String?
|
||||
ownerAdminId String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
|
||||
assignedAgent Customer? @relation("OpportunityAgent", fields: [assignedAgentId], references: [id], onDelete: SetNull)
|
||||
wonOrder Order? @relation(fields: [wonOrderId], references: [id], onDelete: SetNull)
|
||||
nextActions CrmNextAction[]
|
||||
|
||||
@@index([customerId])
|
||||
@@index([stage, outcome])
|
||||
@@index([assignedAgentId])
|
||||
}
|
||||
|
||||
model CustomerTimelineEvent {
|
||||
id String @id @default(cuid())
|
||||
customerId String
|
||||
kind TimelineEventKind
|
||||
source TimelineEventSource @default(manual)
|
||||
title String
|
||||
body String?
|
||||
occurredAt DateTime @default(now())
|
||||
actorAdminId String?
|
||||
actorCustomerId String?
|
||||
relatedOrderId String?
|
||||
relatedMeetingId String?
|
||||
relatedActionId String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([customerId, occurredAt])
|
||||
}
|
||||
|
||||
model CrmNextAction {
|
||||
id String @id @default(cuid())
|
||||
customerId String
|
||||
opportunityId String?
|
||||
title String
|
||||
description String?
|
||||
dueAt DateTime
|
||||
completed Boolean @default(false)
|
||||
completedAt DateTime?
|
||||
assigneeAdminId String?
|
||||
assigneeAgentId String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
|
||||
opportunity SalesOpportunity? @relation(fields: [opportunityId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([customerId, completed])
|
||||
@@index([dueAt])
|
||||
}
|
||||
|
||||
model CustomerAssignmentRequest {
|
||||
id String @id @default(cuid())
|
||||
customerId String
|
||||
fromAgentId String?
|
||||
toAgentId String
|
||||
requestedByAgentId String
|
||||
status AssignmentRequestStatus @default(pending)
|
||||
reviewNote String?
|
||||
reviewedByAdminId String?
|
||||
reviewedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
customer Customer @relation("AssignmentCustomer", fields: [customerId], references: [id], onDelete: Cascade)
|
||||
fromAgent Customer? @relation("AssignmentFromAgent", fields: [fromAgentId], references: [id], onDelete: SetNull)
|
||||
toAgent Customer @relation("AssignmentToAgent", fields: [toAgentId], references: [id], onDelete: Cascade)
|
||||
requestedByAgent Customer @relation("AssignmentRequestedBy", fields: [requestedByAgentId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([status])
|
||||
@@index([customerId])
|
||||
}
|
||||
|
||||
model ProductFavorite {
|
||||
id String @id @default(cuid())
|
||||
customerId String
|
||||
|
||||
+102
-3
File diff suppressed because one or more lines are too long
+1508
-10
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user