wip
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."share_dashboards" (
|
||||
"id" TEXT NOT NULL,
|
||||
"dashboardId" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"public" BOOLEAN NOT NULL DEFAULT false,
|
||||
"password" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."share_reports" (
|
||||
"id" TEXT NOT NULL,
|
||||
"reportId" UUID NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"public" BOOLEAN NOT NULL DEFAULT false,
|
||||
"password" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "share_dashboards_id_key" ON "public"."share_dashboards"("id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "share_dashboards_dashboardId_key" ON "public"."share_dashboards"("dashboardId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "share_reports_id_key" ON "public"."share_reports"("id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "share_reports_reportId_key" ON "public"."share_reports"("reportId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."share_dashboards" ADD CONSTRAINT "share_dashboards_dashboardId_fkey" FOREIGN KEY ("dashboardId") REFERENCES "public"."dashboards"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."share_dashboards" ADD CONSTRAINT "share_dashboards_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."share_dashboards" ADD CONSTRAINT "share_dashboards_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "public"."projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."share_reports" ADD CONSTRAINT "share_reports_reportId_fkey" FOREIGN KEY ("reportId") REFERENCES "public"."reports"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."share_reports" ADD CONSTRAINT "share_reports_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."share_reports" ADD CONSTRAINT "share_reports_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "public"."projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -46,16 +46,18 @@ model Chat {
|
||||
}
|
||||
|
||||
model Organization {
|
||||
id String @id @default(dbgenerated("gen_random_uuid()"))
|
||||
id String @id @default(dbgenerated("gen_random_uuid()"))
|
||||
name String
|
||||
projects Project[]
|
||||
members Member[]
|
||||
createdByUserId String?
|
||||
createdBy User? @relation(name: "organizationCreatedBy", fields: [createdByUserId], references: [id], onDelete: SetNull)
|
||||
createdBy User? @relation(name: "organizationCreatedBy", fields: [createdByUserId], references: [id], onDelete: SetNull)
|
||||
ProjectAccess ProjectAccess[]
|
||||
Client Client[]
|
||||
Dashboard Dashboard[]
|
||||
ShareOverview ShareOverview[]
|
||||
ShareDashboard ShareDashboard[]
|
||||
ShareReport ShareReport[]
|
||||
integrations Integration[]
|
||||
invites Invite[]
|
||||
timezone String?
|
||||
@@ -185,13 +187,15 @@ model Project {
|
||||
/// [IPrismaProjectFilters]
|
||||
filters Json @default("[]")
|
||||
|
||||
clients Client[]
|
||||
reports Report[]
|
||||
dashboards Dashboard[]
|
||||
share ShareOverview?
|
||||
meta EventMeta[]
|
||||
references Reference[]
|
||||
access ProjectAccess[]
|
||||
clients Client[]
|
||||
reports Report[]
|
||||
dashboards Dashboard[]
|
||||
share ShareOverview?
|
||||
shareDashboards ShareDashboard[]
|
||||
shareReports ShareReport[]
|
||||
meta EventMeta[]
|
||||
references Reference[]
|
||||
access ProjectAccess[]
|
||||
|
||||
notificationRules NotificationRule[]
|
||||
notifications Notification[]
|
||||
@@ -283,13 +287,14 @@ enum ChartType {
|
||||
}
|
||||
|
||||
model Dashboard {
|
||||
id String @id @default(dbgenerated("gen_random_uuid()"))
|
||||
id String @id @default(dbgenerated("gen_random_uuid()"))
|
||||
name String
|
||||
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
||||
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
||||
organizationId String
|
||||
projectId String
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
reports Report[]
|
||||
share ShareDashboard?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
@@ -328,6 +333,7 @@ model Report {
|
||||
dashboardId String
|
||||
dashboard Dashboard @relation(fields: [dashboardId], references: [id], onDelete: Cascade)
|
||||
layout ReportLayout?
|
||||
share ShareReport?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
@@ -372,6 +378,38 @@ model ShareOverview {
|
||||
@@map("shares")
|
||||
}
|
||||
|
||||
model ShareDashboard {
|
||||
id String @unique
|
||||
dashboardId String @unique
|
||||
dashboard Dashboard @relation(fields: [dashboardId], references: [id], onDelete: Cascade)
|
||||
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
||||
organizationId String
|
||||
projectId String
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
public Boolean @default(false)
|
||||
password String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
@@map("share_dashboards")
|
||||
}
|
||||
|
||||
model ShareReport {
|
||||
id String @unique
|
||||
reportId String @unique @db.Uuid
|
||||
report Report @relation(fields: [reportId], references: [id], onDelete: Cascade)
|
||||
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
||||
organizationId String
|
||||
projectId String
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
public Boolean @default(false)
|
||||
password String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
@@map("share_reports")
|
||||
}
|
||||
|
||||
model EventMeta {
|
||||
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
||||
name String
|
||||
|
||||
@@ -18,3 +18,100 @@ export function getShareByProjectId(projectId: string) {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Dashboard sharing functions
|
||||
export function getShareDashboardById(id: string) {
|
||||
return db.shareDashboard.findFirst({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
include: {
|
||||
dashboard: {
|
||||
include: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function getShareDashboardByDashboardId(dashboardId: string) {
|
||||
return db.shareDashboard.findUnique({
|
||||
where: {
|
||||
dashboardId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Report sharing functions
|
||||
export function getShareReportById(id: string) {
|
||||
return db.shareReport.findFirst({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
include: {
|
||||
report: {
|
||||
include: {
|
||||
project: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function getShareReportByReportId(reportId: string) {
|
||||
return db.shareReport.findUnique({
|
||||
where: {
|
||||
reportId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Validation for secure endpoints
|
||||
export async function validateReportAccess(
|
||||
reportId: string,
|
||||
shareId: string,
|
||||
shareType: 'dashboard' | 'report',
|
||||
) {
|
||||
if (shareType === 'dashboard') {
|
||||
const share = await db.shareDashboard.findUnique({
|
||||
where: { id: shareId },
|
||||
include: {
|
||||
dashboard: {
|
||||
include: {
|
||||
reports: {
|
||||
where: { id: reportId },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!share || !share.public) {
|
||||
throw new Error('Share not found or not public');
|
||||
}
|
||||
|
||||
if (!share.dashboard.reports.some((r) => r.id === reportId)) {
|
||||
throw new Error('Report does not belong to this dashboard');
|
||||
}
|
||||
|
||||
return share;
|
||||
} else {
|
||||
const share = await db.shareReport.findUnique({
|
||||
where: { id: shareId },
|
||||
include: {
|
||||
report: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!share || !share.public) {
|
||||
throw new Error('Share not found or not public');
|
||||
}
|
||||
|
||||
if (share.reportId !== reportId) {
|
||||
throw new Error('Report ID mismatch');
|
||||
}
|
||||
|
||||
return share;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user