fix: update personalize sentiment stats data
This commit is contained in:
parent
cba88c53e1
commit
981230041a
|
|
@ -1,145 +0,0 @@
|
|||
-- CreateEnum
|
||||
CREATE TYPE "UserGender" AS ENUM ('male', 'female', 'other');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Sentiment" AS ENUM ('positive', 'negative', 'neutral');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Account" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"provider" TEXT NOT NULL,
|
||||
"providerAccountId" TEXT NOT NULL,
|
||||
"refresh_token" TEXT,
|
||||
"access_token" TEXT,
|
||||
"expires_at" INTEGER,
|
||||
"token_type" TEXT,
|
||||
"scope" TEXT,
|
||||
"id_token" TEXT,
|
||||
"session_state" TEXT,
|
||||
|
||||
CONSTRAINT "Account_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Session" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"sessionToken" TEXT NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"expires" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "VerificationToken" (
|
||||
"identifier" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"expires" TIMESTAMP(3) NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "User" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"name" TEXT,
|
||||
"email" TEXT,
|
||||
"emailVerified" TIMESTAMP(3),
|
||||
"image" TEXT,
|
||||
"gender" "UserGender",
|
||||
"productReference" TEXT,
|
||||
"password" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Analysis" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"reviewId" INTEGER NOT NULL,
|
||||
"productId" INTEGER NOT NULL,
|
||||
"modelId" INTEGER NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Analysis_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Product" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"brand" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Product_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Review" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"productId" INTEGER NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"keywords" TEXT[],
|
||||
"sentiment" "Sentiment" NOT NULL,
|
||||
"confidenceScore" DOUBLE PRECISION NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Review_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Model" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"modelName" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"accuracy" DOUBLE PRECISION NOT NULL,
|
||||
"macroF1" DOUBLE PRECISION NOT NULL,
|
||||
"f1Negative" DOUBLE PRECISION NOT NULL,
|
||||
"f1Neutral" DOUBLE PRECISION NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Model_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Account_provider_providerAccountId_key" ON "Account"("provider", "providerAccountId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Session_sessionToken_key" ON "Session"("sessionToken");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "VerificationToken_token_key" ON "VerificationToken"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "VerificationToken_identifier_token_key" ON "VerificationToken"("identifier", "token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Account" ADD CONSTRAINT "Account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Analysis" ADD CONSTRAINT "Analysis_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Analysis" ADD CONSTRAINT "Analysis_reviewId_fkey" FOREIGN KEY ("reviewId") REFERENCES "Review"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Analysis" ADD CONSTRAINT "Analysis_productId_fkey" FOREIGN KEY ("productId") REFERENCES "Product"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Analysis" ADD CONSTRAINT "Analysis_modelId_fkey" FOREIGN KEY ("modelId") REFERENCES "Model"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Review" ADD CONSTRAINT "Review_productId_fkey" FOREIGN KEY ("productId") REFERENCES "Product"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- The values [positive,negative,neutral] on the enum `Sentiment` will be removed. If these variants are still used in the database, this will fail.
|
||||
- You are about to drop the column `reviewId` on the `Analysis` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `updatedAt` on the `Analysis` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `productReference` on the `User` table. All the data in the column will be lost.
|
||||
- A unique constraint covering the columns `[url]` on the table `Product` will be added. If there are existing duplicate values, this will fail.
|
||||
- Added the required column `compatibilityScore` to the `Analysis` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `generalScore` to the `Analysis` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `targetProfession` to the `Analysis` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `verdict` to the `Analysis` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `url` to the `Product` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Role" AS ENUM ('USER', 'ADMIN');
|
||||
|
||||
-- AlterEnum
|
||||
BEGIN;
|
||||
CREATE TYPE "Sentiment_new" AS ENUM ('POSITIVE', 'NEGATIVE', 'NEUTRAL');
|
||||
ALTER TABLE "Review" ALTER COLUMN "sentiment" TYPE "Sentiment_new" USING ("sentiment"::text::"Sentiment_new");
|
||||
ALTER TYPE "Sentiment" RENAME TO "Sentiment_old";
|
||||
ALTER TYPE "Sentiment_new" RENAME TO "Sentiment";
|
||||
DROP TYPE "public"."Sentiment_old";
|
||||
COMMIT;
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Analysis" DROP CONSTRAINT "Analysis_reviewId_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Analysis" DROP CONSTRAINT "Analysis_userId_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Review" DROP CONSTRAINT "Review_productId_fkey";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Analysis" DROP COLUMN "reviewId",
|
||||
DROP COLUMN "updatedAt",
|
||||
ADD COLUMN "compatibilityScore" DOUBLE PRECISION NOT NULL,
|
||||
ADD COLUMN "generalScore" DOUBLE PRECISION NOT NULL,
|
||||
ADD COLUMN "targetProfession" TEXT NOT NULL,
|
||||
ADD COLUMN "verdict" TEXT NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Model" ADD COLUMN "version" TEXT,
|
||||
ALTER COLUMN "description" DROP NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Product" ADD COLUMN "image" TEXT,
|
||||
ADD COLUMN "url" TEXT NOT NULL,
|
||||
ALTER COLUMN "brand" DROP NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Review" ADD COLUMN "modelId" INTEGER;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" DROP COLUMN "productReference",
|
||||
ADD COLUMN "role" "Role" NOT NULL DEFAULT 'USER';
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Product_url_key" ON "Product"("url");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Review" ADD CONSTRAINT "Review_productId_fkey" FOREIGN KEY ("productId") REFERENCES "Product"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Review" ADD CONSTRAINT "Review_modelId_fkey" FOREIGN KEY ("modelId") REFERENCES "Model"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Analysis" ADD CONSTRAINT "Analysis_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `generalScore` on the `Analysis` table. All the data in the column will be lost.
|
||||
- Added the required column `generalSentiment` to the `Analysis` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Analysis" DROP CONSTRAINT "Analysis_productId_fkey";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Analysis" DROP COLUMN "generalScore",
|
||||
ADD COLUMN "generalSentiment" DOUBLE PRECISION NOT NULL,
|
||||
ADD COLUMN "topKeywords" TEXT[];
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Analysis" ADD CONSTRAINT "Analysis_productId_fkey" FOREIGN KEY ("productId") REFERENCES "Product"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `role` on the `User` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- CreateEnum
|
||||
CREATE TYPE "OS" AS ENUM ('WINDOWS', 'MACOS', 'LINUX', 'CHROME_OS', 'OTHER');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Brand" AS ENUM ('APPLE', 'ASUS', 'ACER', 'LENOVO', 'HP', 'DELL', 'MSI', 'AXIOO', 'ADVAN', 'ZYREX', 'OTHER');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" DROP COLUMN "role",
|
||||
ADD COLUMN "bio" TEXT,
|
||||
ADD COLUMN "birthDate" TIMESTAMP(3),
|
||||
ADD COLUMN "location" TEXT;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "UserPreference" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"profession" TEXT,
|
||||
"preferredOS" "OS",
|
||||
"preferedBrand" "Brand",
|
||||
"budgetMin" INTEGER,
|
||||
"budgetMax" INTEGER,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "UserPreference_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "UserPreference_userId_key" ON "UserPreference"("userId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "UserPreference" ADD CONSTRAINT "UserPreference_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `birthDate` on the `User` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `gender` on the `User` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `location` on the `User` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" DROP COLUMN "birthDate",
|
||||
DROP COLUMN "gender",
|
||||
DROP COLUMN "location";
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- The values [male,female,other] on the enum `UserGender` will be removed. If these variants are still used in the database, this will fail.
|
||||
|
||||
*/
|
||||
-- AlterEnum
|
||||
BEGIN;
|
||||
CREATE TYPE "UserGender_new" AS ENUM ('MALE', 'FEMALE', 'OTHER');
|
||||
ALTER TYPE "UserGender" RENAME TO "UserGender_old";
|
||||
ALTER TYPE "UserGender_new" RENAME TO "UserGender";
|
||||
DROP TYPE "public"."UserGender_old";
|
||||
COMMIT;
|
||||
|
||||
-- DropEnum
|
||||
DROP TYPE "Role";
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `version` on the `Model` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Model" DROP COLUMN "version";
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "postgresql"
|
||||
|
|
@ -91,6 +91,7 @@ model User {
|
|||
analyses Analysis[]
|
||||
|
||||
preference UserPreference?
|
||||
review Review[]
|
||||
}
|
||||
|
||||
model UserPreference {
|
||||
|
|
@ -137,6 +138,10 @@ model Review {
|
|||
|
||||
modelId Int?
|
||||
model Model? @relation(fields: [modelId], references: [id])
|
||||
|
||||
userId Int?
|
||||
user User? @relation(fields: [userId], references: [id])
|
||||
|
||||
}
|
||||
|
||||
model Analysis {
|
||||
|
|
@ -160,6 +165,7 @@ model Analysis {
|
|||
|
||||
modelId Int
|
||||
model Model @relation(fields: [modelId], references: [id])
|
||||
|
||||
}
|
||||
|
||||
model Model {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,39 @@
|
|||
import prisma from "@/lib/prisma";
|
||||
import { NextResponse } from "next/server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { authOptions } from "../../auth/[...nextauth]/route";
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const session = await getServerSession(authOptions);
|
||||
|
||||
if (!session?.user?.email) {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Unauthorized. User belum login." },
|
||||
{ status: 401 },
|
||||
);
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { email: session.user.email },
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "User tidak ditemukan." },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
const grouped = await prisma.review.groupBy({
|
||||
by: ["sentiment"],
|
||||
_count: { _all: true },
|
||||
where: {
|
||||
userId: user.id,
|
||||
},
|
||||
_count: {
|
||||
_all: true,
|
||||
},
|
||||
});
|
||||
|
||||
const result = {
|
||||
|
|
@ -15,14 +43,17 @@ export async function GET() {
|
|||
};
|
||||
|
||||
grouped.forEach((item) => {
|
||||
if (item.sentiment === "positive") result.positive = item._count._all;
|
||||
if (item.sentiment === "negative") result.negative = item._count._all;
|
||||
if (item.sentiment === "neutral") result.neutral = item._count._all;
|
||||
if (item.sentiment === "POSITIVE") result.positive = item._count._all;
|
||||
if (item.sentiment === "NEGATIVE") result.negative = item._count._all;
|
||||
if (item.sentiment === "NEUTRAL") result.neutral = item._count._all;
|
||||
});
|
||||
|
||||
return NextResponse.json(result);
|
||||
return NextResponse.json({ success: true, data: result }, { status: 200 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return [];
|
||||
console.error("Gagal mengambil data sentimen:", error);
|
||||
return NextResponse.json(
|
||||
{ success: false, message: "Internal Server Error" },
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,7 +143,6 @@ export default function DashboardClient() {
|
|||
</p>
|
||||
</div>
|
||||
<BrandFilter
|
||||
// brands={brandData}
|
||||
selectedBrand={selectedBrand}
|
||||
onSelect={setSelectedBrand}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -19,16 +19,22 @@ export const useDashboards = () => {
|
|||
useEffect(() => {
|
||||
async function fetchStats() {
|
||||
setLoading(true);
|
||||
const res = await fetch("/api/review/sentiment-stats");
|
||||
const data = await res.json();
|
||||
|
||||
const total = data.positive + data.negative + data.neutral;
|
||||
const res = await fetch("/api/review/sentiment-stats");
|
||||
const json = await res.json();
|
||||
|
||||
const statsData = json.data;
|
||||
|
||||
const total =
|
||||
(statsData?.positive ?? 0) +
|
||||
(statsData?.negative ?? 0) +
|
||||
(statsData?.neutral ?? 0);
|
||||
|
||||
setStats({
|
||||
totalReviews: total ?? 0,
|
||||
positive: data.positive ?? 0,
|
||||
negative: data.negative ?? 0,
|
||||
neutral: data.neutral ?? 0,
|
||||
totalReviews: total,
|
||||
positive: statsData?.positive ?? 0,
|
||||
negative: statsData?.negative ?? 0,
|
||||
neutral: statsData?.neutral ?? 0,
|
||||
});
|
||||
|
||||
setLoading(false);
|
||||
|
|
|
|||
Loading…
Reference in New Issue