diff --git a/prisma/migrations/20260212102528_update_model_cardinality/migration.sql b/prisma/migrations/20260212102528_update_model_cardinality/migration.sql new file mode 100644 index 0000000..315fdf9 --- /dev/null +++ b/prisma/migrations/20260212102528_update_model_cardinality/migration.sql @@ -0,0 +1,71 @@ +/* + 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; diff --git a/prisma/migrations/20260212110614_update_top_keyword_rows/migration.sql b/prisma/migrations/20260212110614_update_top_keyword_rows/migration.sql new file mode 100644 index 0000000..326a4f8 --- /dev/null +++ b/prisma/migrations/20260212110614_update_top_keyword_rows/migration.sql @@ -0,0 +1,17 @@ +/* + 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; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 06eeada..ed8361e 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -6,33 +6,38 @@ datasource db { provider = "postgresql" } +// --- ENUMS --- enum UserGender { male female other } +enum Role { + USER + ADMIN +} + enum Sentiment { - positive - negative - neutral + POSITIVE + NEGATIVE + NEUTRAL } model Account { - id Int @id @default(autoincrement()) - userId Int - type String - provider String - providerAccountId String - refresh_token String? - access_token String? - expires_at Int? - token_type String? - scope String? - id_token String? - session_state String? - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) + id Int @id @default(autoincrement()) + userId Int + type String + provider String + providerAccountId String + refresh_token String? + access_token String? + expires_at Int? + token_type String? + scope String? + id_token String? + session_state String? + user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([provider, providerAccountId]) } @@ -42,8 +47,7 @@ model Session { sessionToken String @unique userId Int expires DateTime - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model VerificationToken { @@ -54,76 +58,93 @@ model VerificationToken { @@unique([identifier, token]) } - model User { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) name String? - email String? @unique + email String? @unique emailVerified DateTime? image String? gender UserGender? - productReference String? - password String? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt + password String? + role Role @default(USER) + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + accounts Account[] sessions Session[] - analysis Analysis[] -} - -model Analysis { - id Int @id @default(autoincrement()) - userId Int - reviewId Int - productId Int - modelId Int - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - user User @relation(fields: [userId], references: [id]) - review Review @relation(fields: [reviewId], references: [id]) - product Product @relation(fields: [productId], references: [id]) - model Model @relation(fields: [modelId], references: [id]) + + analyses Analysis[] } model Product { id Int @id @default(autoincrement()) name String - brand String + brand String? + url String @unique + image String? + createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - reviews Review[] - analysis Analysis[] + reviews Review[] + analyses Analysis[] } model Review { id Int @id @default(autoincrement()) - productId Int - modelId Int - content String - keywords String[] - sentiment Sentiment - confidenceScore Float + content String + sentiment Sentiment + confidenceScore Float + keywords String[] + createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - product Product @relation(fields: [productId], references: [id]) - model Model @relation(fields: [modelId], references: [id]) - analysis Analysis[] + productId Int + product Product @relation(fields: [productId], references: [id], onDelete: Cascade) + + modelId Int? + model Model? @relation(fields: [modelId], references: [id]) +} + +model Analysis { + id Int @id @default(autoincrement()) + + targetProfession String + + generalSentiment Float + compatibilityScore Float + verdict String + + topKeywords String[] + + createdAt DateTime @default(now()) + + userId Int + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + productId Int + product Product @relation(fields: [productId], references: [id], onDelete: Cascade) + + modelId Int + model Model @relation(fields: [modelId], references: [id]) } model Model { id Int @id @default(autoincrement()) - modelName String - description String + modelName String + description String? + version String? + accuracy Float macroF1 Float f1Negative Float f1Neutral Float + createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - analysis Analysis[] - review Review[] -} + analyses Analysis[] + reviews Review[] +} \ No newline at end of file diff --git a/src/components/dashboards/SentimentAnalyzer.tsx b/src/components/dashboards/SentimentAnalyzer.tsx index 32d85e3..549b330 100644 --- a/src/components/dashboards/SentimentAnalyzer.tsx +++ b/src/components/dashboards/SentimentAnalyzer.tsx @@ -19,7 +19,7 @@ import { Badge } from "../ui/badge"; import { getSentimentDisplay } from "@/src/utils/datas"; import { useSentimentForm } from "@/src/hooks/useSentimentForm"; -export default function SentimentForm() { +export default function SentimentAnalyzer() { const { selectedModel, searchQuery, diff --git a/src/utils/datas.ts b/src/utils/datas.ts index 68bdcce..1d80c81 100644 --- a/src/utils/datas.ts +++ b/src/utils/datas.ts @@ -1,5 +1,5 @@ import { Frown, Meh, Smile } from "lucide-react"; -import { WordCloudConfig, WordItem } from "../types"; +import { ScrapeResult, WordCloudConfig, WordItem } from "../types"; export const MODEL_OPTIONS = [ {