mirror of
https://github.com/f/awesome-chatgpt-prompts.git
synced 2026-03-03 02:57:01 +00:00
Initialize v2 work
This commit is contained in:
228
prisma/migrations/20251208165032/migration.sql
Normal file
228
prisma/migrations/20251208165032/migration.sql
Normal file
@@ -0,0 +1,228 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "UserRole" AS ENUM ('ADMIN', 'USER');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "PromptType" AS ENUM ('TEXT', 'IMAGE', 'VIDEO', 'AUDIO');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ChangeRequestStatus" AS ENUM ('PENDING', 'APPROVED', 'REJECTED');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "users" (
|
||||
"id" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"username" TEXT NOT NULL,
|
||||
"name" TEXT,
|
||||
"password" TEXT,
|
||||
"avatar" TEXT,
|
||||
"role" "UserRole" NOT NULL DEFAULT 'USER',
|
||||
"locale" TEXT NOT NULL DEFAULT 'en',
|
||||
"emailVerified" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "accounts" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT 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 "accounts_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "sessions" (
|
||||
"id" TEXT NOT NULL,
|
||||
"sessionToken" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"expires" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "sessions_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "verification_tokens" (
|
||||
"identifier" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"expires" TIMESTAMP(3) NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "prompts" (
|
||||
"id" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"content" TEXT NOT NULL,
|
||||
"type" "PromptType" NOT NULL DEFAULT 'TEXT',
|
||||
"isPrivate" BOOLEAN NOT NULL DEFAULT false,
|
||||
"mediaUrl" TEXT,
|
||||
"viewCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"authorId" TEXT NOT NULL,
|
||||
"categoryId" TEXT,
|
||||
|
||||
CONSTRAINT "prompts_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "prompt_versions" (
|
||||
"id" TEXT NOT NULL,
|
||||
"version" INTEGER NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"changeNote" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"promptId" TEXT NOT NULL,
|
||||
"createdBy" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "prompt_versions_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "change_requests" (
|
||||
"id" TEXT NOT NULL,
|
||||
"proposedContent" TEXT NOT NULL,
|
||||
"proposedTitle" TEXT,
|
||||
"reason" TEXT,
|
||||
"status" "ChangeRequestStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"reviewNote" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"promptId" TEXT NOT NULL,
|
||||
"authorId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "change_requests_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "categories" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"slug" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"icon" TEXT,
|
||||
"order" INTEGER NOT NULL DEFAULT 0,
|
||||
"parentId" TEXT,
|
||||
|
||||
CONSTRAINT "categories_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "tags" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"slug" TEXT NOT NULL,
|
||||
"color" TEXT NOT NULL DEFAULT '#6366f1',
|
||||
|
||||
CONSTRAINT "tags_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "prompt_tags" (
|
||||
"promptId" TEXT NOT NULL,
|
||||
"tagId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "prompt_tags_pkey" PRIMARY KEY ("promptId","tagId")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "users_username_key" ON "users"("username");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "accounts_provider_providerAccountId_key" ON "accounts"("provider", "providerAccountId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "sessions_sessionToken_key" ON "sessions"("sessionToken");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "verification_tokens_token_key" ON "verification_tokens"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "verification_tokens_identifier_token_key" ON "verification_tokens"("identifier", "token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "prompts_authorId_idx" ON "prompts"("authorId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "prompts_categoryId_idx" ON "prompts"("categoryId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "prompts_type_idx" ON "prompts"("type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "prompts_isPrivate_idx" ON "prompts"("isPrivate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "prompt_versions_promptId_idx" ON "prompt_versions"("promptId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "prompt_versions_promptId_version_key" ON "prompt_versions"("promptId", "version");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "change_requests_promptId_idx" ON "change_requests"("promptId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "change_requests_authorId_idx" ON "change_requests"("authorId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "change_requests_status_idx" ON "change_requests"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "categories_slug_key" ON "categories"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "categories_parentId_idx" ON "categories"("parentId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "tags_name_key" ON "tags"("name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "tags_slug_key" ON "tags"("slug");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "accounts" ADD CONSTRAINT "accounts_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "sessions" ADD CONSTRAINT "sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "prompts" ADD CONSTRAINT "prompts_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "prompts" ADD CONSTRAINT "prompts_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "categories"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "prompt_versions" ADD CONSTRAINT "prompt_versions_promptId_fkey" FOREIGN KEY ("promptId") REFERENCES "prompts"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "prompt_versions" ADD CONSTRAINT "prompt_versions_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "change_requests" ADD CONSTRAINT "change_requests_promptId_fkey" FOREIGN KEY ("promptId") REFERENCES "prompts"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "change_requests" ADD CONSTRAINT "change_requests_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "categories" ADD CONSTRAINT "categories_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "categories"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "prompt_tags" ADD CONSTRAINT "prompt_tags_promptId_fkey" FOREIGN KEY ("promptId") REFERENCES "prompts"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "prompt_tags" ADD CONSTRAINT "prompt_tags_tagId_fkey" FOREIGN KEY ("tagId") REFERENCES "tags"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
20
prisma/migrations/20251208185808_init/migration.sql
Normal file
20
prisma/migrations/20251208185808_init/migration.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "category_subscriptions" (
|
||||
"userId" TEXT NOT NULL,
|
||||
"categoryId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "category_subscriptions_pkey" PRIMARY KEY ("userId","categoryId")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "category_subscriptions_userId_idx" ON "category_subscriptions"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "category_subscriptions_categoryId_idx" ON "category_subscriptions"("categoryId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "category_subscriptions" ADD CONSTRAINT "category_subscriptions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "category_subscriptions" ADD CONSTRAINT "category_subscriptions_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "categories"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
3
prisma/migrations/migration_lock.toml
Normal file
3
prisma/migrations/migration_lock.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "postgresql"
|
||||
313
prisma/schema.prisma
Normal file
313
prisma/schema.prisma
Normal file
@@ -0,0 +1,313 @@
|
||||
// Prisma schema for prompts.chat
|
||||
// https://pris.ly/d/prisma-schema
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// User & Authentication
|
||||
// ============================================
|
||||
|
||||
enum UserRole {
|
||||
ADMIN
|
||||
USER
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
username String @unique
|
||||
name String?
|
||||
password String? // For credentials auth
|
||||
avatar String?
|
||||
role UserRole @default(USER)
|
||||
locale String @default("en")
|
||||
emailVerified DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
prompts Prompt[] @relation("PromptAuthor")
|
||||
contributions Prompt[] @relation("PromptContributors")
|
||||
promptVersions PromptVersion[]
|
||||
changeRequests ChangeRequest[]
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
subscriptions CategorySubscription[]
|
||||
votes PromptVote[]
|
||||
pinnedPrompts PinnedPrompt[]
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
model Account {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
type String
|
||||
provider String
|
||||
providerAccountId String
|
||||
refresh_token String? @db.Text
|
||||
access_token String? @db.Text
|
||||
expires_at Int?
|
||||
token_type String?
|
||||
scope String?
|
||||
id_token String? @db.Text
|
||||
session_state String?
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([provider, providerAccountId])
|
||||
@@map("accounts")
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id @default(cuid())
|
||||
sessionToken String @unique
|
||||
userId String
|
||||
expires DateTime
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@map("sessions")
|
||||
}
|
||||
|
||||
model VerificationToken {
|
||||
identifier String
|
||||
token String @unique
|
||||
expires DateTime
|
||||
|
||||
@@unique([identifier, token])
|
||||
@@map("verification_tokens")
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Prompts & Content
|
||||
// ============================================
|
||||
|
||||
enum PromptType {
|
||||
TEXT
|
||||
IMAGE
|
||||
VIDEO
|
||||
AUDIO
|
||||
STRUCTURED
|
||||
}
|
||||
|
||||
enum StructuredFormat {
|
||||
JSON
|
||||
YAML
|
||||
}
|
||||
|
||||
enum ChangeRequestStatus {
|
||||
PENDING
|
||||
APPROVED
|
||||
REJECTED
|
||||
}
|
||||
|
||||
enum RequiredMediaType {
|
||||
IMAGE
|
||||
VIDEO
|
||||
DOCUMENT
|
||||
}
|
||||
|
||||
model Prompt {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
description String?
|
||||
content String @db.Text
|
||||
type PromptType @default(TEXT)
|
||||
structuredFormat StructuredFormat? // For STRUCTURED type: JSON or YAML
|
||||
isPrivate Boolean @default(false)
|
||||
mediaUrl String? // For non-text prompts
|
||||
|
||||
// Media requirements (user needs to upload media to use this prompt)
|
||||
requiresMediaUpload Boolean @default(false)
|
||||
requiredMediaType RequiredMediaType?
|
||||
requiredMediaCount Int?
|
||||
|
||||
// Metadata
|
||||
viewCount Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
authorId String
|
||||
author User @relation("PromptAuthor", fields: [authorId], references: [id], onDelete: Cascade)
|
||||
categoryId String?
|
||||
category Category? @relation(fields: [categoryId], references: [id], onDelete: SetNull)
|
||||
|
||||
versions PromptVersion[]
|
||||
changeRequests ChangeRequest[]
|
||||
tags PromptTag[]
|
||||
votes PromptVote[]
|
||||
contributors User[] @relation("PromptContributors")
|
||||
pinnedBy PinnedPrompt[]
|
||||
|
||||
@@index([authorId])
|
||||
@@index([categoryId])
|
||||
@@index([type])
|
||||
@@index([isPrivate])
|
||||
@@map("prompts")
|
||||
}
|
||||
|
||||
model PromptVersion {
|
||||
id String @id @default(cuid())
|
||||
version Int
|
||||
content String @db.Text
|
||||
changeNote String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
// Relations
|
||||
promptId String
|
||||
prompt Prompt @relation(fields: [promptId], references: [id], onDelete: Cascade)
|
||||
createdBy String
|
||||
author User @relation(fields: [createdBy], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([promptId, version])
|
||||
@@index([promptId])
|
||||
@@map("prompt_versions")
|
||||
}
|
||||
|
||||
model ChangeRequest {
|
||||
id String @id @default(cuid())
|
||||
originalContent String @db.Text
|
||||
originalTitle String
|
||||
proposedContent String @db.Text
|
||||
proposedTitle String?
|
||||
reason String?
|
||||
status ChangeRequestStatus @default(PENDING)
|
||||
reviewNote String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
promptId String
|
||||
prompt Prompt @relation(fields: [promptId], references: [id], onDelete: Cascade)
|
||||
authorId String
|
||||
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([promptId])
|
||||
@@index([authorId])
|
||||
@@index([status])
|
||||
@@map("change_requests")
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Categories & Tags
|
||||
// ============================================
|
||||
|
||||
model Category {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
slug String @unique
|
||||
description String?
|
||||
icon String?
|
||||
order Int @default(0)
|
||||
|
||||
// Self-referential for hierarchy
|
||||
parentId String?
|
||||
parent Category? @relation("CategoryHierarchy", fields: [parentId], references: [id], onDelete: SetNull)
|
||||
children Category[] @relation("CategoryHierarchy")
|
||||
|
||||
prompts Prompt[]
|
||||
subscribers CategorySubscription[]
|
||||
|
||||
@@index([parentId])
|
||||
@@map("categories")
|
||||
}
|
||||
|
||||
model Tag {
|
||||
id String @id @default(cuid())
|
||||
name String @unique
|
||||
slug String @unique
|
||||
color String @default("#6366f1")
|
||||
|
||||
prompts PromptTag[]
|
||||
|
||||
@@map("tags")
|
||||
}
|
||||
|
||||
model PromptTag {
|
||||
promptId String
|
||||
tagId String
|
||||
prompt Prompt @relation(fields: [promptId], references: [id], onDelete: Cascade)
|
||||
tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@id([promptId, tagId])
|
||||
@@map("prompt_tags")
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Subscriptions
|
||||
// ============================================
|
||||
|
||||
model CategorySubscription {
|
||||
userId String
|
||||
categoryId String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
category Category @relation(fields: [categoryId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@id([userId, categoryId])
|
||||
@@index([userId])
|
||||
@@index([categoryId])
|
||||
@@map("category_subscriptions")
|
||||
}
|
||||
|
||||
model PromptVote {
|
||||
userId String
|
||||
promptId String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
prompt Prompt @relation(fields: [promptId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@id([userId, promptId])
|
||||
@@index([userId])
|
||||
@@index([promptId])
|
||||
@@map("prompt_votes")
|
||||
}
|
||||
|
||||
model PinnedPrompt {
|
||||
userId String
|
||||
promptId String
|
||||
order Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
prompt Prompt @relation(fields: [promptId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@id([userId, promptId])
|
||||
@@index([userId])
|
||||
@@map("pinned_prompts")
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Webhook Integration
|
||||
// ============================================
|
||||
|
||||
enum WebhookEvent {
|
||||
PROMPT_CREATED
|
||||
PROMPT_UPDATED
|
||||
PROMPT_DELETED
|
||||
}
|
||||
|
||||
model WebhookConfig {
|
||||
id String @id @default(cuid())
|
||||
name String // e.g. "Slack Notifications"
|
||||
url String // Webhook URL
|
||||
method String @default("POST") // HTTP method
|
||||
headers Json? // Custom headers as JSON object
|
||||
payload String @db.Text // JSON template with placeholders
|
||||
events WebhookEvent[] // Which events trigger this webhook
|
||||
isEnabled Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("webhook_configs")
|
||||
}
|
||||
616
prisma/seed.ts
Normal file
616
prisma/seed.ts
Normal file
@@ -0,0 +1,616 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
console.log("🌱 Seeding database...");
|
||||
|
||||
// Create users
|
||||
const password = await bcrypt.hash("password123", 12);
|
||||
|
||||
const admin = await prisma.user.upsert({
|
||||
where: { email: "admin@prompts.chat" },
|
||||
update: {},
|
||||
create: {
|
||||
email: "admin@prompts.chat",
|
||||
username: "admin",
|
||||
name: "Admin User",
|
||||
password: password,
|
||||
role: "ADMIN",
|
||||
locale: "en",
|
||||
},
|
||||
});
|
||||
|
||||
const demo = await prisma.user.upsert({
|
||||
where: { email: "demo@prompts.chat" },
|
||||
update: {},
|
||||
create: {
|
||||
email: "demo@prompts.chat",
|
||||
username: "demo",
|
||||
name: "Demo User",
|
||||
password: password,
|
||||
role: "USER",
|
||||
locale: "en",
|
||||
},
|
||||
});
|
||||
|
||||
const alice = await prisma.user.upsert({
|
||||
where: { email: "alice@example.com" },
|
||||
update: {},
|
||||
create: {
|
||||
email: "alice@example.com",
|
||||
username: "alice",
|
||||
name: "Alice Johnson",
|
||||
password: password,
|
||||
role: "USER",
|
||||
locale: "en",
|
||||
},
|
||||
});
|
||||
|
||||
const bob = await prisma.user.upsert({
|
||||
where: { email: "bob@example.com" },
|
||||
update: {},
|
||||
create: {
|
||||
email: "bob@example.com",
|
||||
username: "bob",
|
||||
name: "Bob Smith",
|
||||
password: password,
|
||||
role: "USER",
|
||||
locale: "tr",
|
||||
},
|
||||
});
|
||||
|
||||
const charlie = await prisma.user.upsert({
|
||||
where: { email: "charlie@example.com" },
|
||||
update: {},
|
||||
create: {
|
||||
email: "charlie@example.com",
|
||||
username: "charlie",
|
||||
name: "Charlie Brown",
|
||||
password: password,
|
||||
role: "USER",
|
||||
locale: "en",
|
||||
},
|
||||
});
|
||||
|
||||
const users = [admin, demo, alice, bob, charlie];
|
||||
console.log("✅ Created", users.length, "users");
|
||||
|
||||
// Create parent categories
|
||||
const coding = await prisma.category.upsert({
|
||||
where: { slug: "coding" },
|
||||
update: {},
|
||||
create: { name: "Coding", slug: "coding", description: "Programming and development prompts", icon: "💻", order: 1 },
|
||||
});
|
||||
|
||||
const writing = await prisma.category.upsert({
|
||||
where: { slug: "writing" },
|
||||
update: {},
|
||||
create: { name: "Writing", slug: "writing", description: "Content writing and copywriting", icon: "✍️", order: 2 },
|
||||
});
|
||||
|
||||
const business = await prisma.category.upsert({
|
||||
where: { slug: "business" },
|
||||
update: {},
|
||||
create: { name: "Business", slug: "business", description: "Business strategy and operations", icon: "💼", order: 3 },
|
||||
});
|
||||
|
||||
const creative = await prisma.category.upsert({
|
||||
where: { slug: "creative" },
|
||||
update: {},
|
||||
create: { name: "Creative", slug: "creative", description: "Art, design, and creative work", icon: "🎨", order: 4 },
|
||||
});
|
||||
|
||||
const education = await prisma.category.upsert({
|
||||
where: { slug: "education" },
|
||||
update: {},
|
||||
create: { name: "Education", slug: "education", description: "Learning and teaching prompts", icon: "📚", order: 5 },
|
||||
});
|
||||
|
||||
// Create nested categories (children)
|
||||
const webDev = await prisma.category.upsert({
|
||||
where: { slug: "web-development" },
|
||||
update: {},
|
||||
create: { name: "Web Development", slug: "web-development", description: "Frontend and backend web development", parentId: coding.id, order: 1 },
|
||||
});
|
||||
|
||||
const mobileDev = await prisma.category.upsert({
|
||||
where: { slug: "mobile-development" },
|
||||
update: {},
|
||||
create: { name: "Mobile Development", slug: "mobile-development", description: "iOS and Android development", parentId: coding.id, order: 2 },
|
||||
});
|
||||
|
||||
const devops = await prisma.category.upsert({
|
||||
where: { slug: "devops" },
|
||||
update: {},
|
||||
create: { name: "DevOps", slug: "devops", description: "CI/CD, cloud, and infrastructure", parentId: coding.id, order: 3 },
|
||||
});
|
||||
|
||||
const dataScience = await prisma.category.upsert({
|
||||
where: { slug: "data-science" },
|
||||
update: {},
|
||||
create: { name: "Data Science", slug: "data-science", description: "ML, AI, and data analysis", parentId: coding.id, order: 4 },
|
||||
});
|
||||
|
||||
const blogWriting = await prisma.category.upsert({
|
||||
where: { slug: "blog-writing" },
|
||||
update: {},
|
||||
create: { name: "Blog Writing", slug: "blog-writing", description: "Blog posts and articles", parentId: writing.id, order: 1 },
|
||||
});
|
||||
|
||||
const copywriting = await prisma.category.upsert({
|
||||
where: { slug: "copywriting" },
|
||||
update: {},
|
||||
create: { name: "Copywriting", slug: "copywriting", description: "Sales and marketing copy", parentId: writing.id, order: 2 },
|
||||
});
|
||||
|
||||
const technicalWriting = await prisma.category.upsert({
|
||||
where: { slug: "technical-writing" },
|
||||
update: {},
|
||||
create: { name: "Technical Writing", slug: "technical-writing", description: "Documentation and guides", parentId: writing.id, order: 3 },
|
||||
});
|
||||
|
||||
const marketing = await prisma.category.upsert({
|
||||
where: { slug: "marketing" },
|
||||
update: {},
|
||||
create: { name: "Marketing", slug: "marketing", description: "Marketing and advertising prompts", parentId: business.id, order: 1 },
|
||||
});
|
||||
|
||||
const sales = await prisma.category.upsert({
|
||||
where: { slug: "sales" },
|
||||
update: {},
|
||||
create: { name: "Sales", slug: "sales", description: "Sales strategies and outreach", parentId: business.id, order: 2 },
|
||||
});
|
||||
|
||||
const hr = await prisma.category.upsert({
|
||||
where: { slug: "hr" },
|
||||
update: {},
|
||||
create: { name: "HR & Recruiting", slug: "hr", description: "Human resources and hiring", parentId: business.id, order: 3 },
|
||||
});
|
||||
|
||||
const imageGen = await prisma.category.upsert({
|
||||
where: { slug: "image-generation" },
|
||||
update: {},
|
||||
create: { name: "Image Generation", slug: "image-generation", description: "AI image prompts", parentId: creative.id, order: 1 },
|
||||
});
|
||||
|
||||
const music = await prisma.category.upsert({
|
||||
where: { slug: "music" },
|
||||
update: {},
|
||||
create: { name: "Music", slug: "music", description: "Music and audio generation", parentId: creative.id, order: 2 },
|
||||
});
|
||||
|
||||
// Create Workflows category (for structured prompts)
|
||||
const workflows = await prisma.category.upsert({
|
||||
where: { slug: "workflows" },
|
||||
update: {},
|
||||
create: { name: "Workflows", slug: "workflows", description: "Structured AI workflows and pipelines", icon: "⚡", order: 6 },
|
||||
});
|
||||
|
||||
const agentWorkflows = await prisma.category.upsert({
|
||||
where: { slug: "agent-workflows" },
|
||||
update: {},
|
||||
create: { name: "Agent Workflows", slug: "agent-workflows", description: "Multi-step AI agent configurations", parentId: workflows.id, order: 1 },
|
||||
});
|
||||
|
||||
const automations = await prisma.category.upsert({
|
||||
where: { slug: "automations" },
|
||||
update: {},
|
||||
create: { name: "Automations", slug: "automations", description: "Automated task pipelines", parentId: workflows.id, order: 2 },
|
||||
});
|
||||
|
||||
const categories = [coding, writing, business, creative, education, workflows, webDev, mobileDev, devops, dataScience, blogWriting, copywriting, technicalWriting, marketing, sales, hr, imageGen, music, agentWorkflows, automations];
|
||||
console.log("✅ Created", categories.length, "categories (including nested)");
|
||||
|
||||
// Create tags
|
||||
const tags = await Promise.all([
|
||||
prisma.tag.upsert({
|
||||
where: { slug: "gpt-4" },
|
||||
update: {},
|
||||
create: { name: "GPT-4", slug: "gpt-4", color: "#10B981" },
|
||||
}),
|
||||
prisma.tag.upsert({
|
||||
where: { slug: "claude" },
|
||||
update: {},
|
||||
create: { name: "Claude", slug: "claude", color: "#8B5CF6" },
|
||||
}),
|
||||
prisma.tag.upsert({
|
||||
where: { slug: "midjourney" },
|
||||
update: {},
|
||||
create: { name: "Midjourney", slug: "midjourney", color: "#F59E0B" },
|
||||
}),
|
||||
prisma.tag.upsert({
|
||||
where: { slug: "dalle" },
|
||||
update: {},
|
||||
create: { name: "DALL-E", slug: "dalle", color: "#EC4899" },
|
||||
}),
|
||||
prisma.tag.upsert({
|
||||
where: { slug: "beginner" },
|
||||
update: {},
|
||||
create: { name: "Beginner", slug: "beginner", color: "#06B6D4" },
|
||||
}),
|
||||
prisma.tag.upsert({
|
||||
where: { slug: "advanced" },
|
||||
update: {},
|
||||
create: { name: "Advanced", slug: "advanced", color: "#EF4444" },
|
||||
}),
|
||||
prisma.tag.upsert({
|
||||
where: { slug: "chain-of-thought" },
|
||||
update: {},
|
||||
create: { name: "Chain of Thought", slug: "chain-of-thought", color: "#3B82F6" },
|
||||
}),
|
||||
prisma.tag.upsert({
|
||||
where: { slug: "system-prompt" },
|
||||
update: {},
|
||||
create: { name: "System Prompt", slug: "system-prompt", color: "#6366F1" },
|
||||
}),
|
||||
prisma.tag.upsert({
|
||||
where: { slug: "workflow" },
|
||||
update: {},
|
||||
create: { name: "Workflow", slug: "workflow", color: "#F97316" },
|
||||
}),
|
||||
prisma.tag.upsert({
|
||||
where: { slug: "agent" },
|
||||
update: {},
|
||||
create: { name: "Agent", slug: "agent", color: "#14B8A6" },
|
||||
}),
|
||||
]);
|
||||
console.log("✅ Created", tags.length, "tags");
|
||||
|
||||
// Create sample prompts - distributed among users
|
||||
const prompts = [
|
||||
// Admin's prompts
|
||||
{ title: "Code Review Assistant", description: "A prompt for thorough code reviews", content: `You are an expert code reviewer. Review the following code:\n\n{{code}}\n\nProvide:\n1. Summary\n2. Strengths\n3. Issues\n4. Improvements\n5. Performance suggestions`, type: "TEXT", categorySlug: "web-development", tagSlugs: ["gpt-4", "advanced"], authorId: admin.id },
|
||||
{ title: "Expert System Prompt", description: "Turn AI into a domain expert", content: `You are an expert {{role}} with {{years}} years of experience in {{domain}}. Be precise, professional, and provide actionable insights.`, type: "TEXT", categorySlug: "coding", tagSlugs: ["system-prompt", "advanced", "gpt-4"], authorId: admin.id },
|
||||
{ title: "Lesson Plan Creator", description: "Create structured lesson plans", content: `Create a lesson plan for {{subject}} - {{topic}} for {{grade}} level. Include objectives, materials, activities, and assessment.`, type: "TEXT", categorySlug: "education", tagSlugs: ["gpt-4", "beginner"], authorId: admin.id },
|
||||
{ title: "DALL-E Product Mockup", description: "Professional product mockups", content: `A professional product photo of {{product}} on {{surface}}, soft studio lighting, high-end advertising style, 4k`, type: "IMAGE", categorySlug: "image-generation", tagSlugs: ["dalle", "beginner"], authorId: admin.id },
|
||||
{ title: "Email Response Generator", description: "Professional email responses", content: `Write a professional email response to: {{original_email}}\n\nTone: {{tone}}\nDesired outcome: {{outcome}}`, type: "TEXT", categorySlug: "business", tagSlugs: ["gpt-4", "beginner"], authorId: admin.id },
|
||||
|
||||
// Demo user's prompts
|
||||
{ title: "Blog Post Generator", description: "Generate engaging blog posts", content: `Write a blog post about {{topic}} for {{audience}}. Include engaging intro, 3-5 sections, practical tips, and CTA. Word count: {{word_count}}`, type: "TEXT", categorySlug: "blog-writing", tagSlugs: ["gpt-4", "beginner"], authorId: demo.id },
|
||||
{ title: "SWOT Analysis Generator", description: "Comprehensive SWOT analysis", content: `Conduct a SWOT analysis for {{subject}} in {{industry}}. Provide Strengths, Weaknesses, Opportunities, Threats, and Strategic Recommendations.`, type: "TEXT", categorySlug: "business", tagSlugs: ["gpt-4", "chain-of-thought"], authorId: demo.id },
|
||||
{ title: "Midjourney Fantasy Landscape", description: "Stunning fantasy landscape images", content: `A breathtaking fantasy landscape, {{scene_type}}, ancient ruins, floating islands, dramatic lighting, volumetric fog, 8k --ar 16:9 --v 6`, type: "IMAGE", categorySlug: "image-generation", tagSlugs: ["midjourney", "advanced"], authorId: demo.id },
|
||||
{ title: "Debug Assistant", description: "Systematic debugging help", content: `Debug this issue:\n\nError: {{error}}\nCode: {{code}}\nTried: {{attempts}}\n\nExplain the error, root cause, fix, and prevention.`, type: "TEXT", categorySlug: "coding", tagSlugs: ["gpt-4", "claude", "chain-of-thought"], authorId: demo.id },
|
||||
|
||||
// Alice's prompts
|
||||
{ title: "React Component Generator", description: "Generate React components with TypeScript", content: `Create a React component for {{component_name}} with TypeScript. Include props interface, hooks if needed, and basic styling.`, type: "TEXT", categorySlug: "web-development", tagSlugs: ["gpt-4", "advanced"], authorId: alice.id },
|
||||
{ title: "API Documentation Writer", description: "Generate API documentation", content: `Write API documentation for {{endpoint}}:\n\nMethod: {{method}}\nParameters: {{params}}\nResponse: {{response}}\n\nInclude examples and error codes.`, type: "TEXT", categorySlug: "technical-writing", tagSlugs: ["gpt-4", "beginner"], authorId: alice.id },
|
||||
{ title: "Social Media Content Calendar", description: "Plan social media content", content: `Create a {{duration}} social media content calendar for {{brand}} targeting {{audience}}. Include post ideas, hashtags, and best posting times.`, type: "TEXT", categorySlug: "marketing", tagSlugs: ["claude", "beginner"], authorId: alice.id },
|
||||
{ title: "UX Research Questions", description: "Generate user research questions", content: `Create user research questions for {{product}} focusing on {{feature}}. Include open-ended, rating, and follow-up questions.`, type: "TEXT", categorySlug: "business", tagSlugs: ["gpt-4", "beginner"], authorId: alice.id },
|
||||
|
||||
// Bob's prompts
|
||||
{ title: "SQL Query Optimizer", description: "Optimize SQL queries", content: `Analyze and optimize this SQL query:\n\n{{query}}\n\nProvide: execution plan analysis, index suggestions, and optimized query.`, type: "TEXT", categorySlug: "data-science", tagSlugs: ["gpt-4", "advanced"], authorId: bob.id },
|
||||
{ title: "Docker Compose Generator", description: "Generate Docker Compose files", content: `Create a Docker Compose file for {{stack}} with {{services}}. Include environment variables, volumes, and networks.`, type: "TEXT", categorySlug: "devops", tagSlugs: ["gpt-4", "advanced"], authorId: bob.id },
|
||||
{ title: "Job Description Writer", description: "Write compelling job descriptions", content: `Write a job description for {{position}} at {{company}}. Include responsibilities, requirements, benefits, and company culture.`, type: "TEXT", categorySlug: "hr", tagSlugs: ["claude", "beginner"], authorId: bob.id },
|
||||
{ title: "Sales Email Sequence", description: "Create sales email sequences", content: `Create a {{length}}-email sequence for {{product}} targeting {{persona}}. Include subject lines, personalization, and CTAs.`, type: "TEXT", categorySlug: "sales", tagSlugs: ["gpt-4", "advanced"], authorId: bob.id },
|
||||
|
||||
// Charlie's prompts
|
||||
{ title: "Mobile App Onboarding Flow", description: "Design onboarding experiences", content: `Design an onboarding flow for {{app_name}} ({{platform}}). Include screens, copy, and user actions for first-time users.`, type: "TEXT", categorySlug: "mobile-development", tagSlugs: ["claude", "beginner"], authorId: charlie.id },
|
||||
{ title: "Product Copywriter", description: "Compelling product copy", content: `Write product copy for {{product_name}}:\n\nFeatures: {{features}}\nTarget: {{target}}\n\nInclude headline, benefits, and CTA.`, type: "TEXT", categorySlug: "copywriting", tagSlugs: ["gpt-4", "beginner"], authorId: charlie.id },
|
||||
{ title: "Meeting Notes Summarizer", description: "Summarize meeting notes", content: `Summarize this meeting:\n\n{{transcript}}\n\nProvide: key decisions, action items, owners, and deadlines.`, type: "TEXT", categorySlug: "business", tagSlugs: ["gpt-4", "beginner"], authorId: charlie.id },
|
||||
{ title: "Music Prompt Generator", description: "Generate music with AI", content: `Create a {{genre}} track with {{mood}} feel. BPM: {{bpm}}, Key: {{key}}. Include intro, verse, chorus structure.`, type: "AUDIO", categorySlug: "music", tagSlugs: ["claude", "advanced"], authorId: charlie.id },
|
||||
|
||||
// Structured prompts (workflows)
|
||||
{
|
||||
title: "Content Pipeline Workflow",
|
||||
description: "Multi-step content creation pipeline",
|
||||
content: JSON.stringify({
|
||||
name: "Content Creation Pipeline",
|
||||
version: "1.0",
|
||||
steps: [
|
||||
{
|
||||
id: "research",
|
||||
name: "Research Topic",
|
||||
prompt: "Research the topic '{{topic}}' and provide 5 key points with sources",
|
||||
output: "research_results"
|
||||
},
|
||||
{
|
||||
id: "outline",
|
||||
name: "Create Outline",
|
||||
prompt: "Based on {{research_results}}, create a detailed blog post outline",
|
||||
output: "outline",
|
||||
depends_on: ["research"]
|
||||
},
|
||||
{
|
||||
id: "draft",
|
||||
name: "Write Draft",
|
||||
prompt: "Write a {{word_count}} word blog post following this outline: {{outline}}",
|
||||
output: "draft",
|
||||
depends_on: ["outline"]
|
||||
},
|
||||
{
|
||||
id: "review",
|
||||
name: "Review & Edit",
|
||||
prompt: "Review and improve this draft for clarity, grammar, and engagement: {{draft}}",
|
||||
output: "final_content",
|
||||
depends_on: ["draft"]
|
||||
}
|
||||
],
|
||||
variables: {
|
||||
topic: { type: "string", required: true },
|
||||
word_count: { type: "number", default: 1500 }
|
||||
}
|
||||
}, null, 2),
|
||||
type: "STRUCTURED",
|
||||
structuredFormat: "JSON",
|
||||
categorySlug: "automations",
|
||||
tagSlugs: ["workflow", "gpt-4", "advanced"],
|
||||
authorId: admin.id
|
||||
},
|
||||
{
|
||||
title: "Code Review Agent",
|
||||
description: "AI agent for comprehensive code reviews",
|
||||
content: `name: Code Review Agent
|
||||
version: "1.0"
|
||||
description: Multi-pass code review agent
|
||||
|
||||
agent:
|
||||
role: Senior Software Engineer
|
||||
expertise:
|
||||
- Code quality
|
||||
- Security
|
||||
- Performance optimization
|
||||
- Best practices
|
||||
|
||||
workflow:
|
||||
- step: security_scan
|
||||
prompt: |
|
||||
Analyze this code for security vulnerabilities:
|
||||
\`\`\`{{language}}
|
||||
{{code}}
|
||||
\`\`\`
|
||||
Focus on: injection, XSS, authentication issues
|
||||
output: security_report
|
||||
|
||||
- step: performance_review
|
||||
prompt: |
|
||||
Review this code for performance issues:
|
||||
{{code}}
|
||||
Consider: time complexity, memory usage, database queries
|
||||
output: performance_report
|
||||
depends_on: [security_scan]
|
||||
|
||||
- step: best_practices
|
||||
prompt: |
|
||||
Check adherence to {{language}} best practices:
|
||||
{{code}}
|
||||
output: practices_report
|
||||
depends_on: [security_scan]
|
||||
|
||||
- step: final_summary
|
||||
prompt: |
|
||||
Compile a final code review report from:
|
||||
- Security: {{security_report}}
|
||||
- Performance: {{performance_report}}
|
||||
- Best Practices: {{practices_report}}
|
||||
output: final_review
|
||||
depends_on: [performance_review, best_practices]
|
||||
|
||||
variables:
|
||||
code:
|
||||
type: string
|
||||
required: true
|
||||
language:
|
||||
type: string
|
||||
default: typescript`,
|
||||
type: "STRUCTURED",
|
||||
structuredFormat: "YAML",
|
||||
categorySlug: "agent-workflows",
|
||||
tagSlugs: ["agent", "workflow", "claude", "advanced"],
|
||||
authorId: demo.id
|
||||
},
|
||||
{
|
||||
title: "Customer Support Agent",
|
||||
description: "Intelligent customer support workflow",
|
||||
content: JSON.stringify({
|
||||
name: "Customer Support Agent",
|
||||
version: "1.0",
|
||||
agent: {
|
||||
role: "Customer Support Specialist",
|
||||
tone: "friendly, professional, helpful",
|
||||
constraints: [
|
||||
"Never share internal policies",
|
||||
"Escalate billing issues over $1000",
|
||||
"Always verify customer identity first"
|
||||
]
|
||||
},
|
||||
workflow: [
|
||||
{
|
||||
step: "classify",
|
||||
prompt: "Classify this customer inquiry: {{inquiry}}\nCategories: billing, technical, general, complaint",
|
||||
output: "category"
|
||||
},
|
||||
{
|
||||
step: "gather_context",
|
||||
prompt: "What additional information is needed to resolve this {{category}} issue? List specific questions.",
|
||||
output: "followup_questions",
|
||||
depends_on: ["classify"]
|
||||
},
|
||||
{
|
||||
step: "resolve",
|
||||
prompt: "Provide a helpful response for this {{category}} issue: {{inquiry}}\nContext gathered: {{context}}",
|
||||
output: "response",
|
||||
depends_on: ["gather_context"]
|
||||
}
|
||||
],
|
||||
variables: {
|
||||
inquiry: { type: "string", required: true },
|
||||
context: { type: "string", default: "" }
|
||||
}
|
||||
}, null, 2),
|
||||
type: "STRUCTURED",
|
||||
structuredFormat: "JSON",
|
||||
categorySlug: "agent-workflows",
|
||||
tagSlugs: ["agent", "workflow", "gpt-4", "beginner"],
|
||||
authorId: alice.id
|
||||
},
|
||||
{
|
||||
title: "Data Processing Pipeline",
|
||||
description: "ETL-style data transformation workflow",
|
||||
content: `name: Data Processing Pipeline
|
||||
version: "1.0"
|
||||
description: Transform and analyze data with AI
|
||||
|
||||
pipeline:
|
||||
- stage: extract
|
||||
name: Data Extraction
|
||||
prompt: |
|
||||
Extract structured data from this input:
|
||||
{{raw_data}}
|
||||
|
||||
Output as JSON with fields: {{fields}}
|
||||
output: extracted_data
|
||||
|
||||
- stage: transform
|
||||
name: Data Transformation
|
||||
prompt: |
|
||||
Transform this data according to rules:
|
||||
Data: {{extracted_data}}
|
||||
Rules: {{transformation_rules}}
|
||||
output: transformed_data
|
||||
depends_on: [extract]
|
||||
|
||||
- stage: validate
|
||||
name: Data Validation
|
||||
prompt: |
|
||||
Validate this data against schema:
|
||||
Data: {{transformed_data}}
|
||||
Schema: {{validation_schema}}
|
||||
Report any errors or inconsistencies.
|
||||
output: validation_report
|
||||
depends_on: [transform]
|
||||
|
||||
- stage: analyze
|
||||
name: Data Analysis
|
||||
prompt: |
|
||||
Analyze this validated data:
|
||||
{{transformed_data}}
|
||||
|
||||
Provide: summary statistics, patterns, anomalies
|
||||
output: analysis_report
|
||||
depends_on: [validate]
|
||||
|
||||
variables:
|
||||
raw_data:
|
||||
type: string
|
||||
required: true
|
||||
fields:
|
||||
type: array
|
||||
default: [id, name, value, timestamp]
|
||||
transformation_rules:
|
||||
type: string
|
||||
default: "normalize dates, clean text, convert currencies"
|
||||
validation_schema:
|
||||
type: string
|
||||
default: "standard"`,
|
||||
type: "STRUCTURED",
|
||||
structuredFormat: "YAML",
|
||||
categorySlug: "automations",
|
||||
tagSlugs: ["workflow", "claude", "advanced"],
|
||||
authorId: bob.id
|
||||
},
|
||||
];
|
||||
|
||||
for (const promptData of prompts) {
|
||||
const category = categories.find((c) => c.slug === promptData.categorySlug);
|
||||
const promptTags = tags.filter((t) => promptData.tagSlugs.includes(t.slug));
|
||||
|
||||
const existingPrompt = await prisma.prompt.findFirst({
|
||||
where: { title: promptData.title, authorId: promptData.authorId },
|
||||
});
|
||||
|
||||
if (!existingPrompt) {
|
||||
const prompt = await prisma.prompt.create({
|
||||
data: {
|
||||
title: promptData.title,
|
||||
description: promptData.description,
|
||||
content: promptData.content,
|
||||
type: promptData.type as "TEXT" | "IMAGE" | "VIDEO" | "AUDIO" | "STRUCTURED",
|
||||
structuredFormat: (promptData as { structuredFormat?: "JSON" | "YAML" }).structuredFormat,
|
||||
authorId: promptData.authorId,
|
||||
categoryId: category?.id,
|
||||
tags: {
|
||||
create: promptTags.map((tag) => ({ tagId: tag.id })),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Create initial version
|
||||
await prisma.promptVersion.create({
|
||||
data: {
|
||||
promptId: prompt.id,
|
||||
version: 1,
|
||||
content: promptData.content,
|
||||
changeNote: "Initial version",
|
||||
createdBy: promptData.authorId,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
console.log("✅ Created", prompts.length, "prompts");
|
||||
|
||||
// Create comprehensive change requests
|
||||
const allPrompts = await prisma.prompt.findMany();
|
||||
|
||||
const changeRequestsData = [
|
||||
// Pending requests
|
||||
{ id: "cr-1", promptTitle: "Code Review Assistant", authorId: demo.id, reason: "Added best practices section", proposedAddition: "\n\n6. **Best Practices**: Suggest industry best practices.", status: "PENDING" as const },
|
||||
{ id: "cr-2", promptTitle: "Blog Post Generator", authorId: alice.id, reason: "Added SEO tips", proposedAddition: "\n\nInclude meta description and keyword suggestions.", status: "PENDING" as const },
|
||||
{ id: "cr-3", promptTitle: "React Component Generator", authorId: bob.id, reason: "Add accessibility considerations", proposedAddition: "\n\nEnsure ARIA labels and keyboard navigation support.", status: "PENDING" as const },
|
||||
{ id: "cr-4", promptTitle: "SQL Query Optimizer", authorId: charlie.id, reason: "Include explain analyze output", proposedAddition: "\n\nShow EXPLAIN ANALYZE output interpretation.", status: "PENDING" as const },
|
||||
{ id: "cr-5", promptTitle: "Expert System Prompt", authorId: demo.id, reason: "Add error handling guidance", proposedAddition: "\n\nHandle edge cases gracefully and provide fallback responses.", status: "PENDING" as const },
|
||||
|
||||
// Approved requests
|
||||
{ id: "cr-6", promptTitle: "SWOT Analysis Generator", authorId: admin.id, reason: "Added competitive analysis section", proposedAddition: "\n\n## Competitive Position\nCompare against top 3 competitors.", status: "APPROVED" as const, reviewNote: "Great addition! Merged." },
|
||||
{ id: "cr-7", promptTitle: "Debug Assistant", authorId: alice.id, reason: "Include stack trace analysis", proposedAddition: "\n\n6. Analyze the full stack trace if provided.", status: "APPROVED" as const, reviewNote: "Very helpful improvement." },
|
||||
{ id: "cr-8", promptTitle: "Docker Compose Generator", authorId: demo.id, reason: "Add health checks", proposedAddition: "\n\nInclude healthcheck configurations for each service.", status: "APPROVED" as const, reviewNote: "Essential for production setups." },
|
||||
{ id: "cr-9", promptTitle: "API Documentation Writer", authorId: bob.id, reason: "Add rate limiting info", proposedAddition: "\n\nDocument rate limits and throttling policies.", status: "APPROVED" as const, reviewNote: "Good call, this is often missing." },
|
||||
|
||||
// Rejected requests
|
||||
{ id: "cr-10", promptTitle: "Midjourney Fantasy Landscape", authorId: admin.id, reason: "Simplify the prompt", proposedAddition: " (simplified)", status: "REJECTED" as const, reviewNote: "I prefer the detailed version for better results." },
|
||||
{ id: "cr-11", promptTitle: "Sales Email Sequence", authorId: charlie.id, reason: "Make it more aggressive", proposedAddition: "\n\nBe more pushy and urgent.", status: "REJECTED" as const, reviewNote: "This goes against our brand voice guidelines." },
|
||||
{ id: "cr-12", promptTitle: "Job Description Writer", authorId: alice.id, reason: "Remove benefits section", proposedAddition: "", status: "REJECTED" as const, reviewNote: "Benefits are important for attracting candidates." },
|
||||
];
|
||||
|
||||
for (const cr of changeRequestsData) {
|
||||
const prompt = allPrompts.find(p => p.title === cr.promptTitle);
|
||||
if (prompt) {
|
||||
await prisma.changeRequest.upsert({
|
||||
where: { id: cr.id },
|
||||
update: {},
|
||||
create: {
|
||||
id: cr.id,
|
||||
promptId: prompt.id,
|
||||
authorId: cr.authorId,
|
||||
originalContent: prompt.content,
|
||||
originalTitle: prompt.title,
|
||||
proposedContent: prompt.content + cr.proposedAddition,
|
||||
proposedTitle: null,
|
||||
reason: cr.reason,
|
||||
status: cr.status,
|
||||
reviewNote: cr.reviewNote || null,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log("✅ Created", changeRequestsData.length, "change requests");
|
||||
|
||||
console.log("\n🎉 Seeding complete!");
|
||||
console.log("\n📋 Test credentials (all passwords: password123):");
|
||||
console.log(" Admin: admin@prompts.chat");
|
||||
console.log(" Demo: demo@prompts.chat");
|
||||
console.log(" Alice: alice@example.com");
|
||||
console.log(" Bob: bob@example.com");
|
||||
console.log(" Charlie: charlie@example.com");
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error("❌ Seeding failed:", e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
Reference in New Issue
Block a user