Compare commits

2 Commits
1 ... master

Author SHA1 Message Date
baa670b4fd Добавлена возможность подключаться из вне 2026-02-10 13:03:46 +05:00
5a419156ed - Настроена среда на Ubuntu 24.04: проверены Node.js и PostgreSQL, выполнен npm run install:all.
- Пересобран bcrypt под Linux (npm rebuild / переустановка), после чего успешно отработал prisma seed (созданы пользователи и загружены СБЦ).
- Создано виртуальное окружение backend/pdf_generator/venv и установлены зависимости из requirements.txt; backend настроен использовать python из этого venv при генерации PDF (pdf-python.service.ts).
- Переключён AI-провайдер с LMStudio на Ollama: в ai.service.ts добавлена поддержка Ollama, в .env и .env.example выставлены AI_PROVIDER=ollama, OLLAMA_API_URL=http://192.168.88.160:11434 и OLLAMA_MODEL=gemma3n:e4b.
- Перезапущены backend и frontend; проверено, что API /api/health отвечает, а Ollama (gemma3n:e4b) успешно обрабатывает chat-запросы.
2026-02-10 12:27:53 +05:00
1909 changed files with 374428 additions and 11357 deletions

View File

@@ -7,8 +7,8 @@ NODE_ENV=development
JWT_SECRET=change-this-in-production-to-random-string
# AI Providers
AI_PROVIDER=iieasy
# iieasy | lmstudio
AI_PROVIDER=ollama
# iieasy | lmstudio | ollama
# iieasy.ru API
IIEASY_API_URL=https://ai.iieasy.ru/v1
@@ -19,6 +19,10 @@ IIEASY_MODEL=google/gemma-3n-e4b
LMSTUDIO_API_URL=http://localhost:1234/v1
LMSTUDIO_MODEL=local-model
# Ollama
OLLAMA_API_URL=http://192.168.88.160:11434
OLLAMA_MODEL=gemma3n:e4b
# Default company settings
DEFAULT_EXECUTOR=ООО "ГеоВектор"
DEFAULT_VAT_RATE=20

View File

@@ -7,7 +7,7 @@ NODE_ENV=development
# AI Providers
AI_PROVIDER=iieasy
# iieasy | lmstudio
# iieasy | lmstudio | ollama
# iieasy.ru API
IIEASY_API_URL=https://ai.iieasy.ru/v1
@@ -18,6 +18,10 @@ IIEASY_MODEL=google/gemma-3n-e4b
LMSTUDIO_API_URL=http://localhost:1234/v1
LMSTUDIO_MODEL=local-model
# Ollama
OLLAMA_API_URL=http://192.168.88.160:11434
OLLAMA_MODEL=gemma3n:e4b
# Default company settings
DEFAULT_EXECUTOR=ООО "ГеоВектор"
DEFAULT_VAT_RATE=20

View File

@@ -1,5 +0,0 @@
# Шрифты для PDF
Для генерации PDF с кириллицей используются шрифты PT Sans из npm-пакета `@fontsource/pt-sans` (файлы в `node_modules/@fontsource/pt-sans/files/`).
При необходимости можно положить сюда свои TTF/WOFF (например, PTSans-Regular.ttf и PTSans-Bold.ttf) — тогда в `pdf.service.ts` нужно указать путь к этой папке через `path.join(process.cwd(), 'fonts', '...')`.

View File

@@ -276,6 +276,7 @@
"integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33",
@@ -344,6 +345,7 @@
"integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@@ -2633,6 +2635,7 @@
"devOptional": true,
"hasInstallScript": true,
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"@prisma/engines": "5.22.0"
},
@@ -3374,6 +3377,7 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"

0
backend/node_modules/.prisma/client/default.d.ts generated vendored Executable file → Normal file
View File

0
backend/node_modules/.prisma/client/default.js generated vendored Executable file → Normal file
View File

0
backend/node_modules/.prisma/client/edge.d.ts generated vendored Executable file → Normal file
View File

25
backend/node_modules/.prisma/client/edge.js generated vendored Executable file → Normal file

File diff suppressed because one or more lines are too long

12
backend/node_modules/.prisma/client/index-browser.js generated vendored Executable file → Normal file
View File

