initial: standalone repo from monorepo split
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "super_admins" (
|
||||
"id" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"password" TEXT NOT NULL,
|
||||
"firstName" TEXT NOT NULL,
|
||||
"lastName" TEXT NOT NULL,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "super_admins_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "admin_refresh_tokens" (
|
||||
"id" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"adminId" TEXT NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "admin_refresh_tokens_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "platform_audit_logs" (
|
||||
"id" TEXT NOT NULL,
|
||||
"adminId" TEXT NOT NULL,
|
||||
"action" TEXT NOT NULL,
|
||||
"target" TEXT,
|
||||
"details" JSONB NOT NULL DEFAULT '{}',
|
||||
"ipAddress" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "platform_audit_logs_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "support_tickets" (
|
||||
"id" TEXT NOT NULL,
|
||||
"tenantId" TEXT NOT NULL,
|
||||
"tenantName" TEXT NOT NULL,
|
||||
"tenantSlug" TEXT NOT NULL,
|
||||
"createdById" TEXT NOT NULL,
|
||||
"createdByName" TEXT NOT NULL,
|
||||
"subject" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"category" TEXT NOT NULL DEFAULT 'general',
|
||||
"priority" TEXT NOT NULL DEFAULT 'normal',
|
||||
"status" TEXT NOT NULL DEFAULT 'open',
|
||||
"assignedToId" TEXT,
|
||||
"resolvedAt" TIMESTAMP(3),
|
||||
"closedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "support_tickets_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "support_ticket_comments" (
|
||||
"id" TEXT NOT NULL,
|
||||
"ticketId" TEXT NOT NULL,
|
||||
"authorId" TEXT NOT NULL,
|
||||
"authorName" TEXT NOT NULL,
|
||||
"authorType" TEXT NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "support_ticket_comments_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "super_admins_email_key" ON "super_admins"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "admin_refresh_tokens_token_key" ON "admin_refresh_tokens"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "admin_refresh_tokens_adminId_idx" ON "admin_refresh_tokens"("adminId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "admin_refresh_tokens_expiresAt_idx" ON "admin_refresh_tokens"("expiresAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "platform_audit_logs_adminId_idx" ON "platform_audit_logs"("adminId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "platform_audit_logs_action_idx" ON "platform_audit_logs"("action");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "platform_audit_logs_target_idx" ON "platform_audit_logs"("target");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "platform_audit_logs_createdAt_idx" ON "platform_audit_logs"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "support_tickets_tenantId_idx" ON "support_tickets"("tenantId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "support_tickets_status_idx" ON "support_tickets"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "support_tickets_category_idx" ON "support_tickets"("category");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "support_tickets_priority_idx" ON "support_tickets"("priority");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "support_tickets_assignedToId_idx" ON "support_tickets"("assignedToId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "support_tickets_createdAt_idx" ON "support_tickets"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "support_ticket_comments_ticketId_idx" ON "support_ticket_comments"("ticketId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "support_ticket_comments_authorId_idx" ON "support_ticket_comments"("authorId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "admin_refresh_tokens" ADD CONSTRAINT "admin_refresh_tokens_adminId_fkey" FOREIGN KEY ("adminId") REFERENCES "super_admins"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "platform_audit_logs" ADD CONSTRAINT "platform_audit_logs_adminId_fkey" FOREIGN KEY ("adminId") REFERENCES "super_admins"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "support_tickets" ADD CONSTRAINT "support_tickets_assignedToId_fkey" FOREIGN KEY ("assignedToId") REFERENCES "super_admins"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "support_ticket_comments" ADD CONSTRAINT "support_ticket_comments_ticketId_fkey" FOREIGN KEY ("ticketId") REFERENCES "support_tickets"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "support_ticket_comments" ADD CONSTRAINT "support_ticket_comments_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "super_admins"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
3
packages/admin-db/prisma/migrations/migration_lock.toml
Normal file
3
packages/admin-db/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"
|
||||
133
packages/admin-db/prisma/schema.prisma
Normal file
133
packages/admin-db/prisma/schema.prisma
Normal file
@@ -0,0 +1,133 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
output = "../generated"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_ADMIN_URL")
|
||||
}
|
||||
|
||||
// ─── Platform SuperAdmins ────────────────────────────
|
||||
|
||||
model SuperAdmin {
|
||||
id String @id @default(uuid())
|
||||
email String @unique
|
||||
password String
|
||||
firstName String
|
||||
lastName String
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
refreshTokens AdminRefreshToken[]
|
||||
auditLogs PlatformAuditLog[]
|
||||
assignedTickets SupportTicket[] @relation("TicketAssignee")
|
||||
ticketComments SupportTicketComment[]
|
||||
|
||||
@@map("super_admins")
|
||||
}
|
||||
|
||||
model AdminRefreshToken {
|
||||
id String @id @default(uuid())
|
||||
token String @unique
|
||||
adminId String
|
||||
expiresAt DateTime
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
admin SuperAdmin @relation(fields: [adminId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([adminId])
|
||||
@@index([expiresAt])
|
||||
@@map("admin_refresh_tokens")
|
||||
}
|
||||
|
||||
// ─── Platform Audit Log ──────────────────────────────
|
||||
|
||||
model PlatformAuditLog {
|
||||
id String @id @default(uuid())
|
||||
adminId String
|
||||
action String
|
||||
target String?
|
||||
details Json @default("{}")
|
||||
ipAddress String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
admin SuperAdmin @relation(fields: [adminId], references: [id])
|
||||
|
||||
@@index([adminId])
|
||||
@@index([action])
|
||||
@@index([target])
|
||||
@@index([createdAt])
|
||||
@@map("platform_audit_logs")
|
||||
}
|
||||
|
||||
// ─── Support Tickets (Tenant → Platform) ─────────────
|
||||
|
||||
model SupportTicket {
|
||||
id String @id @default(uuid())
|
||||
tenantId String
|
||||
tenantName String
|
||||
tenantSlug String
|
||||
createdById String
|
||||
createdByName String
|
||||
subject String
|
||||
description String
|
||||
category String @default("general") // billing, technical, account, general, feature_request
|
||||
priority String @default("normal") // low, normal, high, urgent
|
||||
status String @default("open") // open, in_progress, waiting_tenant, resolved, closed
|
||||
assignedToId String?
|
||||
resolvedAt DateTime?
|
||||
closedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
assignee SuperAdmin? @relation("TicketAssignee", fields: [assignedToId], references: [id])
|
||||
comments SupportTicketComment[]
|
||||
attachments SupportTicketAttachment[]
|
||||
|
||||
@@index([tenantId])
|
||||
@@index([status])
|
||||
@@index([category])
|
||||
@@index([priority])
|
||||
@@index([assignedToId])
|
||||
@@index([createdAt])
|
||||
@@map("support_tickets")
|
||||
}
|
||||
|
||||
model SupportTicketComment {
|
||||
id String @id @default(uuid())
|
||||
ticketId String
|
||||
authorId String
|
||||
authorName String
|
||||
authorType String // "super_admin" or "tenant_user"
|
||||
content String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
ticket SupportTicket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
||||
author SuperAdmin? @relation(fields: [authorId], references: [id])
|
||||
attachments SupportTicketAttachment[]
|
||||
|
||||
@@index([ticketId])
|
||||
@@index([authorId])
|
||||
@@map("support_ticket_comments")
|
||||
}
|
||||
|
||||
model SupportTicketAttachment {
|
||||
id String @id @default(uuid())
|
||||
ticketId String
|
||||
commentId String?
|
||||
fileName String
|
||||
originalName String
|
||||
mimeType String
|
||||
sizeBytes Int
|
||||
uploadedBy String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
ticket SupportTicket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
||||
comment SupportTicketComment? @relation(fields: [commentId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([ticketId])
|
||||
@@index([commentId])
|
||||
@@map("support_ticket_attachments")
|
||||
}
|
||||
29
packages/admin-db/prisma/seed.ts
Normal file
29
packages/admin-db/prisma/seed.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { PrismaClient } from '../generated';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
const password = await bcrypt.hash('SuperAdmin@123', 12);
|
||||
|
||||
const admin = await prisma.superAdmin.upsert({
|
||||
where: { email: 'superadmin@fiberops.dev' },
|
||||
update: {},
|
||||
create: {
|
||||
email: 'superadmin@fiberops.dev',
|
||||
password,
|
||||
firstName: 'Super',
|
||||
lastName: 'Admin',
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`Seeded superadmin: ${admin.email}`);
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(() => prisma.$disconnect());
|
||||
Reference in New Issue
Block a user