Сделан баланс, проверка чеков, начата система создания серверов

This commit is contained in:
Georgiy Syralev
2025-09-18 16:26:11 +03:00
parent 515d31ee9e
commit cce9e7b996
54 changed files with 1914 additions and 316 deletions

View File

@@ -0,0 +1,9 @@
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
await prisma.operatingSystem.deleteMany({ where: { type: 'windows' } });
console.log('Все Windows Server ОС удалены!');
}
main().finally(() => prisma.$disconnect());

View File

@@ -0,0 +1,5 @@
-- AddForeignKey
ALTER TABLE `Ticket` ADD CONSTRAINT `Ticket_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Response` ADD CONSTRAINT `Response_operatorId_fkey` FOREIGN KEY (`operatorId`) REFERENCES `User`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@@ -0,0 +1,14 @@
-- CreateTable
CREATE TABLE `Check` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`userId` INTEGER NOT NULL,
`amount` DOUBLE NOT NULL,
`status` VARCHAR(191) NOT NULL DEFAULT 'pending',
`fileUrl` VARCHAR(191) NOT NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `Check` ADD CONSTRAINT `Check_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE `user` ADD COLUMN `balance` DOUBLE NOT NULL DEFAULT 0;

View File

@@ -0,0 +1,45 @@
-- CreateTable
CREATE TABLE `Tariff` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`name` VARCHAR(191) NOT NULL,
`price` DOUBLE NOT NULL,
`description` VARCHAR(191) NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
UNIQUE INDEX `Tariff_name_key`(`name`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `OperatingSystem` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`name` VARCHAR(191) NOT NULL,
`type` VARCHAR(191) NOT NULL,
`template` VARCHAR(191) NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
UNIQUE INDEX `OperatingSystem_name_key`(`name`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `Server` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`userId` INTEGER NOT NULL,
`tariffId` INTEGER NOT NULL,
`osId` INTEGER NOT NULL,
`status` VARCHAR(191) NOT NULL DEFAULT 'stopped',
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `Server` ADD CONSTRAINT `Server_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Server` ADD CONSTRAINT `Server_tariffId_fkey` FOREIGN KEY (`tariffId`) REFERENCES `Tariff`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Server` ADD CONSTRAINT `Server_osId_fkey` FOREIGN KEY (`osId`) REFERENCES `OperatingSystem`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@@ -1,4 +1,3 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
@@ -10,14 +9,61 @@ datasource db {
url = env("DATABASE_URL")
}
// This is your Prisma schema file,
model Tariff {
id Int @id @default(autoincrement())
name String @unique
price Float
description String?
createdAt DateTime @default(now())
servers Server[]
}
model OperatingSystem {
id Int @id @default(autoincrement())
name String @unique
type String // linux, windows, etc
template String? // путь к шаблону для контейнера
createdAt DateTime @default(now())
servers Server[]
}
model Server {
id Int @id @default(autoincrement())
userId Int
tariffId Int
osId Int
status String @default("stopped") // running, stopped, etc
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
tariff Tariff @relation(fields: [tariffId], references: [id])
os OperatingSystem @relation(fields: [osId], references: [id])
}
model User {
id Int @id @default(autoincrement())
username String
email String @unique
password String
createdAt DateTime @default(now())
plans Plan[]
operator Int @default(0) // Добавляем новую колонку operator
plans Plan[] @relation("UserPlans")
operator Int @default(0)
tickets Ticket[] @relation("UserTickets")
responses Response[] @relation("OperatorResponses")
checks Check[] @relation("UserChecks")
balance Float @default(0)
servers Server[]
}
model Check {
id Int @id @default(autoincrement())
userId Int
amount Float
status String @default("pending") // pending, approved, rejected
fileUrl String
createdAt DateTime @default(now())
user User @relation("UserChecks", fields: [userId], references: [id])
}
model Plan {
@@ -28,8 +74,8 @@ model Plan {
isCustom Boolean @default(false)
createdAt DateTime @default(now())
userId Int
owner User @relation(fields: [userId], references: [id])
services Service[]
owner User @relation("UserPlans", fields: [userId], references: [id])
services Service[] @relation("PlanServices")
}
model Service {
@@ -37,7 +83,7 @@ model Service {
name String @unique
price Float
planId Int?
plan Plan? @relation(fields: [planId], references: [id])
plan Plan? @relation("PlanServices", fields: [planId], references: [id])
}
model Ticket {
@@ -48,10 +94,8 @@ model Ticket {
status String @default("open")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
responses Response[] // связь
// Если нужна связь с User:
// user User @relation(fields: [userId], references: [id])
responses Response[] @relation("TicketResponses")
user User? @relation("UserTickets", fields: [userId], references: [id])
}
model Response {
@@ -60,5 +104,6 @@ model Response {
operatorId Int
message String
createdAt DateTime @default(now())
ticket Ticket @relation(fields: [ticketId], references: [id]) // <-- обратная связь
ticket Ticket @relation("TicketResponses", fields: [ticketId], references: [id])
operator User @relation("OperatorResponses", fields: [operatorId], references: [id])
}

View File

@@ -0,0 +1,27 @@
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
const tariffs = [
{ name: 'Минимальный', price: 150, description: '1 ядро, 1ГБ RAM, 20ГБ SSD' },
{ name: 'Базовый', price: 300, description: '2 ядра, 2ГБ RAM, 40ГБ SSD' },
{ name: 'Старт', price: 500, description: '2 ядра, 4ГБ RAM, 60ГБ SSD' },
{ name: 'Оптимальный', price: 700, description: '4 ядра, 4ГБ RAM, 80ГБ SSD' },
{ name: 'Профи', price: 1000, description: '4 ядра, 8ГБ RAM, 120ГБ SSD' },
{ name: 'Бизнес', price: 1500, description: '8 ядер, 16ГБ RAM, 200ГБ SSD' },
{ name: 'Корпоративный', price: 2000, description: '12 ядер, 24ГБ RAM, 300ГБ SSD' },
{ name: 'Премиум', price: 2500, description: '16 ядер, 32ГБ RAM, 400ГБ SSD' },
{ name: 'Энтерпрайз', price: 2800, description: '24 ядра, 48ГБ RAM, 500ГБ SSD' },
{ name: 'Максимум', price: 3000, description: '32 ядра, 64ГБ RAM, 1ТБ SSD' },
];
for (const t of tariffs) {
await prisma.tariff.upsert({
where: { name: t.name },
update: t,
create: t,
});
}
console.log('Тарифы успешно добавлены!');
}
main().finally(() => prisma.$disconnect());

View File

@@ -0,0 +1,24 @@
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
const oses = [
{ name: 'Ubuntu 22.04', type: 'linux', template: 'local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst' },
{ name: 'Debian 12', type: 'linux', template: 'local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst' },
{ name: 'CentOS 9', type: 'linux', template: 'local:vztmpl/centos-9-stream-default_20240828_amd64.tar.xz' },
{ name: 'AlmaLinux 9', type: 'linux', template: 'local:vztmpl/almalinux-9-default_20240911_amd64.tar.xz' },
{ name: 'Rocky Linux 9', type: 'linux', template: 'local:vztmpl/rockylinux-9-default_20240912_amd64.tar.xz' },
{ name: 'Arch Linux', type: 'linux', template: 'local:vztmpl/archlinux-base_20240911-1_amd64.tar.zst' },
{ name: 'Fedora 41', type: 'linux', template: 'local:vztmpl/fedora-41-default_20241118_amd64.tar.xz' },
];
for (const os of oses) {
await prisma.operatingSystem.upsert({
where: { name: os.name },
update: os,
create: os,
});
}
console.log('ОС успешно добавлены!');
}
main().finally(() => prisma.$disconnect());