diff --git a/docs/scripts/build-typst-tz.mjs b/docs/scripts/build-typst-tz.mjs
index c865b6d..c87897e 100644
--- a/docs/scripts/build-typst-tz.mjs
+++ b/docs/scripts/build-typst-tz.mjs
@@ -1,313 +1,25 @@
-import { mkdir, readFile, writeFile } from 'node:fs/promises';
+import { mkdir } from 'node:fs/promises';
import { dirname, join, relative } from 'node:path';
import { fileURLToPath } from 'node:url';
import { spawnSync } from 'node:child_process';
// Usage: node docs/scripts/build-typst-tz.mjs
-// Output: docs/export/tz-fregat.typ and docs/export/tz-fregat.pdf
+// Source: docs/tz-fregat.typ
+// Output: docs/export/tz-fregat.pdf
const __dirname = dirname(fileURLToPath(import.meta.url));
const docsDir = join(__dirname, '..');
-const sourceFile = join(docsDir, 'index.md');
+const sourceFile = join(docsDir, 'tz-fregat.typ');
const exportDir = join(docsDir, 'export');
-const typstFile = join(exportDir, 'tz-fregat.typ');
const pdfFile = join(exportDir, 'tz-fregat.pdf');
-const includePattern = /^$/gm;
-
-async function readMarkdownWithIncludes(filePath, seen = new Set()) {
- if (seen.has(filePath)) {
- throw new Error(`Circular include detected: ${filePath}`);
- }
-
- seen.add(filePath);
-
- let content = await readFile(filePath, 'utf8');
- const replacements = [];
-
- for (const match of content.matchAll(includePattern)) {
- const includePath = join(dirname(filePath), match[1]);
- const includeContent = await readMarkdownWithIncludes(includePath, seen);
- replacements.push([match[0], includeContent.trim()]);
- }
-
- for (const [needle, replacement] of replacements) {
- content = content.replace(needle, replacement);
- }
-
- seen.delete(filePath);
-
- return content;
-}
-
-function escapeTypstString(value) {
- return value.replaceAll('\\', '\\\\').replaceAll('"', '\\"');
-}
-
-function escapeContentBlock(value) {
- return value
- .replaceAll('\\', '\\\\')
- .replaceAll('[', '\\[')
- .replaceAll(']', '\\]')
- .replaceAll('*', '\\*')
- .replaceAll('#', '\\#')
- .replaceAll('@', '\\@');
-}
-
-function inlineTypst(value) {
- let text = value.trim();
-
- text = text.replaceAll('
', ' ');
- text = text.replaceAll('
', ' ');
- text = text.replaceAll(' ', ' ');
- text = text.replace(/\*\*([^*]+)\*\*/g, '$1');
- text = text.replace(/`([^`]+)`/g, '$1');
- text = text.replaceAll('*', '\\*');
- text = text.replaceAll('@', '\\@');
- text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_match, label, href) => {
- if (href.startsWith('http://') || href.startsWith('https://')) {
- return `#link("${escapeTypstString(href)}")[${escapeContentBlock(label)}]`;
- }
-
- return label;
- });
-
- return text;
-}
-
-function parseTableRow(line) {
- const trimmed = line.trim();
- const withoutEdges = trimmed.replace(/^\|/, '').replace(/\|$/, '');
-
- return withoutEdges.split('|').map((cell) => inlineTypst(cell));
-}
-
-function isTableSeparator(line) {
- return /^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/.test(line);
-}
-
-function renderTable(lines, startIndex) {
- const rows = [];
- let index = startIndex;
-
- while (index < lines.length && /^\s*\|/.test(lines[index])) {
- if (!isTableSeparator(lines[index])) {
- rows.push(parseTableRow(lines[index]));
- }
-
- index += 1;
- }
-
- const columnCount = Math.max(...rows.map((row) => row.length));
- const normalizedRows = rows.map((row) => {
- if (row.length >= columnCount) {
- return row;
- }
-
- return [...row, ...Array.from({ length: columnCount - row.length }, () => '')];
- });
-
- const cells = normalizedRows.flatMap((row, rowIndex) => row.map((cell) => {
- const content = escapeContentBlock(cell);
- return rowIndex === 0 ? `[*${content}*]` : `[${content}]`;
- }));
-
- const columns = Array.from({ length: columnCount }, () => '1fr').join(', ');
-
- return {
- nextIndex: index,
- typst: [
- '#text(size: 7.6pt)[',
- ' #table(',
- ` columns: (${columns}),`,
- ' stroke: rgb("#d0d7de"),',
- ' inset: 4pt,',
- ' align: horizon + left,',
- ` ${cells.join(',\n ')}`,
- ' )',
- ']',
- '',
- ].join('\n'),
- };
-}
-
-function renderImage(line) {
- const match = line.match(/^!\[([^\]]*)\]\(([^)]+)\)$/);
-
- if (!match) {
- return null;
- }
-
- const [, alt, src] = match;
- const imagePath = src.startsWith('/')
- ? `..${src.replace(/^\//, '/public/')}`
- : src;
-
- return [
- '#figure(',
- ` image("${escapeTypstString(imagePath)}", width: 100%),`,
- ` caption: [${escapeContentBlock(alt)}],`,
- ')',
- '',
- ].join('\n');
-}
-
-function markdownToTypst(markdown) {
- const lines = markdown
- .replace(/\r\n/g, '\n')
- .replace(/^---[\s\S]*?---\n/, '')
- .split('\n');
-
- const output = [];
- let inFence = false;
-
- for (let index = 0; index < lines.length;) {
- const line = lines[index];
- const trimmed = line.trim();
-
- if (trimmed.startsWith('```')) {
- inFence = !inFence;
- output.push(line);
- index += 1;
- continue;
- }
-
- if (inFence) {
- output.push(line);
- index += 1;
- continue;
- }
-
- if (!trimmed) {
- output.push('');
- index += 1;
- continue;
- }
-
- if (/^\s*\|/.test(line) && index + 1 < lines.length && isTableSeparator(lines[index + 1])) {
- const table = renderTable(lines, index);
- output.push(table.typst);
- index = table.nextIndex;
- continue;
- }
-
- const image = renderImage(trimmed);
-
- if (image) {
- output.push(image);
- index += 1;
- continue;
- }
-
- const heading = line.match(/^(#{1,6})\s+(.+)$/);
-
- if (heading) {
- const level = heading[1].length;
- const title = inlineTypst(heading[2]);
-
- if (level === 1 && title === 'Техническое задание на разработку программного продукта') {
- index += 1;
- continue;
- }
-
- if (level === 1 && output.some((item) => item.trim())) {
- output.push('#pagebreak(weak: true)');
- }
-
- output.push(`${'='.repeat(level)} ${title}`);
- output.push('');
- index += 1;
- continue;
- }
-
- const bullet = line.match(/^(\s*)-\s+(.+)$/);
-
- if (bullet) {
- output.push(`${bullet[1]}- ${inlineTypst(bullet[2])}`);
- index += 1;
- continue;
- }
-
- const ordered = line.match(/^(\s*)\d+\.\s+(.+)$/);
-
- if (ordered) {
- output.push(`${ordered[1]}+ ${inlineTypst(ordered[2])}`);
- index += 1;
- continue;
- }
-
- output.push(inlineTypst(line));
- index += 1;
- }
-
- return output.join('\n');
-}
-
-function typstDocument(body) {
- return `#set document(title: "Техническое задание на разработку программного продукта")
-#set page(
- paper: "a4",
- margin: (left: 20mm, right: 18mm, top: 18mm, bottom: 18mm),
- numbering: "1",
- header: align(right)[#text(size: 8pt, fill: rgb("#667085"))[Личный кабинет Фрегат]],
- footer: align(center)[#text(size: 8pt, fill: rgb("#667085"))[#context counter(page).display("1")]],
-)
-#set text(font: "Times New Roman", size: 10.5pt, lang: "ru")
-#set par(justify: true, leading: 0.58em, first-line-indent: 0pt)
-#set list(indent: 13pt, body-indent: 5pt)
-#show link: underline
-#show raw: set text(font: "Times New Roman")
-#show heading.where(level: 1): set text(size: 16pt, weight: "bold")
-#show heading.where(level: 2): set text(size: 13pt, weight: "bold")
-#show heading.where(level: 3): set text(size: 11.5pt, weight: "bold")
-#show heading: it => block(above: 1.15em, below: 0.55em, it)
-
-#align(center)[
- #text(size: 18pt, weight: "bold")[Техническое задание]
-
- #v(5mm)
- #text(size: 14pt)[на разработку программного продукта]
-
- #v(3mm)
- #text(size: 14pt, weight: "bold")[«Личный кабинет Фрегат»]
-]
-
-#v(12mm)
-
-#align(center)[
- #table(
- columns: (40%, 60%),
- stroke: rgb("#d0d7de"),
- inset: 6pt,
- [Заказчик], [ООО «Фрегат Групп»],
- [Исполнитель], [ИП Бакиев Р.Ш.],
- [Основание], [Договор №28/04-26ПО от 28.04.2026],
- [Формат], [Техническое задание],
- )
-]
-
-#pagebreak()
-
-#outline(title: [Содержание], depth: 2, indent: auto)
-
-#pagebreak()
-
-${body}
-`;
-}
-
await mkdir(exportDir, { recursive: true });
-const markdown = await readMarkdownWithIncludes(sourceFile);
-const typst = typstDocument(markdownToTypst(markdown));
-
-await writeFile(typstFile, typst, 'utf8');
-
const compileResult = spawnSync('typst', [
'compile',
'--root',
'.',
- relative(docsDir, typstFile),
+ relative(docsDir, sourceFile),
relative(docsDir, pdfFile),
], {
cwd: docsDir,
@@ -320,5 +32,4 @@ if (compileResult.status !== 0) {
throw new Error('Typst PDF build failed');
}
-process.stdout.write(`Generated ${relative(docsDir, typstFile)}\n`);
process.stdout.write(`Generated ${relative(docsDir, pdfFile)}\n`);
diff --git a/docs/tz-fregat.typ b/docs/tz-fregat.typ
new file mode 100644
index 0000000..3267c2d
--- /dev/null
+++ b/docs/tz-fregat.typ
@@ -0,0 +1,2922 @@
+#set document(title: "Техническое задание на разработку программного продукта")
+#set page(
+ paper: "a4",
+ margin: (left: 20mm, right: 18mm, top: 18mm, bottom: 18mm),
+ numbering: "1",
+ header: align(right)[#text(size: 8pt, fill: rgb("#667085"))[Личный кабинет Фрегат]],
+ footer: align(center)[#text(size: 8pt, fill: rgb("#667085"))[#context counter(page).display("1")]],
+)
+#set text(font: "Times New Roman", size: 10.5pt, lang: "ru")
+#set par(justify: true, leading: 0.58em, first-line-indent: 0pt)
+#set list(indent: 13pt, body-indent: 5pt)
+#show link: underline
+#show raw: set text(font: "Times New Roman")
+#show heading.where(level: 1): set text(size: 16pt, weight: "bold")
+#show heading.where(level: 2): set text(size: 13pt, weight: "bold")
+#show heading.where(level: 3): set text(size: 11.5pt, weight: "bold")
+#show heading: it => block(above: 1.15em, below: 0.55em, it)
+
+#align(center)[
+ #text(size: 18pt, weight: "bold")[Техническое задание]
+
+ #v(5mm)
+ #text(size: 14pt)[на разработку программного продукта]
+
+ #v(3mm)
+ #text(size: 14pt, weight: "bold")[«Личный кабинет Фрегат»]
+]
+
+#v(12mm)
+
+#align(center)[
+ #table(
+ columns: (40%, 60%),
+ stroke: rgb("#d0d7de"),
+ inset: 6pt,
+ [Заказчик], [ООО «Фрегат Групп»],
+ [Исполнитель], [ИП Бакиев Р.Ш.],
+ [Основание], [Договор №28/04-26ПО от 28.04.2026],
+ )
+]
+
+#pagebreak()
+
+#outline(title: [Содержание], depth: 2, indent: auto)
+
+#pagebreak()
+
+
+= 1. Введение, основание, цель и состав проекта
+
+
+Настоящее техническое задание описывает разработку программного продукта Личный кабинет Фрегат для поддержки клиентских, менеджерских, заказных, бонусных и интеграционных сценариев в едином веб-интерфейсе.
+
+Документ используется для согласования состава работ, функциональных и технических требований, этапов разработки, требований к программной документации, порядка приемки и гарантийного сопровождения.
+
+== 1.1 Основание для разработки
+
+
+Разработка программного продукта выполняется на основании следующих документов и материалов:
+
+- договор на разработку программного продукта №28/04-26ПО от 28 апреля 2026 года
+- приложение №1 к договору: спецификация основных требований к программному обеспечению Личный кабинет Фрегат
+- согласованные требования заказчика к клиентскому, менеджерскому, бонусному и интеграционному контурам
+
+== 1.2 Цель разработки
+
+
+Программный продукт Личный кабинет Фрегат предназначен для организации единого цифрового канала взаимодействия между ООО Фрегат Групп и B2B-клиентами компании.
+
+Система должна обеспечивать:
+
+- подключение и регистрацию клиентов
+- выбор готовой продукции из каталога
+- подачу заявок на заказ готовой продукции
+- подачу заявок на расчет продукции с индивидуальными параметрами
+- согласование стоимости и условий поставки
+- сопровождение заказов по статусам
+- отправку клиентских уведомлений
+- ведение бонусной и реферальной программы
+
+== 1.3 Объект автоматизации
+
+
+Объектом автоматизации являются процессы клиентского обслуживания и внутренней обработки заявок, выполняемые менеджерами ООО Фрегат Групп при работе с готовой и индивидуальной продукцией.
+
+== 1.4 Состав системы
+
+
+В состав программного продукта входят:
+
+- клиентский веб-интерфейс
+- менеджерский веб-интерфейс
+- серверная бизнес-логика
+- база данных
+- модуль синхронизации с внешними системами
+- модуль уведомлений
+- модуль бонусной программы
+- модуль административных настроек
+
+== 1.5 Границы реализации
+
+
+В состав программного продукта входят следующие функциональные области:
+
+- регистрация и подключение клиента
+- профиль клиента и данные компании
+- каталог готовой продукции
+- карточка товара и выбор параметров
+- корзина и заявка на заказ
+- заявка на расчет индивидуальной продукции
+- обработка заявок менеджером
+- список заказов и карточка заказа
+- уведомления
+- бонусный кабинет
+- административные настройки
+
+Программный продукт не предназначен для выполнения следующих функций:
+
+- самостоятельного ценообразования клиентом
+- ведения бухгалтерского учета
+- выполнения функций публичного B2C-магазина
+- прямого редактирования клиентом внутренних бизнес-правил компании
+- замены учетной системы 1С как первичного источника учетных данных
+
+== 1.6 Основные принципы работы
+
+
+Система должна обеспечивать следующие базовые принципы:
+
+- доступ к функциям и данным определяется ролью пользователя
+- клиент работает только в пределах собственных данных и данных своего контрагента
+- стоимость товара и условия поставки публикуются только после обработки менеджером
+- история изменений по заявкам, заказам и бонусным операциям фиксируется в системе
+- сведения о товарах, остатках, заказах и статусах могут обновляться из внешней учетной системы
+
+#pagebreak(weak: true)
+= 2. Основания для разработки и нормативные материалы
+
+
+== 2.1 Основания для разработки
+
+
+Разработка программного продукта выполняется на основании следующих документов:
+
+- договор на разработку программного продукта №28/04-26ПО от 28 апреля 2026 года
+- приложение №1 к договору: спецификация основных требований к программному обеспечению Личный кабинет Фрегат
+- согласованные требования заказчика к клиентскому, менеджерскому, бонусному и интеграционному контурам
+
+== 2.2 Нормативные и методические материалы
+
+
+Настоящее техническое задание подготовлено как документ для согласования требований к разработке веб-программного продукта.
+
+Настоящий документ устанавливает требования к программному продукту применительно к современному веб-решению с разграничением ролей, интеграцией с учетной системой, журналированием событий и поддержкой клиентских и менеджерских сценариев.
+
+== 2.3 Исходные материалы для детализации требований
+
+
+При разработке технического задания использованы следующие исходные материалы:
+
+- договорная документация заказчика
+- согласованные бизнес-сценарии работы клиента и менеджера
+- перечень разделов личного кабинета
+- перечень основных товарных направлений и параметров каталога
+- требования к обмену данными с учетной системой 1С
+- требования к уведомлениям, бонусной программе и административным настройкам
+
+== 2.4 Назначение настоящего документа
+
+
+Настоящий документ предназначен для:
+
+- фиксации полного объема требований к программному продукту
+- определения состава реализуемых функций
+- определения состава данных и интеграционных точек
+- определения требований к пользовательским и административным интерфейсам
+- определения критериев приемки результата работ
+- определения состава артефактов, передаваемых заказчику
+
+#pagebreak(weak: true)
+= 3. Назначение и границы программного продукта
+
+
+== 3.1 Назначение системы
+
+
+Программный продукт Личный кабинет Фрегат предназначен для организации единого цифрового канала взаимодействия между ООО Фрегат Групп и клиентами компании.
+
+Система должна обеспечивать:
+
+- подключение новых клиентов и ведение клиентских учетных записей
+- предоставление клиенту каталога готовой продукции без публичного отображения цены
+- прием заявок на заказ готовой продукции
+- прием заявок на расчет продукции с индивидуальными параметрами
+- обработку заявок менеджером с публикацией стоимости и условий поставки
+- сопровождение заказов по статусам
+- информирование клиентов о значимых изменениях
+- ведение бонусной и реферальной программы
+
+== 3.2 Границы программного продукта
+
+
+В состав программного продукта входят следующие функциональные области:
+
+- регистрация и подключение клиента
+- профиль клиента и данные компании
+- каталог готовой продукции
+- карточка товара и выбор параметров
+- корзина и заявка на заказ
+- заявка на расчет индивидуальной продукции
+- обработка заявок менеджером
+- список заказов и карточка заказа
+- уведомления
+- бонусный кабинет
+- административные настройки
+
+== 3.3 Функции, не входящие в состав программного продукта
+
+
+Программный продукт не предназначен для выполнения следующих функций:
+
+- самостоятельного ценообразования клиентом
+- ведения бухгалтерского учета
+- выполнения функций публичного B2C-магазина
+- прямого редактирования клиентом внутренних бизнес-правил компании
+- замены учетной системы 1С как первичного источника учетных данных
+
+== 3.4 Пользовательские контуры
+
+
+В системе должны быть предусмотрены следующие пользовательские контуры:
+
+- клиентский контур
+- менеджерский контур
+- административный контур суперменеджера
+
+Клиентский контур предназначен для работы клиента с каталогом, заявками, заказами, уведомлениями и бонусным кабинетом.
+
+Менеджерский контур предназначен для обработки клиентских заявок, публикации коммерческих условий, сопровождения заказов, работы с клиентскими карточками и бонусными операциями.
+
+Административный контур предназначен для управления настройками каталога, уведомлений, интеграционных параметров и отдельных сервисных настроек системы.
+
+== 3.5 Основные бизнес-сценарии
+
+
+=== 3.5.1 Подключение клиента
+
+
++ Потенциальный клиент получает приглашение на регистрацию либо подает заявку на подключение самостоятельно.
++ Менеджер проверяет сведения о клиенте и принимает решение о подтверждении либо отклонении заявки.
++ При положительном решении клиенту предоставляется доступ к завершению регистрации.
++ После завершения регистрации клиент получает доступ к личному кабинету.
+
+=== 3.5.2 Заказ готовой продукции
+
+
++ Клиент открывает каталог готовой продукции.
++ Клиент выбирает товарное направление.
++ Клиент выбирает параметры товара.
++ Клиент просматривает доступные варианты и остатки.
++ Клиент добавляет выбранные позиции в корзину.
++ Клиент отправляет заявку на заказ.
++ Менеджер указывает стоимость, условия поставки и комментарий.
++ Система публикует обновленные условия клиенту.
+
+=== 3.5.3 Заявка на расчет индивидуальной продукции
+
+
++ Клиент переходит в режим расчета индивидуальной продукции.
++ Клиент указывает параметры требуемого изделия.
++ Клиент направляет заявку менеджеру.
++ Менеджер подготавливает коммерческие условия и публикует их клиенту.
+
+=== 3.5.4 Сопровождение заказа
+
+
++ Заказ получает уникальный идентификатор и статус.
++ Данные по заказу обновляются в системе по мере обработки.
++ Клиент отслеживает состав, статус, сроки и иные существенные сведения.
++ При изменении статуса либо условий система направляет уведомления.
+
+=== 3.5.5 Бонусная и реферальная программа
+
+
++ Для клиента фиксируются правила участия в бонусной программе и, при наличии, реферальные связи.
++ Система ведет учет начислений, списаний и остатка бонусов.
++ Клиент получает доступ к истории бонусных операций.
++ Менеджер обрабатывает заявки, связанные с использованием либо выводом бонусов, в пределах установленных правил.
+
+#pagebreak(weak: true)
+= 4. Функциональные требования
+
+
+== 4.1 Требования к регистрации и подключению клиентов
+
+
+Система должна поддерживать два базовых сценария подключения клиента:
+
+- регистрация по персональному приглашению
+- самостоятельная заявка на подключение
+
+Функциональные требования:
+
++ Менеджер должен иметь возможность направить клиенту приглашение на регистрацию по электронной почте.
++ Клиент должен иметь возможность завершить регистрацию по персональной ссылке.
++ Клиент должен иметь возможность подать заявку на подключение через публичную форму.
++ Самостоятельная заявка должна поступать в менеджерский контур на рассмотрение.
++ Менеджер должен иметь возможность подтвердить либо отклонить заявку на подключение.
++ При подтверждении заявки система должна предоставить клиенту возможность завершить регистрацию.
++ После завершения регистрации клиент должен получить доступ к личному кабинету.
++ Система должна поддерживать подключение доступных каналов уведомлений для клиентской учетной записи.
+
+== 4.2 Требования к каталогу готовой продукции
+
+
+Система должна предоставлять клиенту каталог готовой продукции без отображения цены до обработки менеджером.
+
+Функциональные требования:
+
++ Система должна отображать список товарных направлений.
++ Для каждого товарного направления система должна предоставлять отдельную карточку товара.
++ В карточке товара система должна отображать параметры выбора, применимые к данному типу продукции.
++ В карточке товара система должна отображать доступные стандартные варианты.
++ Для каждой доступной позиции система должна отображать складские остатки.
++ Система должна позволять клиенту выбрать параметры и добавить позицию в корзину.
++ Система должна исключать отображение стоимости до момента публикации условий менеджером.
++ Для параметров товара система должна отображать пояснения, помогающие клиенту понять назначение параметра и ограничения выбора.
+
+== 4.3 Требования к параметрам каталога и кастомизации
+
+
+Система должна поддерживать настройку параметров по каждому товарному направлению.
+
+Функциональные требования:
+
++ Для каждого типа продукции должен задаваться перечень стандартных параметров выбора.
++ Для параметров длины должна поддерживаться настройка доступных стандартных значений.
++ Для параметров длины должна поддерживаться возможность индивидуального значения при наличии соответствующего разрешения.
++ Для параметров втулки должна поддерживаться возможность заказа втулки с логотипом при наличии соответствующего разрешения.
++ Для параметров надписи должна поддерживаться возможность заказа индивидуального нанесения при наличии соответствующего разрешения.
++ Наборы стандартных параметров должны редактироваться в административном контуре.
++ Изменение набора стандартных параметров не должно приводить к потере уже сохраненных заказных данных.
+
+== 4.4 Требования к корзине и заявке на заказ
+
+
+Система должна позволять клиенту собрать корзину и направить заявку на заказ.
+
+Функциональные требования:
+
++ Клиент должен видеть перечень выбранных позиций.
++ Для каждой позиции клиент должен иметь возможность изменить количество.
++ Клиент должен иметь возможность удалить позицию из корзины.
++ Клиент должен иметь возможность направить заявку менеджеру.
++ После отправки заявки система должна зафиксировать состав, параметры и количество позиций.
++ Для заявки должны сохраняться дата создания, инициатор и закрепленный менеджер.
++ До обработки менеджером стоимость в заявке не должна отображаться клиенту.
+
+== 4.5 Требования к обработке заявки менеджером
+
+
+Менеджер должен иметь возможность обработать клиентскую заявку вручную.
+
+Функциональные требования:
+
++ Менеджер должен видеть состав заявки и параметры заказанных позиций.
++ Менеджер должен видеть карточку клиента и сведения о контрагенте.
++ Менеджер должен иметь возможность указать стоимость.
++ Менеджер должен иметь возможность указать условия поставки и доставки.
++ Менеджер должен иметь возможность оставить комментарий к заявке.
++ Менеджер должен иметь возможность опубликовать согласованные условия клиенту.
++ До перевода заявки в работу менеджер должен иметь возможность скорректировать опубликованные условия.
++ Менеджер должен иметь возможность перевести заявку в работу.
++ Менеджер должен иметь возможность отменить заявку с фиксацией основания отмены.
+
+== 4.6 Требования к заявке на расчет индивидуальной продукции
+
+
+Система должна поддерживать отдельный сценарий расчета продукции с индивидуальными параметрами.
+
+Функциональные требования:
+
++ Клиент должен иметь возможность перейти из каталога в сценарий расчета индивидуальной продукции.
++ Клиент должен иметь возможность указать параметры изделия.
++ Клиент должен иметь возможность приложить комментарий к заявке.
++ Клиент должен иметь возможность направить заявку менеджеру.
++ Менеджер должен иметь возможность обработать такую заявку по правилам, аналогичным заявке на заказ.
++ Стоимость и условия поставки должны публиковаться клиенту только после ручной обработки менеджером.
+
+Минимальный состав параметров расчетной заявки должен поддерживать:
+
+- тип продукции
+- ширину
+- длину
+- толщину
+- цвет
+- надпись или маркировку
+- иные параметры в зависимости от вида продукции
+- текстовый комментарий клиента
+
+== 4.7 Требования к статусам заявок
+
+
+Система должна обеспечивать сквозное сопровождение заявок по статусам.
+
+Для заявок на заказ и заявок на расчет должны поддерживаться следующие базовые статусы:
+
+- создана
+- направлена менеджеру
+- обработана менеджером
+- условия опубликованы
+- в работе
+- отменена
+
+Для каждого изменения статуса система должна сохранять:
+
+- предыдущее состояние
+- новое состояние
+- дату и время изменения
+- пользователя или источник, выполнивший изменение
+- комментарий, если он предусмотрен сценарием
+
+== 4.8 Требования к заказам и их сопровождению
+
+
+Система должна предоставлять клиенту и менеджеру доступ к списку заказов, карточке каждого заказа и актуальным учетным сведениям, полученным из 1С.
+
+Функциональные требования:
+
++ Система должна отображать перечень заказов клиента.
++ Система должна поддерживать фильтрацию заказов по периоду и статусу.
++ Для каждого заказа система должна предоставлять отдельную карточку.
++ В карточке заказа должны отображаться состав, статус, стоимость, условия поставки и история изменений.
++ В карточке заказа должна отображаться дата актуальности данных.
++ При наличии обновлений из внешней системы сведения по заказу должны синхронизироваться и отображаться пользователю.
++ Система должна отображать текущую задолженность клиента, если такие сведения получены из 1С.
++ Для задолженности должна отображаться дата актуальности данных.
+
+== 4.9 Требования к уведомлениям
+
+
+Система должна поддерживать уведомления по нескольким каналам связи.
+
+Поддерживаемые каналы:
+
+- электронная почта
+- Telegram
+- Max
+
+Система должна поддерживать уведомления по следующим событиям:
+
+- приглашение к регистрации
+- подтверждение либо отклонение заявки на подключение
+- публикация условий по заявке
+- изменение статуса заказа
+- изменение бонусного баланса
+- обработка заявки на использование либо вывод бонусов
+
+== 4.10 Требования к бонусной и реферальной программе
+
+
+Система должна включать бонусный контур как самостоятельную функциональную область с отдельным пользовательским интерфейсом.
+
+Функциональные требования:
+
++ Система должна хранить правила участия клиента в бонусной программе.
++ Система должна поддерживать фиксацию реферальных связей.
++ Система должна хранить начисления, списания и текущий остаток бонусов.
++ Клиент должен видеть текущий бонусный баланс.
++ Клиент должен видеть историю бонусных операций.
++ Клиент должен иметь возможность использовать бонусы в пределах установленных правил.
++ Клиент должен иметь возможность подать заявку на вывод либо иную операцию, если это предусмотрено правилами программы.
++ Менеджер должен иметь возможность обрабатывать операции бонусного контура.
++ Система должна уведомлять клиента об изменениях бонусного состояния.
+
+== 4.11 Требования к административным настройкам
+
+
+Система должна содержать административные разделы для управления следующими объектами:
+
+- параметрами каталога
+- пользовательскими описаниями параметров
+- шаблонами уведомлений
+- параметрами синхронизации
+- отдельными настройками бонусного контура
+
+#pagebreak(weak: true)
+= 5. Требования к ролям и правам доступа
+
+
+== 5.1 Состав ролей
+
+
+В системе должны быть предусмотрены следующие роли пользователей:
+
+- клиент
+- менеджер
+- суперменеджер
+
+== 5.2 Роль клиента
+
+
+Пользователь с ролью Клиент представляет организацию-контрагента и работает только с данными своей компании.
+
+Клиенту должны быть доступны следующие действия:
+
+- завершение регистрации по персональному приглашению
+- подача заявки на подключение
+- просмотр и изменение разрешенных профильных данных
+- подключение доступных каналов уведомлений
+- просмотр каталога готовой продукции
+- выбор параметров товара
+- добавление позиций в корзину
+- отправка заявки на заказ
+- отправка заявки на расчет
+- просмотр списка заявок и заказов
+- просмотр карточки заявки и карточки заказа
+- просмотр истории уведомлений
+- просмотр бонусного баланса и истории бонусных операций
+- подача заявки на использование либо вывод бонусов при наличии соответствующих правил
+
+== 5.3 Роль менеджера
+
+
+Пользователь с ролью Менеджер представляет сотрудника компании, закрепленного за клиентами.
+
+Менеджеру должны быть доступны следующие действия:
+
+- рассмотрение заявок на подключение клиентов
+- подтверждение либо отклонение заявок на подключение
+- привязка клиента к контрагенту и назначение ответственного сопровождения
+- просмотр и обработка заявок на заказ
+- просмотр и обработка заявок на расчет
+- указание стоимости, условий поставки и сопроводительного комментария
+- публикация условий клиенту
+- перевод заявки в работу
+- отмена заявки при наличии оснований
+- просмотр карточек клиентов, заявок и заказов
+- выполнение операций в бонусном контуре в пределах полномочий
+
+== 5.4 Роль суперменеджера
+
+
+Пользователь с ролью Суперменеджер обладает всеми правами менеджера и дополнительными административными полномочиями.
+
+Суперменеджеру должны быть доступны следующие действия:
+
+- доступ ко всем клиентам, заявкам и заказам
+- управление параметрами каталога
+- управление описаниями и наборами параметров товаров
+- управление настройками уведомлений
+- управление параметрами интеграции и синхронизации
+- расширенное управление бонусным и реферальным контуром
+
+== 5.5 Матрица доступа
+
+
+#text(size: 7.6pt)[
+ #table(
+ columns: (1fr, 1fr, 1fr, 1fr),
+ stroke: rgb("#d0d7de"),
+ inset: 4pt,
+ align: horizon + left,
+ [*Действие*],
+ [*Клиент*],
+ [*Менеджер*],
+ [*Суперменеджер*],
+ [Завершение регистрации],
+ [Да],
+ [Нет],
+ [Нет],
+ [Подача заявки на подключение],
+ [Да],
+ [Нет],
+ [Нет],
+ [Просмотр каталога],
+ [Да],
+ [Да],
+ [Да],
+ [Выбор параметров и добавление в корзину],
+ [Да],
+ [Нет],
+ [Нет],
+ [Отправка заявки на заказ],
+ [Да],
+ [Нет],
+ [Нет],
+ [Отправка заявки на расчет],
+ [Да],
+ [Нет],
+ [Нет],
+ [Назначение стоимости и условий поставки],
+ [Нет],
+ [Да],
+ [Да],
+ [Публикация условий клиенту],
+ [Нет],
+ [Да],
+ [Да],
+ [Перевод заявки в работу],
+ [Нет],
+ [Да],
+ [Да],
+ [Отмена заявки],
+ [Нет],
+ [Да],
+ [Да],
+ [Управление параметрами каталога],
+ [Нет],
+ [Нет],
+ [Да],
+ [Управление уведомлениями],
+ [Нет],
+ [Нет],
+ [Да],
+ [Управление параметрами синхронизации],
+ [Нет],
+ [Нет],
+ [Да],
+ [Управление бонусными правилами],
+ [Нет],
+ [Да],
+ [Да]
+ )
+]
+
+
+== 5.6 Ограничения доступа и требования к безопасности
+
+
+Система должна обеспечивать:
+
+- раздельные интерфейсы для клиентского и менеджерского контуров
+- доступ клиента только к данным собственного контрагента
+- ограничение административных функций в соответствии с ролью
+- журналирование значимых пользовательских действий
+- хранение истории изменения статусов, условий заявок и бонусных операций
+
+#pagebreak(weak: true)
+= 6. Требования к данным и сущностям
+
+
+== 6.1 Общие требования к данным
+
+
+Основное хранилище данных программного продукта реализуется на PostgreSQL. Прикладной доступ к данным осуществляется через Prisma ORM.
+
+Система должна обеспечивать хранение:
+
+- пользователей и ролей
+- компаний и профилей контрагентов
+- адресов доставки
+- каталога и складских остатков
+- корзины и ее позиций
+- заказов и расчетных заявок
+- событий изменения статусов
+- подключений мессенджеров
+- бонусных и реферальных сущностей
+
+В прикладной реализации должны использоваться фактические сущности базы данных, определенные в schema.prisma. Наименование сущностей в документации и в базе данных должно сопоставляться однозначно.
+
+== 6.2 Справочник сущностей базы данных
+
+
+#text(size: 7.6pt)[
+ #table(
+ columns: (1fr, 1fr, 1fr),
+ stroke: rgb("#d0d7de"),
+ inset: 4pt,
+ align: horizon + left,
+ [*Модель в базе данных*],
+ [*Русское наименование*],
+ [*Назначение*],
+ [Company],
+ [Компания],
+ [Клиентская организация],
+ [User],
+ [Пользователь],
+ [Учетная запись клиента, менеджера или суперменеджера],
+ [DeliveryAddress],
+ [Адрес доставки],
+ [Справочник адресов доставки клиента],
+ [CounterpartyProfile],
+ [Профиль контрагента],
+ [Юридические и банковские реквизиты клиента],
+ [RegistrationRequest],
+ [Заявка на подключение],
+ [Самостоятельная заявка клиента на подключение],
+ [Invitation],
+ [Приглашение],
+ [Менеджерское приглашение на регистрацию],
+ [MessengerConnection],
+ [Подключение мессенджера],
+ [Связка пользователя с Telegram или MAX],
+ [Product],
+ [Товар],
+ [Карточка товарной позиции каталога],
+ [CatalogProductTypeSetting],
+ [Настройки типа товара],
+ [Правила параметров и кастомизации по товарному направлению],
+ [Cart],
+ [Корзина],
+ [Корзина клиента],
+ [CartItem],
+ [Позиция корзины],
+ [Конкретный выбранный товар в корзине],
+ [Warehouse],
+ [Склад],
+ [Справочник складов],
+ [ProductStock],
+ [Складской остаток],
+ [Остаток товара на складе],
+ [Order],
+ [Заказ / заявка],
+ [Единая заказная сущность для готовой продукции и расчета],
+ [OrderItem],
+ [Позиция заказа],
+ [Состав заказа],
+ [OrderStatusEvent],
+ [Событие статуса заказа],
+ [История изменения статусов],
+ [ReferralLink],
+ [Реферальная связь],
+ [Связь между рекомендателем и приглашенным клиентом],
+ [BonusTransaction],
+ [Бонусная транзакция],
+ [Начисление или списание бонусов],
+ [RewardWithdrawalRequest],
+ [Заявка на вывод бонусов],
+ [Заявка клиента на использование или вывод бонусов]
+ )
+]
+
+
+== 6.3 Служебные перечисления и статусы
+
+
+В модели данных используются следующие перечисления:
+
+- UserRole: CLIENT, MANAGER, SUPER_MANAGER
+- RegistrationStatus: PENDING, APPROVED, REJECTED
+- MessengerType: TELEGRAM, MAX
+- OrderKind: READY, CALCULATION
+- OrderStatus: NEW, MANAGER_PROCESSING, WAITING_DOUBLE_CONFIRM, CLIENT_REJECTED, MANAGER_REJECTED, MANAGER_BLOCKED, CONFIRMED, IN_PROGRESS, COMPLETED
+- WithdrawalStatus: PENDING, APPROVED, REJECTED
+
+== 6.4 Пользователи и компании
+
+
+=== 6.4.1 Company
+
+
+Русское наименование: Компания
+
+Назначение:
+
+- хранение клиентской организации
+- объединение пользователей одной компании
+
+Основные поля:
+
+- id
+- name
+- inn
+- createdAt
+- updatedAt
+
+Связи:
+
+- одна компания связана со многими пользователями
+
+=== 6.4.2 User
+
+
+Русское наименование: Пользователь
+
+Назначение:
+
+- хранение клиентской, менеджерской или административной учетной записи
+- связывание пользователя с заказами, корзиной, бонусами и адресами
+
+Основные поля:
+
+- id
+- email
+- fullName
+- role
+- companyId
+- defaultDeliveryAddressId
+- createdAt
+- updatedAt
+
+Связи:
+
+- пользователь может быть связан с компанией
+- пользователь может иметь профиль контрагента
+- пользователь может иметь адреса доставки
+- пользователь может иметь корзину
+- пользователь может выступать клиентом или менеджером в заказах
+- пользователь может иметь бонусные операции и заявки на вывод
+
+=== 6.4.3 DeliveryAddress
+
+
+Русское наименование: Адрес доставки
+
+Назначение:
+
+- хранение адресов доставки клиента
+- выбор адреса по умолчанию для корзины и заказов
+
+Основные поля:
+
+- id
+- userId
+- label
+- address
+- unrestrictedValue
+- fiasId
+- createdAt
+- updatedAt
+
+=== 6.4.4 CounterpartyProfile
+
+
+Русское наименование: Профиль контрагента
+
+Назначение:
+
+- хранение полных реквизитов клиента для договоров, счетов и поставки
+
+Основные поля:
+
+- id
+- userId
+- companyName
+- companyFullName
+- inn
+- kpp
+- ogrn
+- legalAddress
+- bankName
+- bik
+- correspondentAccount
+- checkingAccount
+- signerFullName
+- signerPosition
+- signerBasis
+- createdAt
+- updatedAt
+
+=== 6.4.5 RegistrationRequest
+
+
+Русское наименование: Заявка на подключение
+
+Назначение:
+
+- хранение самостоятельной заявки клиента на подключение
+
+Основные поля:
+
+- id
+- companyName
+- inn
+- contactName
+- email
+- status
+- rejectionReason
+- requesterId
+- reviewedById
+- createdAt
+- updatedAt
+
+=== 6.4.6 Invitation
+
+
+Русское наименование: Приглашение
+
+Назначение:
+
+- хранение менеджерского приглашения клиента на регистрацию
+
+Основные поля:
+
+- id
+- token
+- email
+- companyName
+- managerId
+- acceptedById
+- expiresAt
+- acceptedAt
+- createdAt
+
+=== 6.4.7 MessengerConnection
+
+
+Русское наименование: Подключение мессенджера
+
+Назначение:
+
+- хранение подключенного Telegram или MAX-канала пользователя
+
+Основные поля:
+
+- id
+- userId
+- type
+- channelId
+- displayName
+- username
+- avatarFileId
+- avatarFileUniqueId
+- isActive
+- createdAt
+
+== 6.5 Каталог и складской контур
+
+
+=== 6.5.1 Product
+
+
+Русское наименование: Товар
+
+Назначение:
+
+- хранение карточки товарной позиции каталога
+- хранение параметров товара и признаков кастомизации
+
+Основные поля:
+
+- id
+- sku
+- name
+- productType
+- widthMm
+- lengthM
+- thicknessMicron
+- sleeveBrand
+- quantityPerBox
+- tags
+- description
+- isCustomizable
+- isActive
+- createdAt
+- updatedAt
+
+=== 6.5.2 CatalogProductTypeSetting
+
+
+Русское наименование: Настройки типа товара
+
+Назначение:
+
+- хранение правил параметров по товарному направлению
+- хранение разрешений на кастомизацию
+
+Основные поля:
+
+- id
+- productType
+- showQuantityPerBox
+- allowCustomLength
+- customLengthMinM
+- customLengthMaxM
+- customLengthStepM
+- allowCustomSleeveBrand
+- allowCustomLabel
+- widthOptionsMm
+- lengthOptionsM
+- thicknessOptionsMicron
+- sleeveOptions
+- colorOptions
+- labelOptions
+- createdAt
+- updatedAt
+
+=== 6.5.3 Warehouse
+
+
+Русское наименование: Склад
+
+Назначение:
+
+- хранение справочника складов
+
+Основные поля:
+
+- id
+- code
+- name
+- createdAt
+- updatedAt
+
+=== 6.5.4 ProductStock
+
+
+Русское наименование: Складской остаток
+
+Назначение:
+
+- хранение остатка товара на конкретном складе
+
+Основные поля:
+
+- id
+- productId
+- warehouseId
+- availableQty
+- updatedAt
+
+== 6.6 Корзина, заявки и заказы
+
+
+=== 6.6.1 Cart
+
+
+Русское наименование: Корзина
+
+Назначение:
+
+- хранение текущего набора выбранных клиентом позиций
+
+Основные поля:
+
+- id
+- userId
+- deliveryAddressId
+- createdAt
+- updatedAt
+
+=== 6.6.2 CartItem
+
+
+Русское наименование: Позиция корзины
+
+Назначение:
+
+- хранение одной выбранной клиентом позиции с параметрами и количеством
+
+Основные поля:
+
+- id
+- cartId
+- productId
+- productName
+- sku
+- isCustomizable
+- quantity
+- parameters
+- createdAt
+- updatedAt
+
+=== 6.6.3 Order
+
+
+Русское наименование: Заказ / заявка
+
+Назначение:
+
+- хранение готовой заказной заявки и расчетной заявки в единой сущности
+- хранение согласованных менеджером условий и статуса работы
+
+Основные поля:
+
+- id
+- code
+- kind
+- customerId
+- deliveryAddressId
+- deliveryAddress
+- managerId
+- status
+- clientApproved
+- managerApproved
+- blockReason
+- deliveryTerms
+- deliveryFee
+- totalPrice
+- calculationPayload
+- createdAt
+- updatedAt
+
+Комментарий к модели:
+
+- kind = READY означает сценарий заказа готовой продукции
+- kind = CALCULATION означает сценарий расчета индивидуальной продукции
+- поле calculationPayload хранит параметры расчетной заявки
+
+=== 6.6.4 OrderItem
+
+
+Русское наименование: Позиция заказа
+
+Назначение:
+
+- хранение состава заказа
+
+Основные поля:
+
+- id
+- orderId
+- productId
+- productName
+- quantity
+- unitPrice
+- createdAt
+
+=== 6.6.5 OrderStatusEvent
+
+
+Русское наименование: Событие статуса заказа
+
+Назначение:
+
+- хранение истории изменения статусов заказа или заявки
+
+Основные поля:
+
+- id
+- orderId
+- status
+- actorUserId
+- note
+- createdAt
+
+== 6.7 Бонусный и реферальный контур
+
+
+=== 6.7.1 ReferralLink
+
+
+Русское наименование: Реферальная связь
+
+Назначение:
+
+- фиксация связи между рекомендателем и приглашенным клиентом
+
+Основные поля:
+
+- id
+- referrerId
+- refereeId
+- createdById
+- bonusPercent
+- createdAt
+
+=== 6.7.2 BonusTransaction
+
+
+Русское наименование: Бонусная транзакция
+
+Назначение:
+
+- хранение начисления или списания бонусов
+
+Основные поля:
+
+- id
+- userId
+- amount
+- reason
+- orderId
+- referralLinkId
+- createdAt
+
+=== 6.7.3 RewardWithdrawalRequest
+
+
+Русское наименование: Заявка на вывод бонусов
+
+Назначение:
+
+- хранение заявки клиента на использование или вывод бонусов
+
+Основные поля:
+
+- id
+- requesterId
+- amount
+- status
+- reviewedById
+- reviewComment
+- createdAt
+- updatedAt
+
+== 6.8 Основные связи между сущностями
+
+
+Укрупненная структура связей определяется следующими правилами:
+
+- Company объединяет пользователей одной клиентской организации
+- User связан с CounterpartyProfile, DeliveryAddress, MessengerConnection, Cart, Order, BonusTransaction и RewardWithdrawalRequest
+- Cart содержит набор CartItem, привязанных к конкретным Product
+- Order содержит набор OrderItem и историю OrderStatusEvent
+- Product связан с остатками ProductStock, распределенными по сущностям Warehouse
+- настройки параметров по товарному направлению хранятся в CatalogProductTypeSetting
+- реферальные связи реализуются через ReferralLink, связывающий одного пользователя с другим пользователем
+
+#pagebreak(weak: true)
+= 7. Требования к интерфейсу и прототипам
+
+
+== 7.1 Карта экранов
+
+
+Ниже приведен базовый состав экранов, подлежащих реализации и сопровождению в рамках программного продукта.
+
+#text(size: 7.6pt)[
+ #table(
+ columns: (1fr, 1fr, 1fr, 1fr),
+ stroke: rgb("#d0d7de"),
+ inset: 4pt,
+ align: horizon + left,
+ [*Раздел*],
+ [*Маршрут*],
+ [*Роль*],
+ [*Назначение*],
+ [Главная страница],
+ [/],
+ [клиент],
+ [стартовая точка, быстрые действия, актуальные события],
+ [Каталог],
+ [/products],
+ [клиент],
+ [выбор товарного направления],
+ [Карточка товара],
+ [/products/\[slug\]],
+ [клиент],
+ [выбор параметров, просмотр вариантов, добавление в корзину],
+ [Корзина],
+ [/cart],
+ [клиент],
+ [формирование и отправка заявки],
+ [Список заказов клиента],
+ [/client-orders],
+ [клиент],
+ [просмотр истории заявок и заказов],
+ [Карточка заказа клиента],
+ [/client-orders/\[id\]],
+ [клиент],
+ [просмотр статуса, состава, условий и истории],
+ [Профиль],
+ [/profile],
+ [клиент],
+ [базовые данные учетной записи],
+ [Контрагент],
+ [/profile/counterparty],
+ [клиент],
+ [реквизиты и юридические данные],
+ [Адреса доставки],
+ [/profile/addresses],
+ [клиент],
+ [адресный справочник],
+ [Уведомления],
+ [/notifications],
+ [клиент],
+ [история уведомлений],
+ [Бонусный кабинет],
+ [/bonus-program],
+ [клиент],
+ [баланс, история и бонусные действия],
+ [Список клиентов],
+ [/clients],
+ [менеджер],
+ [клиентская база],
+ [Карточка клиента],
+ [/clients/\[id\]],
+ [менеджер],
+ [данные компании, заказы, бонусы],
+ [Приглашение клиента],
+ [/clients/invite],
+ [менеджер],
+ [выдача приглашения на регистрацию],
+ [Список заказов],
+ [/orders],
+ [менеджер],
+ [обработка заказного контура],
+ [Карточка заказа],
+ [/orders/\[id\]],
+ [менеджер],
+ [обработка условий, статуса и доставки],
+ [Настройки каталога],
+ [/catalog-settings],
+ [суперменеджер],
+ [параметры товарных направлений],
+ [Настройки синхронизации],
+ [/settings-sync],
+ [суперменеджер],
+ [мониторинг и управление обменом],
+ [Бонусная система],
+ [/bonus-system/\\\*],
+ [менеджер/суперменеджер],
+ [рефералы, транзакции, выводы]
+ )
+]
+
+
+== 7.2 Маршруты и экранные формы
+
+
+Ниже приведен перечень экранных форм, предусмотренных в составе frontend-контура программного продукта.
+
+=== 7.2.1 Публичные и клиентские страницы
+
+
+#text(size: 7.6pt)[
+ #table(
+ columns: (1fr, 1fr, 1fr),
+ stroke: rgb("#d0d7de"),
+ inset: 4pt,
+ align: horizon + left,
+ [*Маршрут*],
+ [*Экран*],
+ [*Назначение*],
+ [/],
+ [Главная страница],
+ [Стартовая страница личного кабинета],
+ [/login],
+ [Вход],
+ [Вход и первичный сценарий доступа],
+ [/products],
+ [Каталог продукции],
+ [Список товарных направлений],
+ [/products/\[slug\]],
+ [Карточка товара],
+ [Выбор параметров, просмотр вариантов, добавление в корзину],
+ [/cart],
+ [Корзина],
+ [Состав выбранных позиций и отправка заявки],
+ [/client-orders],
+ [Список заказов клиента],
+ [История заявок и заказов клиента],
+ [/client-orders/\[id\]],
+ [Карточка заказа клиента],
+ [Детали конкретного заказа клиента],
+ [/notifications],
+ [Уведомления],
+ [Список системных уведомлений],
+ [/bonus-program],
+ [Бонусный кабинет],
+ [Бонусный баланс, подарочные карты и бонусные действия]
+ )
+]
+
+
+=== 7.2.2 Профиль клиента
+
+
+#text(size: 7.6pt)[
+ #table(
+ columns: (1fr, 1fr, 1fr),
+ stroke: rgb("#d0d7de"),
+ inset: 4pt,
+ align: horizon + left,
+ [*Маршрут*],
+ [*Экран*],
+ [*Назначение*],
+ [/profile],
+ [Профиль],
+ [Основные данные пользователя],
+ [/profile/counterparty],
+ [Реквизиты контрагента],
+ [Юридические и банковские данные],
+ [/profile/addresses],
+ [Адреса доставки],
+ [Список адресов доставки],
+ [/profile/addresses/new],
+ [Новый адрес доставки],
+ [Создание адреса доставки],
+ [/profile/notifications],
+ [Настройки уведомлений],
+ [Подключение и настройка каналов уведомлений],
+ [/profile/notifications/success],
+ [Успешное подключение уведомлений],
+ [Финальный экран сценария подключения канала]
+ )
+]
+
+
+=== 7.2.3 Менеджерские и административные страницы
+
+
+#text(size: 7.6pt)[
+ #table(
+ columns: (1fr, 1fr, 1fr),
+ stroke: rgb("#d0d7de"),
+ inset: 4pt,
+ align: horizon + left,
+ [*Маршрут*],
+ [*Экран*],
+ [*Назначение*],
+ [/clients],
+ [Клиенты],
+ [Список клиентских компаний и пользователей],
+ [/clients/\[id\]],
+ [Карточка клиента],
+ [Детали клиента, его заказы и бонусные данные],
+ [/clients/invite],
+ [Пригласить клиента],
+ [Создание приглашения на регистрацию],
+ [/orders],
+ [Список заказов],
+ [Очередь заказов и заявок для менеджера],
+ [/orders/\[id\]],
+ [Карточка заказа],
+ [Обработка стоимости, условий поставки и статуса],
+ [/catalog-settings],
+ [Настройки каталога],
+ [Параметры товарных направлений и кастомизации],
+ [/settings-sync],
+ [1С / синхронизация],
+ [Управление и мониторинг синхронизации],
+ [/messages],
+ [Сообщения],
+ [Шаблоны и тексты менеджерских сообщений]
+ )
+]
+
+
+=== 7.2.4 Бонусный менеджерский контур
+
+
+#text(size: 7.6pt)[
+ #table(
+ columns: (1fr, 1fr, 1fr),
+ stroke: rgb("#d0d7de"),
+ inset: 4pt,
+ align: horizon + left,
+ [*Маршрут*],
+ [*Экран*],
+ [*Назначение*],
+ [/bonus-system],
+ [Бонусная система],
+ [Список клиентов и бонусных сущностей],
+ [/bonus-system/\[userId\]],
+ [Карточка бонусного счета клиента],
+ [История и состояние бонусного счета],
+ [/bonus-system/referrals/new],
+ [Создать бонусный счет],
+ [Создание реферальной связи],
+ [/bonus-system/transactions/new],
+ [Добавить бонусную транзакцию],
+ [Ручное начисление или списание],
+ [/bonus-system/withdrawals/\[id\]],
+ [Проверка заявки на вывод],
+ [Рассмотрение заявки клиента на вывод бонусов]
+ )
+]
+
+
+== 7.3 Общие требования к экранным формам
+
+
+Экранные формы должны обеспечивать:
+
+- однозначное понимание текущего объекта работы
+- явное отображение статуса объекта
+- соответствие доступных действий роли пользователя
+- единый визуальный подход для клиентского и менеджерского контуров
+- понятное отображение параметров товара, условий заказа и бонусных операций
+
+Для экранов, связанных с товарами, заявками и заказами, должны выполняться дополнительные требования:
+
+- цена не отображается клиенту до публикации условий менеджером
+- остатки и доступные варианты отображаются в наглядном виде
+- пользователь понимает ограничения выбора и возможность кастомизации
+
+Ниже приведены низкодетализированные wireframe-прототипы. Они используются как визуальная фиксация состава страниц, ключевых блоков и пользовательских действий.
+
+== 7.4 Клиентские экранные формы
+
+
+=== 7.4.1 Главная страница клиента
+
+
+Назначение страницы:
+
+- вход в основные разделы личного кабинета
+- отображение актуальных действий и событий
+
+Состав страницы:
+
+- верхняя навигация
+- быстрые переходы по основным разделам
+- блок актуальных заказов и заявок
+- блок последних уведомлений
+- блок бонусной информации при наличии подключенного бонусного контура
+- индикатор статуса заполненности профиля клиента
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/dashboard.svg", width: 100%),
+ caption: [Прототип главной страницы клиента],
+)
+
+
+=== 7.4.2 Каталог продукции
+
+
+Назначение страницы:
+
+- отображение товарных направлений
+- переход к карточке выбранного типа товара
+
+Состав страницы:
+
+- заголовок раздела
+- поиск при необходимости
+- сетка карточек товарных направлений
+- карточка каждого товарного направления с изображением и наименованием
+- переход в карточку выбранного товарного направления
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/catalog-grid.svg", width: 100%),
+ caption: [Прототип каталога продукции],
+)
+
+
+=== 7.4.3 Карточка товара
+
+
+Назначение страницы:
+
+- выбор параметров товара
+- просмотр стандартных вариантов
+- просмотр складских остатков
+- добавление выбранной позиции в корзину
+
+Состав страницы:
+
+- заголовок товара
+- изображение товара
+- блок выбора параметров
+- блок пояснений по параметрам
+- блок индивидуальных возможностей, если они разрешены
+- блок добавления в корзину
+- таблица доступных вариантов
+- блок навигации к соседним товарным направлениям
+
+Маршрут страницы:
+
+- /products/[slug]
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/product-card.svg", width: 100%),
+ caption: [Прототип карточки товара],
+)
+
+
+Состав блока выбора параметров:
+
+- ширина
+- длина
+- толщина
+- тип втулки
+- цвет
+- надпись
+- индивидуальные опции при наличии разрешения
+
+Состав блока пояснений:
+
+- описание каждого параметра простым деловым языком
+- ограничения по индивидуальной длине
+- правила по втулке с логотипом
+- правила по нанесению индивидуальной надписи
+
+=== 7.4.4 Корзина
+
+
+Назначение страницы:
+
+- просмотр выбранных позиций
+- изменение количества
+- удаление позиции
+- отправка заявки на заказ
+
+Состав страницы:
+
+- список позиций
+- параметры и количество
+- комментарий клиента
+- действие отправки заявки
+- выбранный адрес доставки
+- итоговая сводка по количеству позиций
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/cart.svg", width: 100%),
+ caption: [Прототип корзины],
+)
+
+
+=== 7.4.5 Карточка заявки или заказа
+
+
+Назначение страницы:
+
+- просмотр состава
+- просмотр статуса
+- просмотр стоимости и условий поставки после публикации
+- просмотр истории изменений
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/client-order.svg", width: 100%),
+ caption: [Прототип карточки заявки или заказа],
+)
+
+
+Состав страницы:
+
+- номер документа
+- статус
+- состав позиций
+- стоимость после публикации менеджером
+- условия поставки и доставки
+- история статусов
+- системные комментарии
+
+=== 7.4.6 Страница логина и регистрации
+
+
+Назначение страницы:
+
+- запуск входа в систему
+- запуск самостоятельной заявки на подключение
+- запуск сценариев входа через мессенджеры
+
+Состав страницы:
+
+- форма запроса кода входа
+- выбор канала входа
+- ссылка на самостоятельную заявку на подключение
+- блок пояснения по дальнейшему сценарию доступа
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/login.svg", width: 100%),
+ caption: [Прототип страницы логина и подключения],
+)
+
+
+=== 7.4.7 Список заказов
+
+
+Назначение страницы:
+
+- просмотр текущих и архивных заказов
+- фильтрация по периоду и статусу
+
+Состав страницы:
+
+- фильтры
+- таблица заказов
+- переход в карточку конкретного заказа
+
+=== 7.4.8 Уведомления
+
+
+Назначение страницы:
+
+- просмотр истории уведомлений по заказам, заявкам и бонусным операциям
+
+=== 7.4.9 Бонусный кабинет
+
+
+Назначение страницы:
+
+- просмотр текущего бонусного баланса
+- просмотр истории операций
+- инициирование действий, допускаемых правилами бонусной программы
+
+Состав страницы:
+
+- текущий баланс
+- история начислений и списаний
+- связанные реферальные сведения
+- форма подачи заявки на использование либо вывод бонусов
+- правила бонусной программы
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/bonus-cabinet.svg", width: 100%),
+ caption: [Прототип бонусного кабинета],
+)
+
+
+== 7.5 Менеджерские экранные формы
+
+
+=== 7.5.1 Список клиентов
+
+
+Назначение страницы:
+
+- просмотр клиентской базы
+- переход в карточку конкретного клиента
+
+Состав страницы:
+
+- поиск и фильтры
+- таблица клиентов
+- индикаторы активности и количества заказов
+- действие приглашения нового клиента
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/client-list.svg", width: 100%),
+ caption: [Прототип списка клиентов],
+)
+
+
+=== 7.5.2 Карточка клиента
+
+
+Назначение страницы:
+
+- просмотр сведений о компании
+- просмотр истории заявок и заказов
+- просмотр бонусных и реферальных данных
+
+Состав страницы:
+
+- карточка компании и контактных данных
+- реквизиты контрагента
+- список заказов клиента
+- список бонусных операций
+- связанные рефералы
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/client-card.svg", width: 100%),
+ caption: [Прототип карточки клиента],
+)
+
+
+=== 7.5.3 Карточка обработки заявки
+
+
+Назначение страницы:
+
+- просмотр состава заявки
+- ввод коммерческих условий
+- публикация условий клиенту
+- перевод заявки в работу либо отмена
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/manager-order.svg", width: 100%),
+ caption: [Прототип карточки обработки заявки],
+)
+
+
+Состав страницы:
+
+- клиент и контрагент
+- состав позиции или расчетный payload
+- стоимость
+- доставка
+- комментарий менеджера
+- история изменений
+- блок действий со статусом
+
+=== 7.5.4 Список заказов менеджера
+
+
+Назначение страницы:
+
+- просмотр заказов по клиентам
+- фильтрация по статусам
+- переход к обработке конкретного заказа
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/manager-orders.svg", width: 100%),
+ caption: [Прототип списка заказов менеджера],
+)
+
+
+=== 7.5.5 Настройки каталога
+
+
+Назначение страницы:
+
+- управление параметрами товарных направлений
+- управление стандартными значениями параметров
+- управление возможностями кастомизации
+- управление описаниями параметров
+
+Состав страницы:
+
+- список товарных направлений
+- карточка настроек конкретного направления
+- чекбоксы разрешений кастомизации
+- списки стандартных параметров
+- единое действие сохранения настроек
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/catalog-settings.svg", width: 100%),
+ caption: [Прототип настроек каталога],
+)
+
+
+=== 7.5.6 Настройки синхронизации и уведомлений
+
+
+Назначение страницы:
+
+- управление шаблонами уведомлений
+- управление параметрами интеграционного обмена
+
+Состав страницы:
+
+- список шаблонов уведомлений
+- каналы отправки
+- статусы последних синхронизаций
+- диагностическая информация по обмену
+
+Wireframe-прототип:
+
+#figure(
+ image("public/prototypes/sync-settings.svg", width: 100%),
+ caption: [Прототип настроек синхронизации],
+)
+
+
+== 7.6 Дополнительные профильные и сервисные страницы
+
+
+Помимо основных клиентских и менеджерских экранов, программный продукт включает дополнительные экранные формы:
+
+- профиль пользователя
+- реквизиты контрагента
+- список адресов доставки
+- создание нового адреса доставки
+- настройки уведомлений пользователя
+- экран успешного подключения канала уведомлений
+- менеджерский экран сообщений
+- бонусная система для менеджера
+- карточка бонусного счета клиента
+- создание реферальной связи
+- создание бонусной транзакции
+- проверка заявки на вывод бонусов
+
+Прототипы служебных и дополнительных экранов:
+
+#figure(
+ image("public/prototypes/profile.svg", width: 100%),
+ caption: [Прототип профиля клиента],
+)
+
+
+#figure(
+ image("public/prototypes/bonus-manager.svg", width: 100%),
+ caption: [Прототип бонусной системы менеджера],
+)
+
+
+#pagebreak(weak: true)
+= 8. Требования к интеграции с 1С и внешним интерфейсам
+
+
+== 8.1 Общие требования к интеграционному контуру
+
+
+Интеграционный слой должен обеспечивать обмен данными между личным кабинетом и внешними системами без потери целостности внутренних сущностей и статусов.
+
+Интеграционный контур должен обеспечивать:
+
+- получение данных из 1С
+- прием событий от 1С
+- передачу во внешние системы данных, необходимых для сопровождения заказов и клиентов, если такой обмен согласован сторонами
+- сопоставление внутренних идентификаторов и идентификаторов внешних систем
+- регистрацию входящих и исходящих операций обмена
+- повторную обработку неуспешных сообщений
+- хранение истории обновлений по интеграционным операциям
+
+== 8.2 Интеграция с 1С
+
+
+Интеграция с 1С должна обеспечивать обмен данными, необходимыми для сопровождения каталога, заказов, статусов, остатков и сведений о задолженности клиента.
+
+Система должна обеспечивать получение из 1С следующих данных:
+
+- каталог товаров
+- характеристики товаров
+- складские остатки
+- сведения о заказах
+- статусы заказов
+- изменения состава, стоимости, доставки и иных существенных параметров заказа
+- текущая задолженность клиента
+- дата актуальности сведений, полученных из 1С
+
+1С рассматривается как первичный источник учетных данных по заказам, складам, статусам, стоимости, доставке и задолженности. Личный кабинет отображает эти сведения и фиксирует дату их актуальности.
+
+== 8.3 События от 1С
+
+
+Система должна поддерживать прием webhook-событий от 1С в согласованном формате.
+
+Минимальный состав событий:
+
+- создание нового заказа
+- изменение информации по заказу
+- изменение статуса заказа
+- изменение сроков, условий или параметров доставки
+- изменение состава заказа
+- изменение сведений о задолженности клиента, если такие данные передаются событийно
+
+Для каждого события должны фиксироваться:
+
+- тип события
+- внешний идентификатор объекта 1С
+- внутренний идентификатор объекта, если сопоставление выполнено
+- дата и время события
+- источник события
+- статус обработки
+- текст ошибки при неуспешной обработке
+
+Система должна защищаться от повторной обработки дублей webhook-событий.
+
+== 8.4 Методы получения данных из 1С
+
+
+Система должна поддерживать получение данных из 1С через согласованные методы.
+
+Минимальный состав методов:
+
+- получение заказов клиента
+- получение товарного каталога
+- получение характеристик товаров
+- получение доступных остатков по складам
+- получение статусов и изменений по заказам
+- получение текущей задолженности клиента и даты актуальности этих сведений
+
+Точный набор методов, параметры запросов, формат ответов и ограничения по частоте вызовов фиксируются в интеграционной спецификации.
+
+== 8.5 Требования к структурам обмена
+
+
+Входные и выходные данные интеграционного слоя должны описываться в структурированном виде и позволять однозначно восстанавливать:
+
+- тип объекта обмена
+- идентификатор объекта
+- дату и время события
+- полезную нагрузку объекта
+- статус обработки
+- источник изменения
+
+Для обмена должны использоваться структурированные payload-форматы, пригодные для сериализации в JSON.
+
+Точная структура payload, схема подписи запросов и набор обязательных полей согласуются сторонами до начала этапа интеграции с 1С.
+
+== 8.6 Интеграционные поля и служебные атрибуты
+
+
+Для сущностей, участвующих в обмене, должны поддерживаться:
+
+- внешний идентификатор учетной системы
+- дата последней синхронизации
+- источник последнего обновления
+- признак успешной или неуспешной обработки
+- журнал интеграционных ошибок при наличии
+- технический идентификатор последнего обработанного события, если он передается 1С
+
+== 8.7 Журналирование интеграционных операций
+
+
+Для ключевых операций обмена система должна сохранять:
+
+- тип объекта
+- идентификатор объекта
+- предыдущее состояние
+- новое состояние
+- дату и время изменения
+- пользователя либо внешний источник, выполнивший изменение
+- статус обработки сообщения
+- текст ошибки при наличии
+
+== 8.8 Требования к защите интеграционного обмена
+
+
+Интеграционные запросы должны выполняться с использованием согласованного механизма авторизации или подписи.
+
+Система должна отклонять интеграционные запросы, если:
+
+- отсутствуют обязательные параметры авторизации
+- подпись или токен не прошли проверку
+- payload не соответствует согласованной структуре
+- невозможно определить тип события или объект обработки
+
+Секреты, используемые для интеграции с 1С, должны храниться только в Vault и передаваться сервисам через runtime-конфигурацию.
+
+== 8.9 Критерии приемки интеграции с 1С
+
+
+Интеграция с 1С считается готовой в согласованном объеме, если:
+
+- каталог и характеристики товаров получаются и отображаются в личном кабинете
+- остатки по складам отображаются в карточках товаров
+- заказы клиента получаются и отображаются с актуальными статусами
+- изменения заказа из 1С отображаются в карточке заказа
+- текущая задолженность клиента и дата актуальности данных отображаются в предусмотренных интерфейсах
+- webhook-события не обрабатываются повторно при дублях
+- ошибки интеграционного обмена фиксируются в журнале
+- неуспешные сообщения могут быть проанализированы и повторно обработаны в согласованном порядке
+
+#pagebreak(weak: true)
+= 9. Техническая архитектура, стек, компоненты и эксплуатационный контур
+
+
+== 9.1 Общая архитектурная схема
+
+
+Программный продукт реализуется по клиент-серверной модели и включает веб-клиент, сервер бизнес-логики, базу данных, модуль интеграции и вспомогательные сервисы уведомлений.
+
+#figure(
+ image("public/diagrams/architecture-overview.svg", width: 100%),
+ caption: [Общая архитектурная схема],
+)
+
+
+== 9.2 Состав прикладных сервисов
+
+
+Согласно действующей карте деплоя в составе проекта используются следующие сервисы:
+
+- web-frontend — клиентский и менеджерский веб-интерфейс
+- apollo-backend — сервер GraphQL и бизнес-логика
+- vault — централизованное хранилище секретов
+- tg-bot — Telegram-контур
+- max-bot — MAX-контур
+- bonus-bot — бонусный мессенджерный контур
+
+Основные прикладные сервисы web-frontend и apollo-backend разворачиваются через dokploy_webhook на сервере main.
+
+== 9.3 Технологический стек фронтенда
+
+
+Клиентская часть программного продукта реализуется на следующих технологиях:
+
+- Nuxt 4 — прикладной веб-фреймворк
+- Vue 3 — библиотека пользовательского интерфейса
+- \@nuxtjs/apollo и \@vue/apollo-composable — работа с GraphQL
+- GraphQL Code Generator — генерация типизированных GraphQL-документов
+- Tailwind CSS и daisyUI — базовая стилизация интерфейсов
+- Storybook — контур изоляционного просмотра компонентов
+- VitePress — подготовка проектной документации
+
+== 9.4 Технологический стек серверной части
+
+
+Серверная часть программного продукта реализуется на следующих технологиях:
+
+- Node.js — среда выполнения
+- Express 5 — HTTP-сервер
+- Apollo Server 5 — GraphQL-сервер
+- Prisma 7 — доступ к данным и ORM-слой
+- PostgreSQL — основное хранилище данных
+- Zod — валидация структур данных в прикладных сценариях
+- Nodemailer — отправка уведомлений по электронной почте
+
+== 9.5 Архитектура клиентской части
+
+
+Клиентская часть организована по следующим слоям:
+
+- страницы app/pages — входные экранные формы
+- компоненты app/components — переиспользуемые элементы интерфейса
+- composables app/composables — клиентская логика и представление данных
+- GraphQL-документы graphql/operations — отдельные запросы и мутации
+- сгенерированная типизированная схема app/composables/graphql/generated.ts
+- серверные proxy и интеграционные обработчики server/api
+
+Ключевые экранные маршруты текущей реализации:
+
+- /products и /products/[slug] — каталог и карточка товара
+- /cart — корзина
+- /client-orders и /client-orders/[id] — клиентские заявки и заказы
+- /clients и /clients/[id] — менеджерский контур клиентов
+- /orders и /orders/[id] — менеджерский контур заказов
+- /catalog-settings — административные настройки каталога
+- /bonus-program, /bonus-system/\* — бонусный контур
+
+== 9.6 Карта слоев и компонентов
+
+
+#figure(
+ image("public/diagrams/component-map.svg", width: 100%),
+ caption: [Карта слоев и компонентов],
+)
+
+
+== 9.7 Архитектура серверной части
+
+
+Серверная часть организована по следующим основным модулям:
+
+- src/server.js — инициализация HTTP-сервера и GraphQL-сервера
+- src/schema.graphql — контракт GraphQL API
+- src/resolvers.js — реализация GraphQL-операций
+- src/context.js — построение контекста запроса
+- src/auth.js — аутентификация и токены доступа
+- src/access.js — правила авторизации и проверки ролей
+- src/prisma-client.js — точка подключения Prisma
+- src/messenger\*.js, src/telegram\*.js, src/max-mini-app.js — мессенджерный контур и мини-приложения
+
+== 9.8 Взаимодействие фронтенда и backend
+
+
+Взаимодействие клиентской и серверной части строится через GraphQL API.
+
+На стороне Nuxt используется серверный proxy-маршрут /api/graphql, который:
+
+- принимает запросы браузера
+- прокидывает cookie и авторизационные заголовки
+- перенаправляет запрос в apollo-backend
+- возвращает результат в клиентское приложение
+
+Такой подход позволяет:
+
+- изолировать прямой backend endpoint от браузерного клиента
+- централизованно передавать авторизационные данные
+- поддерживать единый клиентский GraphQL endpoint
+
+== 9.9 Интеграционные и вспомогательные HTTP-точки
+
+
+Помимо GraphQL API, во фронтенд-контуре реализованы вспомогательные серверные маршруты:
+
+- /api/graphql — proxy в backend GraphQL API
+- /api/auth/messenger-start — запуск сценариев messenger login / connect
+- /api/dadata/address — подсказки адресов
+- /api/dadata/bank — подсказки банковских реквизитов
+- /api/dadata/party — подсказки контрагентов
+- /api/messenger-avatar/[connectionId] — выдача изображений, связанных с мессенджерными подключениями
+
+== 9.10 Компонентные требования к реализации
+
+
+Архитектура программного продукта должна сохранять следующие правила:
+
+- экранная логика должна находиться на уровне страниц и composables
+- переиспользуемые элементы интерфейса должны быть вынесены в компоненты
+- каждый GraphQL-документ должен храниться в отдельном .graphql файле
+- клиентский код должен использовать сгенерированные типизированные документы
+- серверная логика доступа к данным должна проходить через Prisma
+- бизнес-правила доступа должны контролироваться серверной частью, а не только интерфейсом
+
+== 9.11 Требования к конфигурации и секретам
+
+
+Сервисы программного продукта должны получать прикладные секреты из Vault.
+
+В конфигурации сервисов допускается хранение только bootstrap-параметров для подключения к Vault. Бизнес-секреты, ключи интеграций и иные чувствительные данные должны загружаться из Vault при старте приложения.
+
+== 9.12 Инфраструктура, деплой и эксплуатационный контур
+
+
+Текущая инфраструктурная схема проекта включает прикладные сервисы, сервис секретов, мессенджерные сервисы и вспомогательный worker-контур.
+
+#figure(
+ image("public/diagrams/infrastructure-topology.svg", width: 100%),
+ caption: [Инфраструктура, деплой и эксплуатационный контур],
+)
+
+
+Сервисы проекта и способ их развёртывания:
+
+#text(size: 7.6pt)[
+ #table(
+ columns: (1fr, 1fr, 1fr, 1fr, 1fr),
+ stroke: rgb("#d0d7de"),
+ inset: 4pt,
+ align: horizon + left,
+ [*Сервис*],
+ [*Путь в репозитории*],
+ [*Роль*],
+ [*Deploy mode*],
+ [*Сервер*],
+ [web-frontend],
+ [web-frontend],
+ [клиентский и менеджерский веб-интерфейс],
+ [dokploy_webhook],
+ [main],
+ [apollo-backend],
+ [apollo-backend],
+ [GraphQL API и бизнес-логика],
+ [dokploy_webhook],
+ [main],
+ [hatchet-worker],
+ [hatchet-worker],
+ [фоновый worker-контур],
+ [dokploy_webhook],
+ [main],
+ [tg-bot],
+ [tg-bot],
+ [Telegram-контур],
+ [dokploy_webhook],
+ [main],
+ [max-bot],
+ [max-bot],
+ [MAX-контур],
+ [dokploy_webhook],
+ [main],
+ [bonus-bot],
+ [bonus-bot],
+ [бонусный сервис],
+ [dokploy_webhook],
+ [main],
+ [vault],
+ [vault],
+ [сервис секретов],
+ [dokploy_webhook],
+ [main]
+ )
+]
+
+
+Серверная карта текущего проекта:
+
+- сервер main
+- Tailscale user: root
+- Tailscale host: dsrptlab
+
+Эксплуатационные операции доступа и диагностики выполняются через Tailscale SSH.
+
+== 9.13 Dokploy и цепочка развёртывания
+
+
+Для основных сервисов проекта используется режим dokploy_webhook.
+
+Это означает следующую последовательность:
+
++ изменения фиксируются в Git-репозитории;
++ изменения публикуются в main;
++ Dokploy получает webhook-событие;
++ Dokploy выполняет сборку соответствующего сервиса;
++ сервис перезапускается с загрузкой секретов из Vault;
++ после старта выполняются bootstrap-действия, предусмотренные образом и entrypoint-командой.
+
+Текущие особенности прикладных сервисов:
+
+- web-frontend стартует через загрузку Vault env и запуск .output/server/index.mjs
+- apollo-backend стартует через загрузку Vault env, prisma migrate deploy и запуск src/server.js
+- bot-сервисы стартуют через общий паттерн загрузки Vault env и запуск node src/server.js
+
+== 9.14 Vault и хранение секретов
+
+
+Сервис vault развернут как отдельное приложение на базе образа hashicorp/vault:1.21.3.
+
+Текущие инфраструктурные правила работы Vault:
+
+- используется raft storage
+- данные Vault сохраняются в /vault/data
+- конфигурация сервиса хранится в vault/config/vault.hcl
+- при старте выполняется проверка и, при необходимости, автоматический unseal из переменных окружения
+- прикладные сервисы подключаются к Vault через bootstrap-переменные VAULT_ADDR, VAULT_TOKEN, VAULT_KV_MOUNT, VAULT_SHARED_PATH, VAULT_PROJECT_PATH, VAULT_ENABLED
+
+Прикладные сервисы используют общий shell-bootstrap load-vault-env.sh, который:
+
+- ожидает доступность Vault по health endpoint
+- загружает shared secrets
+- загружает project secrets
+- экспортирует секреты в runtime environment процесса
+
+== 9.15 Структура сервисных каталогов
+
+
+Текущая сервисная структура репозитория:
+
+- web-frontend — Nuxt-приложение, GraphQL operations, VitePress-документация
+- apollo-backend — Apollo Server, Prisma schema, миграции, импорт каталога
+- tg-bot — Telegram-сервис
+- max-bot — MAX-сервис
+- bonus-bot — бонусный сервис
+- hatchet-worker — worker-контур
+- vault — Dockerfile, конфигурация и entrypoint Vault
+- hatchet — docker-compose инфраструктурного контура Hatchet
+
+== 9.16 Контур фоновых процессов
+
+
+В проекте присутствует отдельный контур фонового исполнения задач:
+
+- hatchet-worker как прикладной worker
+- hatchet-engine как движок исполнения
+- hatchet-dashboard как интерфейс мониторинга
+- отдельный postgres для Hatchet-контура
+
+Конфигурация этого контура находится в hatchet/docker-compose.yml.
+
+== 9.17 Зафиксированные runtime-версии и технологические зависимости
+
+
+=== Базовые runtime и контейнерные образы
+
+
+#text(size: 7.6pt)[
+ #table(
+ columns: (1fr, 1fr),
+ stroke: rgb("#d0d7de"),
+ inset: 4pt,
+ align: horizon + left,
+ [*Компонент*],
+ [*Текущая версия*],
+ [Node base image для web/backend/bots],
+ [node:22-bookworm-slim],
+ [Vault image],
+ [hashicorp/vault:1.21.3],
+ [Hatchet Postgres],
+ [postgres:15.6],
+ [Nuxt],
+ [4.4.2],
+ [Vue],
+ [3.5.30],
+ [Apollo Server],
+ [5.5.0],
+ [Prisma / Prisma Client],
+ [7.6.0],
+ [Mermaid],
+ [11.14.0],
+ [VitePress],
+ [1.6.4]
+ )
+]
+
+
+=== Основные зависимости фронтенда
+
+
+#text(size: 7.6pt)[
+ #table(
+ columns: (1fr, 1fr, 1fr),
+ stroke: rgb("#d0d7de"),
+ inset: 4pt,
+ align: horizon + left,
+ [*Библиотека*],
+ [*Версия*],
+ [*Назначение*],
+ [\\\@nuxtjs/apollo],
+ [5.0.0-alpha.16],
+ [GraphQL-клиентский слой],
+ [\\\@vue/apollo-composable],
+ [4.2.2],
+ [composable API для GraphQL],
+ [\\\@apollo/client],
+ [3.14.1],
+ [Apollo client runtime],
+ [\\\@fullcalendar/core],
+ [6.1.20],
+ [calendar runtime],
+ [\\\@fullcalendar/daygrid],
+ [6.1.20],
+ [calendar day grid],
+ [\\\@fullcalendar/vue3],
+ [6.1.20],
+ [Vue integration for calendar],
+ [\\\@nuxt/eslint],
+ [1.15.2],
+ [linting Nuxt-проекта],
+ [\\\@nuxtjs/tailwindcss],
+ [6.14.0],
+ [Tailwind integration],
+ [daisyui],
+ [5.5.19],
+ [UI primitives],
+ [graphql],
+ [16.13.2],
+ [GraphQL runtime],
+ [mermaid],
+ [11.14.0],
+ [diagrams in documentation],
+ [\\\@sentry/vue],
+ [10.46.0],
+ [error tracking],
+ [storybook],
+ [8.6.14],
+ [UI component review],
+ [vue-router],
+ [5.0.4],
+ [Vue routing runtime]
+ )
+]
+
+
+=== Основные зависимости backend
+
+
+#text(size: 7.6pt)[
+ #table(
+ columns: (1fr, 1fr, 1fr),
+ stroke: rgb("#d0d7de"),
+ inset: 4pt,
+ align: horizon + left,
+ [*Библиотека*],
+ [*Версия*],
+ [*Назначение*],
+ [\\\@apollo/server],
+ [5.5.0],
+ [GraphQL server],
+ [\\\@as-integrations/express5],
+ [1.1.2],
+ [Apollo + Express integration],
+ [express],
+ [5.2.1],
+ [HTTP server],
+ [\\\@prisma/client],
+ [7.6.0],
+ [data access],
+ [\\\@prisma/adapter-pg],
+ [7.6.0],
+ [Prisma adapter],
+ [pg],
+ [8.20.0],
+ [PostgreSQL driver],
+ [graphql],
+ [16.13.2],
+ [GraphQL runtime],
+ [zod],
+ [4.3.6],
+ [validation],
+ [nodemailer],
+ [8.0.4],
+ [email notifications],
+ [dotenv],
+ [17.3.1],
+ [env bootstrap in local/runtime layers]
+ )
+]
+
+
+=== Основные зависимости worker-контура
+
+
+#text(size: 7.6pt)[
+ #table(
+ columns: (1fr, 1fr, 1fr),
+ stroke: rgb("#d0d7de"),
+ inset: 4pt,
+ align: horizon + left,
+ [*Библиотека*],
+ [*Версия*],
+ [*Назначение*],
+ [\\\@hatchet-dev/typescript-sdk],
+ [1.19.0],
+ [worker runtime],
+ [dotenv],
+ [17.3.1],
+ [env bootstrap in local/runtime layers]
+ )
+]
+
+
+== 9.18 Технические конфигурационные файлы
+
+
+Ключевые технические файлы текущей реализации:
+
+- deploy-map.toml — карта сервисов, deploy mode и серверов
+- web-frontend/nuxt.config.ts — конфигурация Nuxt и Apollo
+- web-frontend/codegen.ts — конфигурация GraphQL codegen
+- apollo-backend/prisma.config.ts — конфигурация Prisma
+- apollo-backend/prisma/schema.prisma — модель данных
+- web-frontend/scripts/load-vault-env.sh — Vault bootstrap frontend
+- apollo-backend/scripts/load-vault-env.sh — Vault bootstrap backend
+- vault/config/vault.hcl — конфигурация Vault
+- vault/entrypoint.sh — startup/unseal логика Vault
+
+#pagebreak(weak: true)
+= 10. Нефункциональные требования
+
+
+== 10.1 Общие требования к архитектуре
+
+
+Программный продукт должен быть реализован как веб-система с разделением клиентского и менеджерского контуров, серверной бизнес-логикой, постоянным хранением данных и возможностью интеграционного обмена с внешними системами.
+
+== 10.2 Требования к доступности интерфейсов
+
+
+Система должна обеспечивать корректную работу:
+
+- в десктопных браузерах
+- в мобильных браузерах
+- на основных пользовательских разрешениях экрана
+
+Интерфейсы должны сохранять работоспособность и читаемость при адаптивном отображении.
+
+== 10.3 Требования к производительности
+
+
+При штатной эксплуатации система должна обеспечивать:
+
+- приемлемое время открытия основных экранов
+- приемлемое время отправки заявок и выполнения пользовательских действий
+- отображение каталогов, карточек и заказов без заметных задержек при типовом объеме данных
+
+Точные количественные показатели производительности подлежат фиксации в рабочей документации по инфраструктуре и тестированию.
+
+== 10.4 Требования к безопасности
+
+
+Система должна обеспечивать:
+
+- аутентификацию пользователей
+- авторизацию по ролям
+- ограничение доступа клиента только к данным своего контрагента
+- хранение и передачу чувствительных данных с использованием защищенных механизмов
+- исключение несанкционированного доступа к административным функциям
+
+== 10.5 Требования к надежности и журналированию
+
+
+Система должна обеспечивать:
+
+- сохранность пользовательских данных
+- сохранность истории изменений по заявкам, заказам и бонусным операциям
+- фиксацию ошибок интеграционного обмена
+- фиксацию значимых системных и пользовательских событий
+
+== 10.6 Требования к сопровождаемости
+
+
+Реализация должна обеспечивать возможность:
+
+- сопровождения и развития клиентского контура
+- сопровождения и развития менеджерского контура
+- изменения параметров каталога и уведомлений без переработки базовой структуры системы
+- расширения интеграционного обмена с 1С и иными внешними системами
+
+== 10.7 Требования к данным и актуальности сведений
+
+
+Система должна обеспечивать:
+
+- хранение актуального состояния пользовательских данных
+- отображение даты актуальности сведений, полученных из внешних систем, когда это применимо
+- защиту от потери данных при обновлении параметров каталога и заказных сущностей
+
+== 10.8 Требования к документации
+
+
+По результатам выполнения работ должна быть сформирована документация, достаточная для:
+
+- приемки результата работ
+- дальнейшего сопровождения программного продукта
+- понимания состава функций, данных, ролей и интеграций
+
+#pagebreak(weak: true)
+= 11. Требования к программной документации
+
+
+== 11.1 Общий подход
+
+
+Настоящее техническое задание является основным техническим документом программного продукта.
+
+В составе настоящего технического задания фиксируются:
+
+- назначение и границы продукта
+- функциональные требования
+- роли пользователей и права доступа
+- требования к данным, сущностям и модели базы данных
+- требования к интерфейсам
+- требования к интеграциям
+- архитектура, стек, компоненты и эксплуатационный контур
+- нефункциональные требования
+- порядок контроля, приемки и гарантийного сопровождения
+
+Отдельные документы не должны дублировать техническое задание. Дополнительная документация должна описывать только то, что необходимо для использования, эксплуатации или интеграции программного продукта и не раскрыто в настоящем документе в достаточном объеме.
+
+== 11.2 Пользовательская документация
+
+
+Пользовательская документация должна быть подготовлена в объеме, достаточном для работы пользователей в предусмотренных ролях:
+
+- клиент
+- менеджер
+- суперменеджер
+
+Пользовательская документация должна описывать:
+
+- вход в личный кабинет и завершение регистрации
+- работу с профилем и каналами уведомлений
+- просмотр каталога готовой продукции
+- добавление товаров в корзину и отправку заявки
+- создание заявки на расчет индивидуальной продукции
+- просмотр заказов, статусов, условий и истории изменений
+- работу с бонусным кабинетом, бонусным балансом и заявками на вывод
+- действия менеджера по обработке клиентов, заявок, заказов и бонусных операций
+- действия суперменеджера в административных разделах, если они отличаются от действий менеджера
+
+Документация должна быть написана прикладным языком и ориентирована на выполнение пользовательских сценариев, а не на описание внутренней реализации.
+
+== 11.3 Эксплуатационная документация
+
+
+Эксплуатационная документация должна быть подготовлена в объеме, достаточном для сопровождения программного продукта после передачи результата работ.
+
+Эксплуатационная документация должна описывать:
+
+- состав сервисов и их назначение
+- порядок запуска и перезапуска сервисов через согласованный контур деплоя
+- используемые окружения и общие принципы конфигурации
+- порядок загрузки секретов из Vault
+- порядок просмотра логов и диагностики типовых сбоев
+- порядок проверки работоспособности клиентского, менеджерского и интеграционного контуров
+- порядок обновления приложения через Git и Dokploy
+- перечень технических контактов или зон ответственности, если они согласованы сторонами
+
+Эксплуатационная документация не должна содержать бизнес-секреты, токены, пароли и иные чувствительные значения. Для секретов указываются только имена переменных, назначение и источник получения.
+
+== 11.4 Интеграционная документация
+
+
+Для интеграции с 1С должна быть подготовлена интеграционная спецификация либо отдельный раздел настоящего технического задания, если к моменту согласования ТЗ формат обмена уже определен.
+
+Интеграционная документация должна описывать:
+
+- состав событий, передаваемых из 1С
+- состав методов получения данных из 1С
+- структуру payload для каждого события и метода
+- обязательные и необязательные поля
+- правила сопоставления идентификаторов
+- требования к авторизации, подписи или иному механизму защиты запросов
+- порядок обработки дублей
+- порядок фиксации ошибок и повторной обработки сообщений
+- критерии приемки интеграционного обмена
+
+Если точный формат обмена с 1С не определен на момент утверждения ТЗ, он фиксируется отдельной согласованной интеграционной спецификацией до начала завершающего этапа интеграции.
+
+== 11.5 Перечень сторонних компонентов
+
+
+Перечень сторонних компонентов формируется на основании фактических файлов проекта, включая package.json, lock-файлы, Dockerfile и конфигурационные файлы сервисов.
+
+Перечень должен содержать:
+
+- наименование компонента
+- версию или диапазон версий
+- назначение компонента в продукте
+- источник установки или репозиторий, если он отличается от стандартного пакетного менеджера
+
+Ключевые сторонние компоненты, используемые в текущей реализации, перечислены в разделе технической архитектуры настоящего технического задания.
+
+#pagebreak(weak: true)
+= 12. Технико-экономические показатели
+
+
+== 12.1 Назначение показателей
+
+
+Технико-экономические показатели используются для фиксации ожидаемого прикладного эффекта от разработки программного продукта.
+
+Расчет финансовой эффективности, окупаемости или экономического эффекта в денежном выражении не входит в состав настоящего технического задания, если стороны не согласуют такой расчет отдельно.
+
+== 12.2 Ожидаемый прикладной эффект
+
+
+Разработка программного продукта должна обеспечить:
+
+- снижение объема ручной коммуникации при приеме и сопровождении заказов
+- единый интерфейс для клиента, менеджера и суперменеджера
+- ускорение обработки заявок за счет фиксации состава, параметров и статусов в системе
+- снижение риска потери информации по заказам, заявкам и бонусным операциям
+- повышение прозрачности статусов заказов и актуальности данных для клиента
+- централизованное хранение истории изменений
+- возможность дальнейшего развития клиентского, менеджерского, бонусного и интеграционного контуров
+
+== 12.3 Ограничения
+
+
+Программный продукт не заменяет учетную систему 1С и не является первичным источником бухгалтерских, складских или финансовых данных.
+
+Экономический эффект зависит от полноты внедрения продукта в рабочие процессы заказчика, качества данных 1С, доступности внешних каналов уведомлений и соблюдения эксплуатационных требований.
+
+#pagebreak(weak: true)
+= 13. Стадии и этапы разработки
+
+
+== 13.1 Общий порядок выполнения работ
+
+
+Работы выполняются поэтапно, чтобы согласовывать ключевые решения до перехода к следующей части реализации.
+
+Переход к следующему этапу выполняется после согласования сторонами результата предыдущего этапа либо после фиксации замечаний, не препятствующих продолжению работ.
+
+== 13.2 Этап 1. Разработка и согласование технического задания
+
+
+На этапе разрабатывается и согласуется настоящее техническое задание.
+
+Результат этапа:
+
+- согласованная редакция технического задания
+- зафиксированные границы продукта
+- зафиксированный состав пользовательских ролей
+- зафиксированные функциональные, интеграционные, технические и эксплуатационные требования
+
+Критерий завершения этапа: утверждение технического задания сторонами.
+
+== 13.3 Этап 2. UX/UI и согласование визуального подхода
+
+
+На этапе подготавливаются 2-3 сверстанные страницы личного кабинета с основными элементами интерфейса.
+
+В состав страниц для согласования могут входить:
+
+- страница входа или регистрации
+- каталог либо карточка товара
+- корзина либо карточка заявки
+- менеджерская карточка клиента или заказа
+
+Результат этапа:
+
+- согласованный визуальный подход
+- согласованные базовые интерфейсные элементы
+- подтверждение применимости выбранного подхода для клиентского и менеджерского контуров
+
+Критерий завершения этапа: согласование визуального подхода сторонами.
+
+== 13.4 Этап 3. Функциональная реализация без интеграции с 1С
+
+
+На этапе реализуются основные пользовательские и менеджерские сценарии без подключения обмена с 1С.
+
+В состав этапа входят:
+
+- регистрация и подключение клиентов
+- роли и разграничение доступа
+- каталог готовой продукции
+- корзина и заявки на заказ
+- заявки на расчет индивидуальной продукции
+- обработка заявок менеджером
+- статусы и история изменений
+- уведомления в согласованном объеме
+- бонусный и реферальный контур
+- административные настройки, необходимые для работы продукта
+
+Результат этапа:
+
+- работоспособный программный продукт с основным функционалом
+- возможность проверки клиентских, менеджерских и бонусных сценариев без обмена с 1С
+
+Критерий завершения этапа: готовность и приемка основного функционала без интеграции с 1С.
+
+== 13.5 Этап 4. Интеграция с 1С и отладка обмена
+
+
+На этапе выполняются подключение, настройка и отладка интеграции с 1С.
+
+В состав этапа входят:
+
+- согласование или уточнение интеграционной спецификации
+- настройка приема webhook-событий от 1С
+- настройка получения данных из 1С через согласованные методы
+- сопоставление внутренних идентификаторов и идентификаторов 1С
+- проверка получения каталога, остатков, заказов, статусов и задолженности
+- проверка обработки дублей и ошибок обмена
+- проверка отображения даты актуальности данных
+
+Результат этапа:
+
+- работоспособный интеграционный обмен с 1С в согласованном объеме
+- журналирование ключевых интеграционных событий
+- подтвержденная работоспособность сценариев, зависящих от данных 1С
+
+Критерий завершения этапа: подтвержденная сторонами работоспособность сценариев с 1С в согласованном объеме.
+
+== 13.6 Этап 5. Передача результата и приемка
+
+
+На этапе выполняются итоговая проверка, устранение критичных замечаний и передача результата работ.
+
+Результат этапа:
+
+- размещенный программный продукт в согласованном эксплуатационном контуре
+- согласованная редакция технического задания
+- пользовательская и эксплуатационная документация в согласованном объеме
+- перечень ключевых сторонних компонентов
+- акт приемки выполненных работ
+
+Критерий завершения этапа: подписание акта приемки либо наступление условий приемки, предусмотренных договором.
+
+#pagebreak(weak: true)
+= 14. Порядок контроля, приемки и гарантийного сопровождения
+
+
+== 14.1 Общие положения приемки
+
+
+Приемка результата работ должна подтверждать соответствие программного продукта требованиям настоящего технического задания, условиям договора и согласованным требованиям заказчика.
+
+При приемке подлежат проверке:
+
+- клиентский контур
+- менеджерский контур
+- каталог готовой продукции
+- сценарии заявок на заказ
+- сценарии заявок на расчет
+- сопровождение заказов
+- уведомления
+- бонусный и реферальный контур
+- интеграционный обмен с 1С в согласованном объеме
+- пользовательская и эксплуатационная документация в согласованном объеме
+
+== 14.2 Виды проверок
+
+
+Для контроля результата работ используются следующие виды проверок:
+
+- функциональная проверка основных пользовательских сценариев
+- проверка разграничения ролей и прав доступа
+- проверка корректности данных, статусов и истории изменений
+- проверка интерфейсов на desktop и mobile
+- проверка уведомлений по согласованным каналам
+- проверка интеграционного обмена с 1С
+- проверка запуска и работы сервисов в согласованном эксплуатационном контуре
+
+== 14.3 Критерии приемки
+
+
+Программный продукт считается соответствующим требованиям, если:
+
+- обязательные пользовательские сценарии выполняются корректно
+- разграничение ролей и прав доступа реализовано корректно
+- заявкам, заказам и бонусным операциям присваиваются и отображаются корректные статусы
+- каталог и остатки отображаются корректно
+- цена не отображается клиенту до публикации условий менеджером
+- менеджер имеет возможность обработать заявку и опубликовать условия
+- история изменений сохраняется и доступна в предусмотренных сценариях
+- сведения из 1С отображаются в согласованном объеме
+- текущая задолженность клиента и дата актуальности данных отображаются при наличии этих сведений из 1С
+- критичные дефекты, препятствующие выполнению основных сценариев, устранены до передачи результата
+
+== 14.4 Передаваемые материалы
+
+
+В состав передаваемых заказчику материалов входят:
+
+- программный продукт, размещенный в согласованном эксплуатационном контуре
+- исходный код разработанных компонентов в репозитории проекта
+- согласованная редакция настоящего технического задания
+- пользовательская документация в согласованном объеме
+- эксплуатационная документация в согласованном объеме
+- интеграционная спецификация 1С, если точные форматы обмена фиксируются отдельно от настоящего технического задания
+- перечень ключевых сторонних компонентов, сформированный на основании фактических файлов проекта
+
+Технические схемы, модель данных, роли, архитектура, стек, состав сервисов и требования к интеграциям являются частью настоящего технического задания и не дублируются в отдельных документах без отдельного согласования сторон.
+
+== 14.5 Порядок фиксации замечаний
+
+
+Каждое замечание, выявленное при приемке, должно содержать:
+
+- описание проблемы
+- сценарий воспроизведения
+- ожидаемый результат
+- фактический результат
+- уровень критичности
+- статус устранения
+
+Замечания, не препятствующие выполнению основных пользовательских и интеграционных сценариев, могут быть зафиксированы сторонами для последующего устранения в согласованном порядке.
+
+== 14.6 Гарантийный срок
+
+
+Гарантийный срок на разработанные модули, сервисы и дополнительный функционал составляет 6 месяцев с даты подписания акта приемки выполненных работ, если иной порядок не согласован сторонами.
+
+Гарантия распространяется на дефекты разработанного программного продукта, проявившиеся при штатной эксплуатации и относящиеся к функционалу, реализованному исполнителем.
+
+== 14.7 Порядок гарантийного обращения
+
+
+Гарантийное обращение должно быть передано исполнителю в письменной форме или иным согласованным сторонами способом.
+
+В обращении должны быть указаны:
+
+- описание дефекта
+- пользовательская роль или контур, в котором проявляется дефект
+- шаги воспроизведения
+- ожидаемый результат
+- фактический результат
+- дата и время обнаружения
+- дополнительные материалы, если они нужны для диагностики
+
+Исполнитель выполняет диагностику дефекта и, если дефект относится к гарантийной зоне ответственности, устраняет его без дополнительной оплаты.
+
+Срок устранения гарантийного дефекта составляет не более 3 дней с даты получения обращения либо иной срок, согласованный сторонами с учетом критичности и характера дефекта.
+
+== 14.8 Ограничения гарантийного сопровождения
+
+
+Гарантийное сопровождение не распространяется на случаи, когда некорректная работа вызвана:
+
+- самостоятельным изменением программного продукта заказчиком или третьими лицами без согласования с исполнителем
+- ошибками сервера, хостинга, инфраструктуры или базы данных, не связанными с разработанным функционалом
+- атакой, компрометацией доступа или нарушением требований информационной безопасности со стороны заказчика
+- некорректной работой стороннего программного обеспечения
+- недоступностью или некорректной работой внешних систем, включая 1С, Telegram, Max, почтовые сервисы и иные внешние API
+- изменением форматов или правил работы внешних систем без предварительного согласования и обновления интеграционной спецификации
+
+Если дефект связан с внешней системой или инфраструктурой, исполнитель фиксирует результат диагностики и передает заказчику сведения, достаточные для дальнейшего устранения причины на стороне соответствующей системы или поставщика.