Files
geo/backend/prisma/schema.prisma
2026-02-04 00:11:19 +05:00

316 lines
14 KiB
Plaintext
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Prisma schema for Estimate Assistant
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// Справочники базовых цен (СБЦ)
model PriceBook {
id String @id @default(uuid())
code String @unique // SBC-GEODESY-2004, SBC-GEOLOGY-1999
name String // Полное название справочника
baseDate DateTime // Дата базовых цен (01.01.2001, 01.01.1991)
approvedBy String? // Кем утвержден
effectiveDate DateTime? // Дата введения в действие
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tables PriceTable[]
items PriceItem[]
}
// Таблицы справочников
model PriceTable {
id String @id @default(uuid())
priceBookId String
tableNumber Int // Номер таблицы (8, 9, 13, и т.д.)
name String // Название таблицы
unit String // Единица измерения (1 пункт, 1 га, 1 км и т.д.)
notes Json? // Примечания к таблице
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
priceBook PriceBook @relation(fields: [priceBookId], references: [id], onDelete: Cascade)
items PriceItem[]
@@unique([priceBookId, tableNumber])
}
// Позиции справочников (расценки)
model PriceItem {
id String @id @default(uuid())
priceBookId String
priceTableId String
paragraph String // Номер параграфа (8-1, 9-4-1 и т.д.)
workType String // Тип работы / наименование
description String? // Дополнительное описание
// Цены (полевые/камеральные для разных категорий)
priceField1 Decimal? @db.Decimal(12, 2) // Полевые работы, категория 1
priceOffice1 Decimal? @db.Decimal(12, 2) // Камеральные работы, категория 1
priceField2 Decimal? @db.Decimal(12, 2) // Полевые работы, категория 2
priceOffice2 Decimal? @db.Decimal(12, 2) // Камеральные работы, категория 2
priceField3 Decimal? @db.Decimal(12, 2) // Полевые работы, категория 3
priceOffice3 Decimal? @db.Decimal(12, 2) // Камеральные работы, категория 3
priceSimple Decimal? @db.Decimal(12, 2) // Простая цена (без категорий)
// Дополнительные параметры
attributes Json? // Доп. атрибуты (масштаб, глубина, диаметр и т.д.)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
priceBook PriceBook @relation(fields: [priceBookId], references: [id], onDelete: Cascade)
priceTable PriceTable @relation(fields: [priceTableId], references: [id], onDelete: Cascade)
estimateItems EstimateItem[]
@@index([paragraph])
@@index([workType])
}
// Коэффициенты
model Coefficient {
id String @id @default(uuid())
type String // regional, transport_internal, transport_external, seasonal, special
code String // Уникальный код коэффициента
name String // Название
value Decimal @db.Decimal(6, 4) // Значение коэффициента
description String? // Описание
conditions Json? // Условия применения
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([type, code])
}
// Индексы инфляции (перевод в текущие цены)
model InflationIndex {
id String @id @default(uuid())
baseDate DateTime // Базовая дата цен
effectiveFrom DateTime // Дата начала действия индекса
effectiveTo DateTime? // Дата окончания (null = текущий)
indexValue Decimal @db.Decimal(10, 4) // Значение индекса
documentRef String? // Ссылка на документ (Письмо Минстроя и т.д.)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// Пользователи
model User {
id String @id @default(uuid())
email String @unique
passwordHash String
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
estimates Estimate[]
chatSessions ChatSession[]
ownedShares EstimateShare[] @relation("ShareOwner")
receivedShares EstimateShare[] @relation("ShareReceiver")
shareNotes EstimateShareNote[]
}
// Направления изысканий
model SurveyDirection {
id String @id @default(uuid())
code String @unique // geodesy, geology, ecology, hydrology
name String // Инженерно-геодезические изыскания
shortName String // Геодезия
isActive Boolean @default(true)
estimates Estimate[]
}
// Сметы
model Estimate {
id String @id @default(uuid())
number String // Номер сметы
directionId String
ownerId String // Владелец сметы
objectName String // Название объекта
customer String // Заказчик
executor String // Исполнитель
// Итоговые значения
totalFieldWorks Decimal? @db.Decimal(14, 2) // Итого полевые работы
totalOfficeWorks Decimal? @db.Decimal(14, 2) // Итого камеральные работы
totalLaboratory Decimal? @db.Decimal(14, 2) // Итого лабораторные
subtotal Decimal? @db.Decimal(14, 2) // Итого по изысканиям
// Коэффициенты и пересчет
regionalCoef Decimal? @db.Decimal(6, 4) // Районный коэффициент
regionalCoefDocRef String? // Описание (С районным коэффициентом и т.д.)
inflationIndex Decimal? @db.Decimal(10, 4) // Индекс перевода в текущие цены
inflationDocRef String? // Ссылка на документ (Письмо Минстроя и т.д.)
companyCoef Decimal? @db.Decimal(6, 4) // Коэффициент компании (Газпром и т.д.)
companyCoefDocRef String? // Описание (Коэффициент ОАО «Газпром» №544 и т.д.)
executorCoef Decimal? @db.Decimal(6, 4) // Коэффициент исполнителя
executorCoefDocRef String? // Описание (Коэффициент ООО «ГеоВектор» и т.д.)
// Итоги
withVat Boolean @default(true) // Смета с НДС (true) или без НДС (false)
totalWithoutVat Decimal? @db.Decimal(14, 2) // Итого без НДС
vatRate Decimal? @db.Decimal(4, 2) // Ставка НДС (18, 20, 7)
vatAmount Decimal? @db.Decimal(14, 2) // Сумма НДС
totalWithVat Decimal? @db.Decimal(14, 2) // Всего с НДС
status String @default("draft") // draft, completed, approved
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade)
direction SurveyDirection @relation(fields: [directionId], references: [id])
items EstimateItem[]
totals EstimateTotal[]
shares EstimateShare[]
versions EstimateVersion[]
}
// История версий сметы (снимок при сохранении/пересчёте)
model EstimateVersion {
id String @id @default(uuid())
estimateId String
versionNumber Int // Порядковый номер версии по смете
snapshot Json // Полный снимок: estimate + items + totals
createdAt DateTime @default(now())
estimate Estimate @relation(fields: [estimateId], references: [id], onDelete: Cascade)
@@index([estimateId])
@@index([estimateId, createdAt])
}
// Шаринг сметы с другим пользователем
model EstimateShare {
id String @id @default(uuid())
estimateId String
ownerId String // Кто поделился
sharedWithId String // С кем поделились
createdAt DateTime @default(now())
estimate Estimate @relation(fields: [estimateId], references: [id], onDelete: Cascade)
sharedWith User @relation("ShareReceiver", fields: [sharedWithId], references: [id], onDelete: Cascade)
owner User @relation("ShareOwner", fields: [ownerId], references: [id], onDelete: Cascade)
notes EstimateShareNote[]
@@unique([estimateId, sharedWithId])
@@index([sharedWithId])
}
// Заметки к шарингу сметы (кто что написал)
model EstimateShareNote {
id String @id @default(uuid())
shareId String
authorId String
content String @db.Text
createdAt DateTime @default(now())
share EstimateShare @relation(fields: [shareId], references: [id], onDelete: Cascade)
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
@@index([shareId])
}
// Позиции сметы
model EstimateItem {
id String @id @default(uuid())
estimateId String
orderNumber Int // Порядковый номер
sectionType String // field, office, laboratory, transport, other
priceItemId String? // Ссылка на позицию справочника
workName String // Наименование работы
justification String? // Обоснование (ссылка на СБЦ)
basePrice Decimal @db.Decimal(12, 2) // Базовая цена
quantity Decimal @db.Decimal(12, 4) // Объем
unit String? // Единица измерения
// Коэффициенты
coef1 Decimal? @db.Decimal(6, 4) // Коэффициент 1
coef1Desc String? // Описание коэффициента 1
coef2 Decimal? @db.Decimal(6, 4) // Коэффициент 2
coef2Desc String? // Описание коэффициента 2
coef3 Decimal? @db.Decimal(6, 4) // Коэффициент 3
coef3Desc String? // Описание коэффициента 3
totalPrice Decimal @db.Decimal(14, 2) // Итоговая стоимость
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
estimate Estimate @relation(fields: [estimateId], references: [id], onDelete: Cascade)
priceItem PriceItem? @relation(fields: [priceItemId], references: [id])
@@index([estimateId, orderNumber])
}
// Итоговая часть сметы (нижняя часть)
model EstimateTotal {
id String @id @default(uuid())
estimateId String
orderNumber Int // Порядок строки
label String // Название строки (Перевод в текущие цены, НДС и т.д.)
description String? // Дополнительное описание
baseValue Decimal? @db.Decimal(14, 2) // Базовое значение
coefficient Decimal? @db.Decimal(10, 4) // Коэффициент/процент
resultValue Decimal @db.Decimal(14, 2) // Результат
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
estimate Estimate @relation(fields: [estimateId], references: [id], onDelete: Cascade)
@@index([estimateId, orderNumber])
}
// Настройки приложения
model Setting {
id String @id @default(uuid())
key String @unique
value String
type String @default("string") // string, number, boolean, json
category String // general, company, ai, display
label String? // Человекочитаемое название
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// Сессии чата (у каждого пользователя свои контексты ИИ)
model ChatSession {
id String @id @default(uuid())
userId String // Владелец сессии
estimateId String? // Связанная смета (опционально)
status String @default("active") // active, completed
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
messages ChatMessage[]
@@index([userId])
@@index([userId, estimateId])
}
// Сообщения чата
model ChatMessage {
id String @id @default(uuid())
sessionId String
role String // user, assistant, system
content String
metadata Json? // Доп. данные (извлеченные сущности и т.д.)
createdAt DateTime @default(now())
session ChatSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
@@index([sessionId, createdAt])
}