update README
This commit is contained in:
18
ospabhost/backend/prisma/add_custom_storage_plan.sql
Normal file
18
ospabhost/backend/prisma/add_custom_storage_plan.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
-- Добавить колонку pricePerGb для расчёта кастомного тарифа
|
||||
ALTER TABLE storage_plan ADD COLUMN pricePerGb DECIMAL(10, 4) NULL AFTER price;
|
||||
|
||||
-- Добавить кастомный тариф
|
||||
INSERT INTO storage_plan
|
||||
(code, name, price, pricePerGb, quotaGb, bandwidthGb, requestLimit, `order`, isActive, description)
|
||||
VALUES
|
||||
('custom', 'Custom', 0, 0.5, 0, 0, 'Неограниченно', 999, TRUE, 'Кастомный тариф - укажите нужное количество GB')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
price = VALUES(price),
|
||||
pricePerGb = VALUES(pricePerGb),
|
||||
quotaGb = VALUES(quotaGb),
|
||||
bandwidthGb = VALUES(bandwidthGb),
|
||||
requestLimit = VALUES(requestLimit),
|
||||
`order` = VALUES(`order`),
|
||||
isActive = VALUES(isActive),
|
||||
description = VALUES(description);
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `storage_console_credential` ADD COLUMN `lastGeneratedAt` DATETIME(3) NULL;
|
||||
@@ -1,6 +0,0 @@
|
||||
-- Добавление полей для интеграции с VPS Panel
|
||||
ALTER TABLE `server` ADD COLUMN `panelVpsId` INT,
|
||||
ADD COLUMN `panelSyncStatus` VARCHAR(255) DEFAULT 'pending';
|
||||
|
||||
-- Создание индекса для быстрого поиска серверов по ID на панели
|
||||
CREATE INDEX `idx_panelVpsId` ON `server`(`panelVpsId`);
|
||||
@@ -0,0 +1,18 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `storage_plan` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`code` VARCHAR(64) NOT NULL,
|
||||
`name` VARCHAR(128) NOT NULL,
|
||||
`price` DOUBLE NOT NULL,
|
||||
`quotaGb` INTEGER NOT NULL,
|
||||
`bandwidthGb` INTEGER NOT NULL,
|
||||
`requestLimit` VARCHAR(64) NOT NULL,
|
||||
`order` INTEGER NOT NULL DEFAULT 0,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
`description` VARCHAR(191) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `storage_plan_code_key`(`code`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `storage_bucket`
|
||||
ADD CONSTRAINT `storage_bucket_plan_fkey`
|
||||
FOREIGN KEY (`plan`) REFERENCES `storage_plan`(`code`) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||
@@ -0,0 +1,13 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `storage_console_credential` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`bucketId` INTEGER NOT NULL,
|
||||
`login` VARCHAR(191) NOT NULL,
|
||||
`passwordHash` VARCHAR(191) NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `storage_console_credential_bucketId_key`(`bucketId`),
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `storage_console_credential_bucketId_fkey` FOREIGN KEY (`bucketId`) REFERENCES `storage_bucket`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
@@ -0,0 +1,22 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `storage_plan` ADD COLUMN `pricePerGb` DECIMAL(10,4) NULL AFTER `price`;
|
||||
ALTER TABLE `storage_plan` ADD COLUMN `bandwidthPerGb` DECIMAL(10,4) NULL AFTER `pricePerGb`;
|
||||
ALTER TABLE `storage_plan` ADD COLUMN `requestsPerGb` INT NULL AFTER `bandwidthPerGb`;
|
||||
|
||||
-- Add custom storage plan (цена, трафик и операции считаются пропорционально GB)
|
||||
INSERT INTO `storage_plan`
|
||||
(`code`, `name`, `price`, `pricePerGb`, `bandwidthPerGb`, `requestsPerGb`, `quotaGb`, `bandwidthGb`, `requestLimit`, `order`, `isActive`, `description`, `createdAt`, `updatedAt`)
|
||||
VALUES
|
||||
('custom', 'Custom', 0, 0.5, 1.2, 100000, 0, 0, '', 999, true, 'Кастомный тариф - укажите нужное количество GB', NOW(), NOW())
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`name` = VALUES(`name`),
|
||||
`price` = VALUES(`price`),
|
||||
`pricePerGb` = VALUES(`pricePerGb`),
|
||||
`bandwidthPerGb` = VALUES(`bandwidthPerGb`),
|
||||
`requestsPerGb` = VALUES(`requestsPerGb`),
|
||||
`quotaGb` = VALUES(`quotaGb`),
|
||||
`bandwidthGb` = VALUES(`bandwidthGb`),
|
||||
`requestLimit` = VALUES(`requestLimit`),
|
||||
`order` = VALUES(`order`),
|
||||
`isActive` = VALUES(`isActive`),
|
||||
`description` = VALUES(`description`);
|
||||
@@ -31,6 +31,7 @@ model User {
|
||||
posts Post[] @relation("PostAuthor") // Статьи блога
|
||||
comments Comment[] @relation("UserComments") // Комментарии
|
||||
buckets StorageBucket[] // S3 хранилища пользователя
|
||||
checkoutSessions StorageCheckoutSession[]
|
||||
|
||||
// Новые relations для расширенных настроек
|
||||
sessions Session[]
|
||||
@@ -377,7 +378,7 @@ model StorageBucket {
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
name String // Уникальное имя бакета в рамках пользователя
|
||||
plan String // Выбранный тариф (basic, standard, plus, pro, enterprise)
|
||||
plan String // Код тарифа из StoragePlan
|
||||
quotaGb Int // Лимит включённого объёма в GB
|
||||
usedBytes BigInt @default(0) // Текущий объём хранения в байтах
|
||||
objectCount Int @default(0)
|
||||
@@ -391,6 +392,10 @@ model StorageBucket {
|
||||
lastBilledAt DateTime?
|
||||
autoRenew Boolean @default(true)
|
||||
usageSyncedAt DateTime?
|
||||
storagePlan StoragePlan? @relation(fields: [plan], references: [code])
|
||||
regionConfig StorageRegion @relation("BucketRegion", fields: [region], references: [code])
|
||||
storageClassConfig StorageClass @relation("BucketClass", fields: [storageClass], references: [code])
|
||||
consoleCredential StorageConsoleCredential?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
@@ -398,6 +403,8 @@ model StorageBucket {
|
||||
accessKeys StorageAccessKey[]
|
||||
|
||||
@@index([userId])
|
||||
@@index([region])
|
||||
@@index([storageClass])
|
||||
@@unique([userId, name]) // Имя уникально в рамках пользователя
|
||||
@@map("storage_bucket")
|
||||
}
|
||||
@@ -416,4 +423,98 @@ model StorageAccessKey {
|
||||
|
||||
@@index([bucketId])
|
||||
@@map("storage_access_key")
|
||||
}
|
||||
|
||||
model StorageConsoleCredential {
|
||||
id Int @id @default(autoincrement())
|
||||
bucketId Int @unique
|
||||
bucket StorageBucket @relation(fields: [bucketId], references: [id], onDelete: Cascade)
|
||||
|
||||
login String
|
||||
passwordHash String
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
lastGeneratedAt DateTime? // Для rate limiting (1 раз в неделю)
|
||||
|
||||
@@map("storage_console_credential")
|
||||
}
|
||||
|
||||
model StoragePlan {
|
||||
id Int @id @default(autoincrement())
|
||||
code String @unique
|
||||
name String
|
||||
price Float
|
||||
pricePerGb Decimal? @db.Decimal(10, 4) // Цена за 1 GB для кастомного тарифа
|
||||
bandwidthPerGb Decimal? @db.Decimal(10, 4) // GB трафика на 1 GB хранения
|
||||
requestsPerGb Int? // Количество операций на 1 GB хранения
|
||||
quotaGb Int // Базовая квота для обычных тарифов (0 для custom)
|
||||
bandwidthGb Int // Базовый трафик для обычных тарифов (0 для custom)
|
||||
requestLimit String // Текстовое описание лимита операций
|
||||
order Int @default(0)
|
||||
isActive Boolean @default(true)
|
||||
description String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
|
||||
buckets StorageBucket[]
|
||||
checkoutSessions StorageCheckoutSession[]
|
||||
|
||||
@@map("storage_plan")
|
||||
}
|
||||
|
||||
model StorageCheckoutSession {
|
||||
id String @id @default(uuid())
|
||||
userId Int?
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
||||
planId Int
|
||||
plan StoragePlan @relation(fields: [planId], references: [id])
|
||||
planCode String
|
||||
planName String
|
||||
planDescription String?
|
||||
price Float
|
||||
quotaGb Int
|
||||
bandwidthGb Int
|
||||
requestLimit String
|
||||
createdAt DateTime @default(now())
|
||||
expiresAt DateTime
|
||||
consumedAt DateTime?
|
||||
|
||||
@@index([userId])
|
||||
@@index([planId])
|
||||
@@map("storage_checkout_session")
|
||||
}
|
||||
|
||||
model StorageRegion {
|
||||
id Int @id @default(autoincrement())
|
||||
code String @unique
|
||||
name String
|
||||
description String?
|
||||
endpoint String?
|
||||
isDefault Boolean @default(false)
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
buckets StorageBucket[] @relation("BucketRegion")
|
||||
|
||||
@@map("storage_region")
|
||||
}
|
||||
|
||||
model StorageClass {
|
||||
id Int @id @default(autoincrement())
|
||||
code String @unique
|
||||
name String
|
||||
description String?
|
||||
redundancy String?
|
||||
performance String?
|
||||
retrievalFee String?
|
||||
isDefault Boolean @default(false)
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
buckets StorageBucket[] @relation("BucketClass")
|
||||
|
||||
@@map("storage_class")
|
||||
}
|
||||
24
ospabhost/backend/prisma/storage_plans_seed.sql
Normal file
24
ospabhost/backend/prisma/storage_plans_seed.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
INSERT INTO storage_plan
|
||||
(code, name, price, quotaGb, bandwidthGb, requestLimit, `order`, isActive, description)
|
||||
VALUES
|
||||
('dev-50', 'Developer 50', 99, 50, 100, '100 000 операций', 1, TRUE, 'ru-central-1 регион | S3-совместимый API | Версионирование и presigned URL | Панель управления и уведомления | Access Key / Secret Key'),
|
||||
('dev-100', 'Developer 100', 149, 100, 200, '250 000 операций', 2, TRUE, 'ru-central-1 регион | S3-совместимый API | Версионирование и presigned URL | Панель управления и уведомления | Access Key / Secret Key'),
|
||||
('dev-250', 'Developer 250', 199, 250, 400, '500 000 операций', 3, TRUE, 'ru-central-1 регион | S3-совместимый API | Версионирование и presigned URL | Панель управления и уведомления | Access Key / Secret Key'),
|
||||
('team-500', 'Team 500', 349, 500, 800, '1 000 000 операций', 4, TRUE, 'ru-central-1 регион | S3-совместимый API | Версионирование и presigned URL | Панель управления и уведомления | Access Key / Secret Key'),
|
||||
('team-1000', 'Team 1000', 499, 1000, 1500, '2 000 000 операций', 5, TRUE, 'ru-central-1 регион | S3-совместимый API | Версионирование и presigned URL | Панель управления и уведомления | Access Key / Secret Key'),
|
||||
('team-2000', 'Team 2000', 749, 2000, 3000, '5 000 000 операций', 6, TRUE, 'ru-central-1 регион | S3-совместимый API | Версионирование и presigned URL | Панель управления и уведомления | Access Key / Secret Key'),
|
||||
('scale-5000', 'Scale 5K', 1099, 5000, 6000, '10 000 000 операций', 7, TRUE, 'ru-central-1 регион | S3-совместимый API | Версионирование и presigned URL | Панель управления и уведомления | Access Key / Secret Key'),
|
||||
('scale-10000', 'Scale 10K', 1599, 10000, 12000, '20 000 000 операций', 8, TRUE, 'ru-central-1 регион | S3-совместимый API | Версионирование и presigned URL | Панель управления и уведомления | Access Key / Secret Key'),
|
||||
('scale-20000', 'Scale 20K', 2199, 20000, 25000, '50 000 000 операций', 9, TRUE, 'ru-central-1 регион | S3-совместимый API | Версионирование и presigned URL | Панель управления и уведомления | Access Key / Secret Key'),
|
||||
('enterprise-50000', 'Enterprise 50K', 3999, 50000, 60000, '100 000 000 операций', 10, TRUE, 'ru-central-1 регион | S3-совместимый API | Версионирование и presigned URL | Панель управления и уведомления | Access Key / Secret Key'),
|
||||
('enterprise-100000', 'Enterprise 100K', 6999, 100000, 120000, '250 000 000 операций', 11, TRUE, 'ru-central-1 регион | S3-совместимый API | Версионирование и presigned URL | Панель управления и уведомления | Access Key / Secret Key'),
|
||||
('enterprise-250000', 'Enterprise 250K', 11999, 250000, 300000, '500 000 000 операций', 12, TRUE, 'ru-central-1 регион | S3-совместимый API | Версионирование и presigned URL | Панель управления и уведомления | Access Key / Secret Key')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
price = VALUES(price),
|
||||
quotaGb = VALUES(quotaGb),
|
||||
bandwidthGb = VALUES(bandwidthGb),
|
||||
requestLimit = VALUES(requestLimit),
|
||||
`order` = VALUES(`order`),
|
||||
isActive = VALUES(isActive),
|
||||
description = VALUES(description);
|
||||
Reference in New Issue
Block a user