fix(header): fix missing Divider, Badge, IconUserShield and navigate
This commit is contained in:
@@ -0,0 +1,568 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ActivityStatus" AS ENUM ('BERJALAN', 'SELESAI', 'TERTUNDA', 'DIBATALKAN');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Priority" AS ENUM ('RENDAH', 'SEDANG', 'TINGGI', 'DARURAT');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "DocumentCategory" AS ENUM ('SURAT_KEPUTUSAN', 'DOKUMENTASI', 'LAPORAN_KEUANGAN', 'NOTULENSI_RAPAT', 'UMUM');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "EventType" AS ENUM ('RAPAT', 'KEGIATAN', 'UPACARA', 'SOSIAL', 'BUDAYA', 'LAINNYA');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ComplaintCategory" AS ENUM ('KETERTIBAN_UMUM', 'PELAYANAN_KESEHATAN', 'INFRASTRUKTUR', 'ADMINISTRASI', 'KEAMANAN', 'LAINNYA');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ComplaintStatus" AS ENUM ('BARU', 'DIPROSES', 'SELESAI', 'DITOLAK');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "LetterType" AS ENUM ('KTP', 'KK', 'DOMISILI', 'USAHA', 'KETERANGAN_TIDAK_MAMPU', 'SURAT_PENGANTAR', 'LAINNYA');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ServiceStatus" AS ENUM ('BARU', 'DIPROSES', 'SELESAI', 'DIAMBIL');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "IdeaStatus" AS ENUM ('BARU', 'DIKAJI', 'DISETUJUI', 'DITOLAK', 'DIIMPLEMENTASI');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Gender" AS ENUM ('LAKI_LAKI', 'PEREMPUAN');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Religion" AS ENUM ('HINDU', 'ISLAM', 'KRISTEN', 'KATOLIK', 'BUDDHA', 'KONGHUCU', 'LAINNYA');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "MaritalStatus" AS ENUM ('BELUM_KAWIN', 'KAWIN', 'CERAI_HIDUP', 'CERAI_MATI');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "EducationLevel" AS ENUM ('TIDAK_SEKOLAH', 'SD', 'SMP', 'SMA', 'D3', 'S1', 'S2', 'S3');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "user" (
|
||||
"id" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"name" TEXT,
|
||||
"emailVerified" BOOLEAN,
|
||||
"image" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"role" TEXT DEFAULT 'user',
|
||||
|
||||
CONSTRAINT "user_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "division" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"color" TEXT NOT NULL DEFAULT '#1E3A5F',
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "division_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "activity" (
|
||||
"id" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"divisionId" TEXT NOT NULL,
|
||||
"startDate" TIMESTAMP(3),
|
||||
"endDate" TIMESTAMP(3),
|
||||
"dueDate" TIMESTAMP(3),
|
||||
"progress" INTEGER NOT NULL DEFAULT 0,
|
||||
"status" "ActivityStatus" NOT NULL DEFAULT 'BERJALAN',
|
||||
"priority" "Priority" NOT NULL DEFAULT 'SEDANG',
|
||||
"assignedTo" TEXT,
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "activity_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "document" (
|
||||
"id" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"category" "DocumentCategory" NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"fileUrl" TEXT NOT NULL,
|
||||
"fileSize" INTEGER,
|
||||
"divisionId" TEXT,
|
||||
"uploadedBy" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "document_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "discussion" (
|
||||
"id" TEXT NOT NULL,
|
||||
"message" TEXT NOT NULL,
|
||||
"senderId" TEXT NOT NULL,
|
||||
"parentId" TEXT,
|
||||
"divisionId" TEXT,
|
||||
"isResolved" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "discussion_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "event" (
|
||||
"id" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"eventType" "EventType" NOT NULL,
|
||||
"startDate" TIMESTAMP(3) NOT NULL,
|
||||
"endDate" TIMESTAMP(3),
|
||||
"location" TEXT,
|
||||
"isAllDay" BOOLEAN NOT NULL DEFAULT false,
|
||||
"isRecurring" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdBy" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "event_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "division_metric" (
|
||||
"id" TEXT NOT NULL,
|
||||
"divisionId" TEXT NOT NULL,
|
||||
"period" TEXT NOT NULL,
|
||||
"activityCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"completionRate" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
"avgProgress" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "division_metric_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "complaint" (
|
||||
"id" TEXT NOT NULL,
|
||||
"complaintNumber" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"category" "ComplaintCategory" NOT NULL,
|
||||
"status" "ComplaintStatus" NOT NULL DEFAULT 'BARU',
|
||||
"priority" "Priority" NOT NULL DEFAULT 'SEDANG',
|
||||
"reporterId" TEXT,
|
||||
"reporterPhone" TEXT,
|
||||
"reporterEmail" TEXT,
|
||||
"isAnonymous" BOOLEAN NOT NULL DEFAULT false,
|
||||
"assignedTo" TEXT,
|
||||
"resolvedBy" TEXT,
|
||||
"resolvedAt" TIMESTAMP(3),
|
||||
"location" TEXT,
|
||||
"imageUrl" TEXT[],
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "complaint_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "complaint_update" (
|
||||
"id" TEXT NOT NULL,
|
||||
"complaintId" TEXT NOT NULL,
|
||||
"message" TEXT NOT NULL,
|
||||
"status" "ComplaintStatus",
|
||||
"updatedBy" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "complaint_update_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "service_letter" (
|
||||
"id" TEXT NOT NULL,
|
||||
"letterNumber" TEXT NOT NULL,
|
||||
"letterType" "LetterType" NOT NULL,
|
||||
"applicantName" TEXT NOT NULL,
|
||||
"applicantNik" TEXT NOT NULL,
|
||||
"applicantAddress" TEXT NOT NULL,
|
||||
"purpose" TEXT,
|
||||
"status" "ServiceStatus" NOT NULL DEFAULT 'BARU',
|
||||
"processedBy" TEXT,
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "service_letter_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "innovation_idea" (
|
||||
"id" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"category" TEXT NOT NULL,
|
||||
"submitterName" TEXT NOT NULL,
|
||||
"submitterContact" TEXT,
|
||||
"status" "IdeaStatus" NOT NULL DEFAULT 'BARU',
|
||||
"reviewedBy" TEXT,
|
||||
"reviewedAt" TIMESTAMP(3),
|
||||
"notes" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "innovation_idea_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "resident" (
|
||||
"id" TEXT NOT NULL,
|
||||
"nik" TEXT NOT NULL,
|
||||
"kk" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"birthDate" TIMESTAMP(3) NOT NULL,
|
||||
"birthPlace" TEXT NOT NULL,
|
||||
"gender" "Gender" NOT NULL,
|
||||
"religion" "Religion" NOT NULL,
|
||||
"maritalStatus" "MaritalStatus" NOT NULL DEFAULT 'BELUM_KAWIN',
|
||||
"education" "EducationLevel",
|
||||
"occupation" TEXT,
|
||||
"banjarId" TEXT NOT NULL,
|
||||
"rt" TEXT NOT NULL,
|
||||
"rw" TEXT NOT NULL,
|
||||
"address" TEXT NOT NULL,
|
||||
"isHeadOfHousehold" BOOLEAN NOT NULL DEFAULT false,
|
||||
"isPoor" BOOLEAN NOT NULL DEFAULT false,
|
||||
"isStunting" BOOLEAN NOT NULL DEFAULT false,
|
||||
"deathDate" TIMESTAMP(3),
|
||||
"moveInDate" TIMESTAMP(3),
|
||||
"moveOutDate" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "resident_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "banjar" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"code" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"totalPopulation" INTEGER NOT NULL DEFAULT 0,
|
||||
"totalKK" INTEGER NOT NULL DEFAULT 0,
|
||||
"totalPoor" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "banjar_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "HealthRecord" (
|
||||
"id" TEXT NOT NULL,
|
||||
"residentId" TEXT NOT NULL,
|
||||
"recordedBy" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "HealthRecord_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "EmploymentRecord" (
|
||||
"id" TEXT NOT NULL,
|
||||
"residentId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "EmploymentRecord_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "PopulationDynamic" (
|
||||
"id" TEXT NOT NULL,
|
||||
"documentedBy" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "PopulationDynamic_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Budget" (
|
||||
"id" TEXT NOT NULL,
|
||||
"approvedBy" TEXT,
|
||||
|
||||
CONSTRAINT "Budget_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "BudgetTransaction" (
|
||||
"id" TEXT NOT NULL,
|
||||
"createdBy" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "BudgetTransaction_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Umkm" (
|
||||
"id" TEXT NOT NULL,
|
||||
"banjarId" TEXT,
|
||||
|
||||
CONSTRAINT "Umkm_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Posyandu" (
|
||||
"id" TEXT NOT NULL,
|
||||
"coordinatorId" TEXT,
|
||||
|
||||
CONSTRAINT "Posyandu_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "SecurityReport" (
|
||||
"id" TEXT NOT NULL,
|
||||
"assignedTo" TEXT,
|
||||
|
||||
CONSTRAINT "SecurityReport_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "session" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"ipAddress" TEXT,
|
||||
"userAgent" TEXT,
|
||||
|
||||
CONSTRAINT "session_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "account" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"accountId" TEXT NOT NULL,
|
||||
"providerId" TEXT NOT NULL,
|
||||
"accessToken" TEXT,
|
||||
"refreshToken" TEXT,
|
||||
"expiresAt" TIMESTAMP(3),
|
||||
"password" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"idToken" TEXT,
|
||||
"accessTokenExpiresAt" TIMESTAMP(3),
|
||||
"refreshTokenExpiresAt" TIMESTAMP(3),
|
||||
"scope" TEXT,
|
||||
|
||||
CONSTRAINT "account_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "verification" (
|
||||
"id" TEXT NOT NULL,
|
||||
"identifier" TEXT NOT NULL,
|
||||
"value" TEXT NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "verification_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "api_key" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"key" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"expiresAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "api_key_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_email_key" ON "user"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "division_name_key" ON "division"("name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "activity_divisionId_idx" ON "activity"("divisionId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "activity_status_idx" ON "activity"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "document_category_idx" ON "document"("category");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "document_divisionId_idx" ON "document"("divisionId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "discussion_divisionId_idx" ON "discussion"("divisionId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "discussion_createdAt_idx" ON "discussion"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "event_startDate_idx" ON "event"("startDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "event_eventType_idx" ON "event"("eventType");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "division_metric_divisionId_period_key" ON "division_metric"("divisionId", "period");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "complaint_complaintNumber_key" ON "complaint"("complaintNumber");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "complaint_status_idx" ON "complaint"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "complaint_category_idx" ON "complaint"("category");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "complaint_createdAt_idx" ON "complaint"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "complaint_update_complaintId_idx" ON "complaint_update"("complaintId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "service_letter_letterNumber_key" ON "service_letter"("letterNumber");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "service_letter_letterType_idx" ON "service_letter"("letterType");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "service_letter_status_idx" ON "service_letter"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "service_letter_createdAt_idx" ON "service_letter"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "innovation_idea_category_idx" ON "innovation_idea"("category");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "innovation_idea_status_idx" ON "innovation_idea"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "resident_nik_key" ON "resident"("nik");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "resident_banjarId_idx" ON "resident"("banjarId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "resident_religion_idx" ON "resident"("religion");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "resident_occupation_idx" ON "resident"("occupation");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "banjar_name_key" ON "banjar"("name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "banjar_code_key" ON "banjar"("code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "session_token_key" ON "session"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "session_userId_idx" ON "session"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "account_userId_idx" ON "account"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "verification_identifier_idx" ON "verification"("identifier");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "api_key_key_key" ON "api_key"("key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "api_key_userId_idx" ON "api_key"("userId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "activity" ADD CONSTRAINT "activity_divisionId_fkey" FOREIGN KEY ("divisionId") REFERENCES "division"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "document" ADD CONSTRAINT "document_divisionId_fkey" FOREIGN KEY ("divisionId") REFERENCES "division"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "discussion" ADD CONSTRAINT "discussion_senderId_fkey" FOREIGN KEY ("senderId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "discussion" ADD CONSTRAINT "discussion_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "discussion"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "discussion" ADD CONSTRAINT "discussion_divisionId_fkey" FOREIGN KEY ("divisionId") REFERENCES "division"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "event" ADD CONSTRAINT "event_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "division_metric" ADD CONSTRAINT "division_metric_divisionId_fkey" FOREIGN KEY ("divisionId") REFERENCES "division"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "complaint" ADD CONSTRAINT "complaint_reporterId_fkey" FOREIGN KEY ("reporterId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "complaint" ADD CONSTRAINT "complaint_assignedTo_fkey" FOREIGN KEY ("assignedTo") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "complaint_update" ADD CONSTRAINT "complaint_update_complaintId_fkey" FOREIGN KEY ("complaintId") REFERENCES "complaint"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "complaint_update" ADD CONSTRAINT "complaint_update_updatedBy_fkey" FOREIGN KEY ("updatedBy") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "service_letter" ADD CONSTRAINT "service_letter_processedBy_fkey" FOREIGN KEY ("processedBy") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "innovation_idea" ADD CONSTRAINT "innovation_idea_reviewedBy_fkey" FOREIGN KEY ("reviewedBy") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "resident" ADD CONSTRAINT "resident_banjarId_fkey" FOREIGN KEY ("banjarId") REFERENCES "banjar"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "HealthRecord" ADD CONSTRAINT "HealthRecord_residentId_fkey" FOREIGN KEY ("residentId") REFERENCES "resident"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "HealthRecord" ADD CONSTRAINT "HealthRecord_recordedBy_fkey" FOREIGN KEY ("recordedBy") REFERENCES "user"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "EmploymentRecord" ADD CONSTRAINT "EmploymentRecord_residentId_fkey" FOREIGN KEY ("residentId") REFERENCES "resident"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "PopulationDynamic" ADD CONSTRAINT "PopulationDynamic_documentedBy_fkey" FOREIGN KEY ("documentedBy") REFERENCES "user"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Budget" ADD CONSTRAINT "Budget_approvedBy_fkey" FOREIGN KEY ("approvedBy") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "BudgetTransaction" ADD CONSTRAINT "BudgetTransaction_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "user"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Umkm" ADD CONSTRAINT "Umkm_banjarId_fkey" FOREIGN KEY ("banjarId") REFERENCES "banjar"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Posyandu" ADD CONSTRAINT "Posyandu_coordinatorId_fkey" FOREIGN KEY ("coordinatorId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "SecurityReport" ADD CONSTRAINT "SecurityReport_assignedTo_fkey" FOREIGN KEY ("assignedTo") REFERENCES "user"("id") ON DELETE SET NULL 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 "account" ADD CONSTRAINT "account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "api_key" ADD CONSTRAINT "api_key_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("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"
|
||||
@@ -21,9 +21,459 @@ model User {
|
||||
sessions Session[]
|
||||
apiKeys ApiKey[]
|
||||
|
||||
// Relations
|
||||
discussions Discussion[]
|
||||
events Event[]
|
||||
complaints Complaint[] @relation("ComplaintReporter")
|
||||
assignedComplaints Complaint[] @relation("ComplaintAssignee")
|
||||
complaintUpdates ComplaintUpdate[]
|
||||
serviceLetters ServiceLetter[]
|
||||
innovationIdeas InnovationIdea[] @relation("IdeaReviewer")
|
||||
healthRecords HealthRecord[]
|
||||
populationDynamics PopulationDynamic[]
|
||||
budgets Budget[]
|
||||
budgetTransactions BudgetTransaction[]
|
||||
posyandus Posyandu[]
|
||||
securityReports SecurityReport[]
|
||||
|
||||
@@map("user")
|
||||
}
|
||||
|
||||
// --- KATEGORI 1: KINERJA DIVISI & AKTIVITAS ---
|
||||
|
||||
model Division {
|
||||
id String @id @default(cuid())
|
||||
name String @unique
|
||||
description String?
|
||||
color String @default("#1E3A5F")
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
activities Activity[]
|
||||
documents Document[]
|
||||
discussions Discussion[]
|
||||
divisionMetrics DivisionMetric[]
|
||||
|
||||
@@map("division")
|
||||
}
|
||||
|
||||
model Activity {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
description String?
|
||||
divisionId String
|
||||
startDate DateTime?
|
||||
endDate DateTime?
|
||||
dueDate DateTime?
|
||||
progress Int @default(0) // 0-100
|
||||
status ActivityStatus @default(BERJALAN)
|
||||
priority Priority @default(SEDANG)
|
||||
assignedTo String? // JSON array of user IDs
|
||||
completedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
division Division @relation(fields: [divisionId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([divisionId])
|
||||
@@index([status])
|
||||
@@map("activity")
|
||||
}
|
||||
|
||||
model Document {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
category DocumentCategory
|
||||
type String // "Gambar", "Dokumen", "PDF", etc
|
||||
fileUrl String
|
||||
fileSize Int? // in bytes
|
||||
divisionId String?
|
||||
uploadedBy String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
division Division? @relation(fields: [divisionId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([category])
|
||||
@@index([divisionId])
|
||||
@@map("document")
|
||||
}
|
||||
|
||||
model Discussion {
|
||||
id String @id @default(cuid())
|
||||
message String
|
||||
senderId String
|
||||
parentId String? // For threaded discussions
|
||||
divisionId String?
|
||||
isResolved Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
sender User @relation(fields: [senderId], references: [id], onDelete: Cascade)
|
||||
parent Discussion? @relation("DiscussionThread", fields: [parentId], references: [id], onDelete: SetNull)
|
||||
replies Discussion[] @relation("DiscussionThread")
|
||||
division Division? @relation(fields: [divisionId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([divisionId])
|
||||
@@index([createdAt])
|
||||
@@map("discussion")
|
||||
}
|
||||
|
||||
model Event {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
description String?
|
||||
eventType EventType
|
||||
startDate DateTime
|
||||
endDate DateTime?
|
||||
location String?
|
||||
isAllDay Boolean @default(false)
|
||||
isRecurring Boolean @default(false)
|
||||
createdBy String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
creator User @relation(fields: [createdBy], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([startDate])
|
||||
@@index([eventType])
|
||||
@@map("event")
|
||||
}
|
||||
|
||||
model DivisionMetric {
|
||||
id String @id @default(cuid())
|
||||
divisionId String
|
||||
period String // "2025-Q1", "2025-01"
|
||||
activityCount Int @default(0)
|
||||
completionRate Float @default(0)
|
||||
avgProgress Float @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
division Division @relation(fields: [divisionId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([divisionId, period])
|
||||
@@map("division_metric")
|
||||
}
|
||||
|
||||
// --- KATEGORI 2: PENGADUAN & LAYANAN PUBLIK ---
|
||||
|
||||
model Complaint {
|
||||
id String @id @default(cuid())
|
||||
complaintNumber String @unique // Auto-generated: COMPLAINT-YYYYMMDD-XXX
|
||||
title String
|
||||
description String
|
||||
category ComplaintCategory
|
||||
status ComplaintStatus @default(BARU)
|
||||
priority Priority @default(SEDANG)
|
||||
|
||||
reporterId String?
|
||||
reporterPhone String?
|
||||
reporterEmail String?
|
||||
isAnonymous Boolean @default(false)
|
||||
|
||||
assignedTo String? // User ID
|
||||
resolvedBy String? // User ID
|
||||
resolvedAt DateTime?
|
||||
|
||||
location String?
|
||||
imageUrl String[] // Array of image URLs
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
reporter User? @relation("ComplaintReporter", fields: [reporterId], references: [id], onDelete: SetNull)
|
||||
assignee User? @relation("ComplaintAssignee", fields: [assignedTo], references: [id], onDelete: SetNull)
|
||||
|
||||
complaintUpdates ComplaintUpdate[]
|
||||
|
||||
@@index([status])
|
||||
@@index([category])
|
||||
@@index([createdAt])
|
||||
@@map("complaint")
|
||||
}
|
||||
|
||||
model ComplaintUpdate {
|
||||
id String @id @default(cuid())
|
||||
complaintId String
|
||||
message String
|
||||
status ComplaintStatus?
|
||||
updatedBy String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
complaint Complaint @relation(fields: [complaintId], references: [id], onDelete: Cascade)
|
||||
updater User @relation(fields: [updatedBy], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([complaintId])
|
||||
@@map("complaint_update")
|
||||
}
|
||||
|
||||
model ServiceLetter {
|
||||
id String @id @default(cuid())
|
||||
letterNumber String @unique
|
||||
letterType LetterType
|
||||
applicantName String
|
||||
applicantNik String
|
||||
applicantAddress String
|
||||
purpose String?
|
||||
status ServiceStatus @default(BARU)
|
||||
|
||||
processedBy String?
|
||||
completedAt DateTime?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
processor User? @relation(fields: [processedBy], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([letterType])
|
||||
@@index([status])
|
||||
@@index([createdAt])
|
||||
@@map("service_letter")
|
||||
}
|
||||
|
||||
model InnovationIdea {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
description String
|
||||
category String // "Teknologi", "Ekonomi", "Kesehatan", "Pendidikan"
|
||||
submitterName String
|
||||
submitterContact String?
|
||||
status IdeaStatus @default(BARU)
|
||||
reviewedBy String?
|
||||
reviewedAt DateTime?
|
||||
notes String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
reviewer User? @relation("IdeaReviewer", fields: [reviewedBy], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([category])
|
||||
@@index([status])
|
||||
@@map("innovation_idea")
|
||||
}
|
||||
|
||||
// --- KATEGORI 3: DEMOGRAFI & KEPENDUDUKAN ---
|
||||
|
||||
model Resident {
|
||||
id String @id @default(cuid())
|
||||
nik String @unique
|
||||
kk String
|
||||
name String
|
||||
birthDate DateTime
|
||||
birthPlace String
|
||||
gender Gender
|
||||
religion Religion
|
||||
maritalStatus MaritalStatus @default(BELUM_KAWIN)
|
||||
education EducationLevel?
|
||||
occupation String?
|
||||
|
||||
banjarId String
|
||||
rt String
|
||||
rw String
|
||||
address String
|
||||
|
||||
isHeadOfHousehold Boolean @default(false)
|
||||
isPoor Boolean @default(false)
|
||||
isStunting Boolean @default(false)
|
||||
|
||||
deathDate DateTime?
|
||||
moveInDate DateTime?
|
||||
moveOutDate DateTime?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
banjar Banjar @relation(fields: [banjarId], references: [id], onDelete: Cascade)
|
||||
|
||||
healthRecords HealthRecord[]
|
||||
employmentRecords EmploymentRecord[]
|
||||
|
||||
@@index([banjarId])
|
||||
@@index([religion])
|
||||
@@index([occupation])
|
||||
@@map("resident")
|
||||
}
|
||||
|
||||
model Banjar {
|
||||
id String @id @default(cuid())
|
||||
name String @unique
|
||||
code String @unique
|
||||
description String?
|
||||
|
||||
totalPopulation Int @default(0)
|
||||
totalKK Int @default(0)
|
||||
totalPoor Int @default(0)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
residents Resident[]
|
||||
umkms Umkm[]
|
||||
|
||||
@@map("banjar")
|
||||
}
|
||||
|
||||
// --- STUBS FOR PHASE 2+ (To maintain relations) ---
|
||||
|
||||
model HealthRecord {
|
||||
id String @id @default(cuid())
|
||||
residentId String
|
||||
resident Resident @relation(fields: [residentId], references: [id])
|
||||
recordedBy String
|
||||
recorder User @relation(fields: [recordedBy], references: [id])
|
||||
}
|
||||
|
||||
model EmploymentRecord {
|
||||
id String @id @default(cuid())
|
||||
residentId String
|
||||
resident Resident @relation(fields: [residentId], references: [id])
|
||||
}
|
||||
|
||||
model PopulationDynamic {
|
||||
id String @id @default(cuid())
|
||||
documentedBy String
|
||||
documentor User @relation(fields: [documentedBy], references: [id])
|
||||
}
|
||||
|
||||
model Budget {
|
||||
id String @id @default(cuid())
|
||||
approvedBy String?
|
||||
approver User? @relation(fields: [approvedBy], references: [id])
|
||||
}
|
||||
|
||||
model BudgetTransaction {
|
||||
id String @id @default(cuid())
|
||||
createdBy String
|
||||
creator User @relation(fields: [createdBy], references: [id])
|
||||
}
|
||||
|
||||
model Umkm {
|
||||
id String @id @default(cuid())
|
||||
banjarId String?
|
||||
banjar Banjar? @relation(fields: [banjarId], references: [id])
|
||||
}
|
||||
|
||||
model Posyandu {
|
||||
id String @id @default(cuid())
|
||||
coordinatorId String?
|
||||
coordinator User? @relation(fields: [coordinatorId], references: [id])
|
||||
}
|
||||
|
||||
model SecurityReport {
|
||||
id String @id @default(cuid())
|
||||
assignedTo String?
|
||||
assignee User? @relation(fields: [assignedTo], references: [id])
|
||||
}
|
||||
|
||||
// --- ENUMS ---
|
||||
|
||||
enum ActivityStatus {
|
||||
BERJALAN
|
||||
SELESAI
|
||||
TERTUNDA
|
||||
DIBATALKAN
|
||||
}
|
||||
|
||||
enum Priority {
|
||||
RENDAH
|
||||
SEDANG
|
||||
TINGGI
|
||||
DARURAT
|
||||
}
|
||||
|
||||
enum DocumentCategory {
|
||||
SURAT_KEPUTUSAN
|
||||
DOKUMENTASI
|
||||
LAPORAN_KEUANGAN
|
||||
NOTULENSI_RAPAT
|
||||
UMUM
|
||||
}
|
||||
|
||||
enum EventType {
|
||||
RAPAT
|
||||
KEGIATAN
|
||||
UPACARA
|
||||
SOSIAL
|
||||
BUDAYA
|
||||
LAINNYA
|
||||
}
|
||||
|
||||
enum ComplaintCategory {
|
||||
KETERTIBAN_UMUM
|
||||
PELAYANAN_KESEHATAN
|
||||
INFRASTRUKTUR
|
||||
ADMINISTRASI
|
||||
KEAMANAN
|
||||
LAINNYA
|
||||
}
|
||||
|
||||
enum ComplaintStatus {
|
||||
BARU
|
||||
DIPROSES
|
||||
SELESAI
|
||||
DITOLAK
|
||||
}
|
||||
|
||||
enum LetterType {
|
||||
KTP
|
||||
KK
|
||||
DOMISILI
|
||||
USAHA
|
||||
KETERANGAN_TIDAK_MAMPU
|
||||
SURAT_PENGANTAR
|
||||
LAINNYA
|
||||
}
|
||||
|
||||
enum ServiceStatus {
|
||||
BARU
|
||||
DIPROSES
|
||||
SELESAI
|
||||
DIAMBIL
|
||||
}
|
||||
|
||||
enum IdeaStatus {
|
||||
BARU
|
||||
DIKAJI
|
||||
DISETUJUI
|
||||
DITOLAK
|
||||
DIIMPLEMENTASI
|
||||
}
|
||||
|
||||
enum Gender {
|
||||
LAKI_LAKI
|
||||
PEREMPUAN
|
||||
}
|
||||
|
||||
enum Religion {
|
||||
HINDU
|
||||
ISLAM
|
||||
KRISTEN
|
||||
KATOLIK
|
||||
BUDDHA
|
||||
KONGHUCU
|
||||
LAINNYA
|
||||
}
|
||||
|
||||
enum MaritalStatus {
|
||||
BELUM_KAWIN
|
||||
KAWIN
|
||||
CERAI_HIDUP
|
||||
CERAI_MATI
|
||||
}
|
||||
|
||||
enum EducationLevel {
|
||||
TIDAK_SEKOLAH
|
||||
SD
|
||||
SMP
|
||||
SMA
|
||||
D3
|
||||
S1
|
||||
S2
|
||||
S3
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
|
||||
403
prisma/seed.ts
403
prisma/seed.ts
@@ -1,150 +1,325 @@
|
||||
import "dotenv/config";
|
||||
import { hash } from "bcryptjs";
|
||||
import { generateId } from "better-auth";
|
||||
import { prisma } from "@/utils/db";
|
||||
import {
|
||||
ActivityStatus,
|
||||
ComplaintCategory,
|
||||
ComplaintStatus,
|
||||
EventType,
|
||||
Gender,
|
||||
Priority,
|
||||
PrismaClient,
|
||||
Religion,
|
||||
} from "../generated/prisma";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function seedAdminUser() {
|
||||
// Load environment variables
|
||||
const adminEmail = process.env.ADMIN_EMAIL;
|
||||
const adminEmail = process.env.ADMIN_EMAIL || "admin@example.com";
|
||||
const adminPassword = process.env.ADMIN_PASSWORD || "admin123";
|
||||
|
||||
if (!adminEmail) {
|
||||
console.log(
|
||||
"No ADMIN_EMAIL environment variable found. Skipping admin user creation.",
|
||||
);
|
||||
return;
|
||||
console.log(`Checking admin user: ${adminEmail}`);
|
||||
|
||||
const existingUser = await prisma.user.findUnique({
|
||||
where: { email: adminEmail },
|
||||
});
|
||||
|
||||
if (existingUser) {
|
||||
if (existingUser.role !== "admin") {
|
||||
await prisma.user.update({
|
||||
where: { email: adminEmail },
|
||||
data: { role: "admin" },
|
||||
});
|
||||
console.log("Updated existing user to admin role.");
|
||||
}
|
||||
return existingUser.id;
|
||||
}
|
||||
|
||||
try {
|
||||
// Check if admin user already exists
|
||||
const existingUser = await prisma.user.findUnique({
|
||||
where: { email: adminEmail },
|
||||
});
|
||||
const hashedPassword = await hash(adminPassword, 12);
|
||||
const userId = generateId();
|
||||
|
||||
if (existingUser) {
|
||||
// Update existing user to have admin role if they don't already
|
||||
if (existingUser.role !== "admin") {
|
||||
await prisma.user.update({
|
||||
where: { email: adminEmail },
|
||||
data: { role: "admin" },
|
||||
});
|
||||
console.log(`User with email ${adminEmail} updated to admin role.`);
|
||||
} else {
|
||||
console.log(`User with email ${adminEmail} already has admin role.`);
|
||||
}
|
||||
} else {
|
||||
// Create new admin user
|
||||
const hashedPassword = await hash(adminPassword, 12);
|
||||
const userId = generateId();
|
||||
|
||||
await prisma.user.create({
|
||||
data: {
|
||||
id: userId,
|
||||
email: adminEmail,
|
||||
name: "Admin User",
|
||||
role: "admin",
|
||||
emailVerified: true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.account.create({
|
||||
data: {
|
||||
await prisma.user.create({
|
||||
data: {
|
||||
id: userId,
|
||||
email: adminEmail,
|
||||
name: "Admin Desa Darmasaba",
|
||||
role: "admin",
|
||||
emailVerified: true,
|
||||
accounts: {
|
||||
create: {
|
||||
id: generateId(),
|
||||
userId,
|
||||
accountId: userId,
|
||||
providerId: "credential",
|
||||
password: hashedPassword,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`Admin user created with email: ${adminEmail}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error seeding admin user:", error);
|
||||
throw error;
|
||||
}
|
||||
console.log(`Admin user created: ${adminEmail}`);
|
||||
return userId;
|
||||
}
|
||||
|
||||
async function seedDemoUsers() {
|
||||
const demoUsers = [
|
||||
{ email: "demo1@example.com", name: "Demo User 1", role: "user" },
|
||||
{ email: "demo2@example.com", name: "Demo User 2", role: "user" },
|
||||
async function seedBanjars() {
|
||||
const banjars = [
|
||||
{
|
||||
email: "moderator@example.com",
|
||||
name: "Moderator User",
|
||||
role: "moderator",
|
||||
name: "Darmasaba",
|
||||
code: "DSB",
|
||||
totalPopulation: 1200,
|
||||
totalKK: 300,
|
||||
totalPoor: 45,
|
||||
},
|
||||
{
|
||||
name: "Manesa",
|
||||
code: "MNS",
|
||||
totalPopulation: 950,
|
||||
totalKK: 240,
|
||||
totalPoor: 32,
|
||||
},
|
||||
{
|
||||
name: "Cabe",
|
||||
code: "CBE",
|
||||
totalPopulation: 800,
|
||||
totalKK: 200,
|
||||
totalPoor: 28,
|
||||
},
|
||||
{
|
||||
name: "Penenjoan",
|
||||
code: "PNJ",
|
||||
totalPopulation: 1100,
|
||||
totalKK: 280,
|
||||
totalPoor: 50,
|
||||
},
|
||||
{
|
||||
name: "Baler Pasar",
|
||||
code: "BPS",
|
||||
totalPopulation: 850,
|
||||
totalKK: 210,
|
||||
totalPoor: 35,
|
||||
},
|
||||
{
|
||||
name: "Bucu",
|
||||
code: "BCU",
|
||||
totalPopulation: 734,
|
||||
totalKK: 184,
|
||||
totalPoor: 24,
|
||||
},
|
||||
];
|
||||
|
||||
for (const userData of demoUsers) {
|
||||
try {
|
||||
const existingUser = await prisma.user.findUnique({
|
||||
where: { email: userData.email },
|
||||
});
|
||||
console.log("Seeding Banjars...");
|
||||
for (const banjar of banjars) {
|
||||
await prisma.banjar.upsert({
|
||||
where: { name: banjar.name },
|
||||
update: banjar,
|
||||
create: banjar,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!existingUser) {
|
||||
const userId = generateId();
|
||||
const hashedPassword = await hash("demo123", 12);
|
||||
async function seedDivisions() {
|
||||
const divisions = [
|
||||
{
|
||||
name: "Pemerintahan",
|
||||
description: "Urusan administrasi dan tata kelola desa",
|
||||
color: "#1E3A5F",
|
||||
},
|
||||
{
|
||||
name: "Pembangunan",
|
||||
description: "Infrastruktur dan sarana prasarana desa",
|
||||
color: "#2E7D32",
|
||||
},
|
||||
{
|
||||
name: "Pemberdayaan",
|
||||
description: "Pemberdayaan ekonomi dan masyarakat",
|
||||
color: "#EF6C00",
|
||||
},
|
||||
{
|
||||
name: "Kesejahteraan",
|
||||
description: "Kesehatan, pendidikan, dan sosial",
|
||||
color: "#C62828",
|
||||
},
|
||||
];
|
||||
|
||||
await prisma.user.create({
|
||||
data: {
|
||||
id: userId,
|
||||
email: userData.email,
|
||||
name: userData.name,
|
||||
role: userData.role,
|
||||
emailVerified: true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
});
|
||||
console.log("Seeding Divisions...");
|
||||
const createdDivisions = [];
|
||||
for (const div of divisions) {
|
||||
const d = await prisma.division.upsert({
|
||||
where: { name: div.name },
|
||||
update: div,
|
||||
create: div,
|
||||
});
|
||||
createdDivisions.push(d);
|
||||
}
|
||||
return createdDivisions;
|
||||
}
|
||||
|
||||
await prisma.account.create({
|
||||
data: {
|
||||
id: generateId(),
|
||||
userId,
|
||||
accountId: userId,
|
||||
providerId: "credential",
|
||||
password: hashedPassword,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
});
|
||||
async function seedResidents(banjarIds: string[]) {
|
||||
console.log("Seeding Residents...");
|
||||
const residents = [
|
||||
{
|
||||
nik: "5103010101700001",
|
||||
kk: "5103010101700000",
|
||||
name: "I Wayan Sudarsana",
|
||||
birthDate: new Date("1970-05-15"),
|
||||
birthPlace: "Badung",
|
||||
gender: Gender.LAKI_LAKI,
|
||||
religion: Religion.HINDU,
|
||||
occupation: "Wiraswasta",
|
||||
banjarId: banjarIds[0],
|
||||
rt: "001",
|
||||
rw: "000",
|
||||
address: "Jl. Raya Darmasaba No. 1",
|
||||
isHeadOfHousehold: true,
|
||||
},
|
||||
{
|
||||
nik: "5103010101850002",
|
||||
kk: "5103010101850000",
|
||||
name: "Ni Made Arianti",
|
||||
birthDate: new Date("1985-08-20"),
|
||||
birthPlace: "Denpasar",
|
||||
gender: Gender.PEREMPUAN,
|
||||
religion: Religion.HINDU,
|
||||
occupation: "Guru",
|
||||
banjarId: banjarIds[1],
|
||||
rt: "002",
|
||||
rw: "000",
|
||||
address: "Gg. Manesa No. 5",
|
||||
isPoor: true,
|
||||
},
|
||||
];
|
||||
|
||||
console.log(`Demo user created: ${userData.email}`);
|
||||
} else {
|
||||
console.log(`Demo user already exists: ${userData.email}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error seeding user ${userData.email}:`, error);
|
||||
}
|
||||
for (const res of residents) {
|
||||
await prisma.resident.upsert({
|
||||
where: { nik: res.nik },
|
||||
update: res,
|
||||
create: res,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function seedActivities(divisionIds: string[]) {
|
||||
console.log("Seeding Activities...");
|
||||
const activities = [
|
||||
{
|
||||
title: "Rapat Koordinasi 2025",
|
||||
description: "Penyusunan rencana kerja tahunan",
|
||||
divisionId: divisionIds[0],
|
||||
progress: 100,
|
||||
status: ActivityStatus.SELESAI,
|
||||
priority: Priority.TINGGI,
|
||||
},
|
||||
{
|
||||
title: "Pemutakhiran Indeks Desa",
|
||||
description: "Pendataan SDG's Desa 2025",
|
||||
divisionId: divisionIds[0],
|
||||
progress: 65,
|
||||
status: ActivityStatus.BERJALAN,
|
||||
priority: Priority.SEDANG,
|
||||
},
|
||||
{
|
||||
title: "Pembangunan Jalan Banjar Cabe",
|
||||
description: "Pengaspalan jalan utama",
|
||||
divisionId: divisionIds[1],
|
||||
progress: 40,
|
||||
status: ActivityStatus.BERJALAN,
|
||||
priority: Priority.DARURAT,
|
||||
},
|
||||
];
|
||||
|
||||
for (const act of activities) {
|
||||
await prisma.activity.create({
|
||||
data: act,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function seedComplaints(adminId: string) {
|
||||
console.log("Seeding Complaints...");
|
||||
const complaints = [
|
||||
{
|
||||
complaintNumber: `COMP-20250326-001`,
|
||||
title: "Lampu Jalan Mati",
|
||||
description:
|
||||
"Lampu jalan di depan Balai Banjar Manesa mati sejak 3 hari lalu.",
|
||||
category: ComplaintCategory.INFRASTRUKTUR,
|
||||
status: ComplaintStatus.BARU,
|
||||
priority: Priority.SEDANG,
|
||||
location: "Banjar Manesa",
|
||||
reporterId: adminId,
|
||||
},
|
||||
{
|
||||
complaintNumber: `COMP-20250326-002`,
|
||||
title: "Sampah Menumpuk",
|
||||
description: "Tumpukan sampah di area pasar Darmasaba belum diangkut.",
|
||||
category: ComplaintCategory.KETERTIBAN_UMUM,
|
||||
status: ComplaintStatus.DIPROSES,
|
||||
priority: Priority.TINGGI,
|
||||
location: "Pasar Darmasaba",
|
||||
assignedTo: adminId,
|
||||
},
|
||||
];
|
||||
|
||||
for (const comp of complaints) {
|
||||
await prisma.complaint.upsert({
|
||||
where: { complaintNumber: comp.complaintNumber },
|
||||
update: comp,
|
||||
create: comp,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function seedEvents(adminId: string) {
|
||||
console.log("Seeding Events...");
|
||||
const events = [
|
||||
{
|
||||
title: "Rapat Pleno Desa",
|
||||
description: "Pembahasan anggaran belanja desa",
|
||||
eventType: EventType.RAPAT,
|
||||
startDate: new Date(),
|
||||
location: "Balai Desa Darmasaba",
|
||||
createdBy: adminId,
|
||||
},
|
||||
{
|
||||
title: "Gotong Royong Kebersihan",
|
||||
description: "Kegiatan rutin mingguan",
|
||||
eventType: EventType.SOSIAL,
|
||||
startDate: new Date(Date.now() + 86400000), // Besok
|
||||
location: "Seluruh Banjar",
|
||||
createdBy: adminId,
|
||||
},
|
||||
];
|
||||
|
||||
for (const event of events) {
|
||||
await prisma.event.create({
|
||||
data: event,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log("Seeding database...");
|
||||
console.log("Starting seed...");
|
||||
|
||||
await seedAdminUser();
|
||||
await seedDemoUsers();
|
||||
const adminId = await seedAdminUser();
|
||||
await seedBanjars();
|
||||
const banjars = await prisma.banjar.findMany();
|
||||
const banjarIds = banjars.map((b) => b.id);
|
||||
|
||||
console.log("Database seeding completed.");
|
||||
const divisions = await seedDivisions();
|
||||
const divisionIds = divisions.map((d) => d.id);
|
||||
|
||||
await seedResidents(banjarIds);
|
||||
await seedActivities(divisionIds);
|
||||
await seedComplaints(adminId);
|
||||
await seedEvents(adminId);
|
||||
|
||||
console.log("Seed finished successfully!");
|
||||
}
|
||||
|
||||
// Only auto-execute when run directly (not when imported)
|
||||
const isMainModule =
|
||||
typeof require !== "undefined"
|
||||
? require.main === module
|
||||
: import.meta.path.endsWith("seed.ts");
|
||||
|
||||
if (isMainModule) {
|
||||
main().catch((error) => {
|
||||
console.error("Error during seeding:", error);
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
// Export for programmatic use
|
||||
export { seedAdminUser, seedDemoUsers, main as runSeed };
|
||||
|
||||
Reference in New Issue
Block a user