@@ -219,10 +219,13 @@ exports.Prisma.EstimateScalarFieldEnum = {
totalLaboratory: 'totalLaboratory',
subtotal: 'subtotal',
regionalCoef: 'regionalCoef',
regionalCoefDocRef: 'regionalCoefDocRef',
inflationIndex: 'inflationIndex',
inflationDocRef: 'inflationDocRef',
companyCoef: 'companyCoef',
companyCoefDocRef: 'companyCoefDocRef',
executorCoef: 'executorCoef',
executorCoefDocRef: 'executorCoefDocRef',
withVat: 'withVat',
totalWithoutVat: 'totalWithoutVat',
vatRate: 'vatRate',
@@ -249,6 +252,14 @@ exports.Prisma.EstimateShareScalarFieldEnum = {
createdAt: 'createdAt'
};
exports.Prisma.EstimateShareNoteScalarFieldEnum = {
id: 'id',
shareId: 'shareId',
authorId: 'authorId',
content: 'content',
createdAt: 'createdAt'
};
exports.Prisma.EstimateItemScalarFieldEnum = {
id: 'id',
estimateId: 'estimateId',
@@ -355,6 +366,7 @@ exports.Prisma.ModelName = {
Estimate: 'Estimate',
EstimateVersion: 'EstimateVersion',
EstimateShare: 'EstimateShare',
EstimateShareNote: 'EstimateShareNote',
EstimateItem: 'EstimateItem',
EstimateTotal: 'EstimateTotal',
Setting: 'Setting',

1875
backend/node_modules/.prisma/client/index.d.ts generated vendored Executable file → Normal file

File diff suppressed because it is too large Load Diff

29
backend/node_modules/.prisma/client/index.js generated vendored Executable file → Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

2
backend/node_modules/.prisma/client/package.json generated vendored Executable file → Normal file
View File

@@ -1,5 +1,5 @@
{
"name": "prisma-client-4b58c981519ea022802510544edb111bbd4ef5e4d3b50b2269f96083d9bf4ae3",
"name": "prisma-client-aa42ad392173f3ebbcce688c9d47fd7d65145cf816fa2f07c9d3255147711e22",
"main": "index.js",
"types": "index.d.ts",
"browser": "index-browser.js",

View File

@@ -9,7 +9,7 @@ datasource db {
url = env("DATABASE_URL")
}
// Справочники базовых цен
// Справочники базовых цен (СБЦ)
model PriceBook {
id String @id @default(uuid())
code String @unique // SBC-GEODESY-2004, SBC-GEOLOGY-1999
@@ -114,8 +114,9 @@ model User {
estimates Estimate[]
chatSessions ChatSession[]
ownedShares EstimateShare[] @relation("ShareOwner")
receivedShares EstimateShare[] @relation("ShareReceiver")
ownedShares EstimateShare[] @relation("ShareOwner")
receivedShares EstimateShare[] @relation("ShareReceiver")
shareNotes EstimateShareNote[]
}
// Направления изысканий
@@ -146,13 +147,17 @@ model Estimate {
subtotal Decimal? @db.Decimal(14, 2) // Итого по изысканиям
// Коэффициенты и пересчет
regionalCoef Decimal? @db.Decimal(6, 4) // Районный коэффициент
inflationIndex Decimal? @db.Decimal(10, 4) // Индекс перевода в текущие цены
inflationDocRef String? // Ссылка на документ с индексом
companyCoef Decimal? @db.Decimal(6, 4) // Коэффициент компании (Газпром и т.д.)
executorCoef Decimal? @db.Decimal(6, 4) // Коэффициент исполнителя
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) // Сумма НДС
@@ -162,11 +167,26 @@ model Estimate {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade)
direction SurveyDirection @relation(fields: [directionId], references: [id])
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])
}
// Шаринг сметы с другим пользователем
@@ -177,14 +197,29 @@ model EstimateShare {
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)
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())

0
backend/node_modules/.prisma/client/wasm.d.ts generated vendored Executable file → Normal file
View File

12
backend/node_modules/.prisma/client/wasm.js generated vendored Executable file → Normal file
View File

@@ -219,10 +219,13 @@ exports.Prisma.EstimateScalarFieldEnum = {
totalLaboratory: 'totalLaboratory',
subtotal: 'subtotal',
regionalCoef: 'regionalCoef',
regionalCoefDocRef: 'regionalCoefDocRef',
inflationIndex: 'inflationIndex',
inflationDocRef: 'inflationDocRef',
companyCoef: 'companyCoef',
companyCoefDocRef: 'companyCoefDocRef',
executorCoef: 'executorCoef',
executorCoefDocRef: 'executorCoefDocRef',
withVat: 'withVat',
totalWithoutVat: 'totalWithoutVat',
vatRate: 'vatRate',
@@ -249,6 +252,14 @@ exports.Prisma.EstimateShareScalarFieldEnum = {
createdAt: 'createdAt'
};
exports.Prisma.EstimateShareNoteScalarFieldEnum = {
id: 'id',
shareId: 'shareId',
authorId: 'authorId',
content: 'content',
createdAt: 'createdAt'
};
exports.Prisma.EstimateItemScalarFieldEnum = {
id: 'id',
estimateId: 'estimateId',
@@ -355,6 +366,7 @@ exports.Prisma.ModelName = {
Estimate: 'Estimate',
EstimateVersion: 'EstimateVersion',
EstimateShare: 'EstimateShare',
EstimateShareNote: 'EstimateShareNote',
EstimateItem: 'EstimateItem',
EstimateTotal: 'EstimateTotal',
Setting: 'Setting',

Binary file not shown.

Binary file not shown.

0
backend/node_modules/bcrypt/.editorconfig generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/.github/workflows/ci.yaml generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/.travis.yml generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/CHANGELOG.md generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/ISSUE_TEMPLATE.md generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/LICENSE generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/Makefile generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/README.md generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/SECURITY.md generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/appveyor.yml generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/bcrypt.js generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/binding.gyp generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/examples/async_compare.js generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/examples/forever_gen_salt.js generated vendored Executable file → Normal file
View File

Binary file not shown.

0
backend/node_modules/bcrypt/package.json generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/promises.js generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/src/bcrypt.cc generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/src/bcrypt_node.cc generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/src/blowfish.cc generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/src/node_blf.h generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/test/async.test.js generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/test/implementation.test.js generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/test/promise.test.js generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/test/repetitions.test.js generated vendored Executable file → Normal file
View File

0
backend/node_modules/bcrypt/test/sync.test.js generated vendored Executable file → Normal file
View File

Binary file not shown.

View File

@@ -309,6 +309,7 @@
"integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33",
@@ -377,6 +378,7 @@
"integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@@ -2681,6 +2683,7 @@
"devOptional": true,
"hasInstallScript": true,
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"@prisma/engines": "5.22.0"
},
@@ -3422,6 +3425,7 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"

View File

@@ -25,12 +25,12 @@
"cors": "^2.8.5",
"dotenv": "^16.4.1",
"express": "^4.18.2",
"jsonwebtoken": "^9.0.2",
"multer": "^1.4.5-lts.1",
"pdf-lib": "^1.17.1",
"pdfkit": "^0.14.0",
"uuid": "^9.0.1",
"xlsx": "^0.18.5",
"jsonwebtoken": "^9.0.2"
"xlsx": "^0.18.5"
},
"devDependencies": {
"@types/bcrypt": "^5.0.2",

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,17 +1,5 @@
# Шрифты для PDF сметы
# Шрифты для PDF
Для корректного отображения кириллицы в PDF положите сюда TTF-шрифты с поддержкой русского языка.
Для генерации PDF с кириллицей используются шрифты PT Sans из npm-пакета `@fontsource/pt-sans` (файлы в `node_modules/@fontsource/pt-sans/files/`).
**Варианты:**
1. **PT Sans** (рекомендуется, лицензия OFL)
Скачайте с [Google Fonts](https://fonts.google.com/specimen/PT+Sans) и поместите в эту папку:
- `PTSans-Regular.ttf`
- `PTSans-Bold.ttf`
2. **Arial**
На Windows можно скопировать из `C:\Windows\Fonts\arial.ttf` (и при необходимости arialbd.ttf для жирного).
3. Любой другой TTF с кириллицей (например, DejaVu Sans, Open Sans).
После добавления шрифтов перезапустите backend.
При необходимости можно положить сюда свои TTF/WOFF (например, PTSans-Regular.ttf и PTSans-Bold.ttf) — тогда в `pdf.service.ts` нужно указать путь к этой папке через `path.join(process.cwd(), 'fonts', '...')`.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More