feat: add Chart, Dashboard, DashboardWidget schema and migration

- Add Prisma models for Chart, Dashboard, DashboardWidget
- ChartType: area, bar, line, pie, big_number only
- Remove DashboardStatus and WidgetType (widgets are always charts)
- DashboardWidget requires chartId, remove content/type fields

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Dhruwang
2026-02-18 17:24:48 +05:30
parent e00405dca2
commit 881cd31f74
2 changed files with 15 additions and 51 deletions

View File

@@ -1,11 +1,5 @@
-- CreateEnum
CREATE TYPE "public"."ChartType" AS ENUM ('area', 'bar', 'line', 'pie', 'big_number', 'big_number_total', 'table', 'funnel', 'map');
-- CreateEnum
CREATE TYPE "public"."DashboardStatus" AS ENUM ('draft', 'published');
-- CreateEnum
CREATE TYPE "public"."WidgetType" AS ENUM ('chart', 'markdown', 'header', 'divider');
CREATE TYPE "public"."ChartType" AS ENUM ('area', 'bar', 'line', 'pie', 'big_number');
-- CreateTable
CREATE TABLE "public"."Chart" (
@@ -29,7 +23,6 @@ CREATE TABLE "public"."Dashboard" (
"updated_at" TIMESTAMP(3) NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"status" "public"."DashboardStatus" NOT NULL DEFAULT 'draft',
"projectId" TEXT NOT NULL,
"createdBy" TEXT,
@@ -42,10 +35,8 @@ CREATE TABLE "public"."DashboardWidget" (
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
"dashboardId" TEXT NOT NULL,
"type" "public"."WidgetType" NOT NULL,
"title" TEXT,
"chartId" TEXT,
"content" JSONB,
"chartId" TEXT NOT NULL,
"layout" JSONB NOT NULL DEFAULT '{"x":0,"y":0,"w":4,"h":3}',
"order" INTEGER NOT NULL DEFAULT 0,
@@ -61,9 +52,6 @@ CREATE UNIQUE INDEX "Chart_projectId_name_key" ON "public"."Chart"("projectId",
-- CreateIndex
CREATE INDEX "Dashboard_projectId_created_at_idx" ON "public"."Dashboard"("projectId", "created_at");
-- CreateIndex
CREATE INDEX "Dashboard_projectId_status_idx" ON "public"."Dashboard"("projectId", "status");
-- CreateIndex
CREATE UNIQUE INDEX "Dashboard_projectId_name_key" ON "public"."Dashboard"("projectId", "name");
@@ -80,4 +68,4 @@ ALTER TABLE "public"."Dashboard" ADD CONSTRAINT "Dashboard_projectId_fkey" FOREI
ALTER TABLE "public"."DashboardWidget" ADD CONSTRAINT "DashboardWidget_dashboardId_fkey" FOREIGN KEY ("dashboardId") REFERENCES "public"."Dashboard"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "public"."DashboardWidget" ADD CONSTRAINT "DashboardWidget_chartId_fkey" FOREIGN KEY ("chartId") REFERENCES "public"."Chart"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "public"."DashboardWidget" ADD CONSTRAINT "DashboardWidget_chartId_fkey" FOREIGN KEY ("chartId") REFERENCES "public"."Chart"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -1013,22 +1013,6 @@ enum ChartType {
line
pie
big_number
big_number_total
table
funnel
map
}
enum DashboardStatus {
draft
published
}
enum WidgetType {
chart
markdown
header
divider
}
/// Represents a chart/visualization that can be used in multiple dashboards.
@@ -1061,15 +1045,14 @@ model Chart {
@@index([projectId, createdAt])
}
/// Represents a dashboard containing multiple widgets/charts.
/// Represents a dashboard containing multiple charts.
/// Dashboards aggregate analytics insights at the project level.
///
/// @property id - Unique identifier for the dashboard
/// @property name - Display name of the dashboard
/// @property description - Optional description
/// @property status - Whether the dashboard is draft or published
/// @property project - The project this dashboard belongs to
/// @property widgets - Charts and other widgets on this dashboard
/// @property widgets - Charts on this dashboard
/// @property createdBy - User who created the dashboard
model Dashboard {
id String @id @default(cuid())
@@ -1077,7 +1060,6 @@ model Dashboard {
updatedAt DateTime @updatedAt @map(name: "updated_at")
name String
description String?
status DashboardStatus @default(draft)
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
projectId String
createdBy String?
@@ -1085,35 +1067,29 @@ model Dashboard {
@@unique([projectId, name])
@@index([projectId, createdAt])
@@index([projectId, status])
}
/// Represents a widget on a dashboard (chart, markdown, header, etc.).
/// Represents a chart widget on a dashboard.
/// Widgets are positioned using a grid layout system.
///
/// @property id - Unique identifier for the widget
/// @property dashboard - The dashboard this widget belongs to
/// @property type - Type of widget (chart, markdown, header, divider)
/// @property title - Optional title for the widget
/// @property chart - Reference to chart if type is "chart"
/// @property content - Content for markdown/header widgets
/// @property chart - The chart displayed in this widget
/// @property layout - Grid layout configuration (x, y, width, height)
/// @property order - Display order within the dashboard
model DashboardWidget {
id String @id @default(cuid())
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @updatedAt @map(name: "updated_at")
dashboard Dashboard @relation(fields: [dashboardId], references: [id], onDelete: Cascade)
id String @id @default(cuid())
createdAt DateTime @default(now()) @map(name: "created_at")
updatedAt DateTime @updatedAt @map(name: "updated_at")
dashboard Dashboard @relation(fields: [dashboardId], references: [id], onDelete: Cascade)
dashboardId String
type WidgetType
title String?
chart Chart? @relation(fields: [chartId], references: [id], onDelete: SetNull)
chartId String?
/// [WidgetContent] - Content for markdown/header widgets
content Json?
chart Chart @relation(fields: [chartId], references: [id], onDelete: Cascade)
chartId String
/// [WidgetLayout] - Grid layout: { x, y, w, h }
layout Json @default("{\"x\":0,\"y\":0,\"w\":4,\"h\":3}")
order Int @default(0)
layout Json @default("{\"x\":0,\"y\":0,\"w\":4,\"h\":3}")
order Int @default(0)
@@index([dashboardId, order])
}