Развёрнутое ТЗ по краткому заданию заказчика: что именно будет сделано за 14 дней, как это устроено внутри и по каким признакам принимается каждый этап.
Гендок — веб-сервис для людей без юридической подготовки. Человек описывает ситуацию своими словами или выбирает её в каталоге, отвечает на 5–10 вопросов и получает готовый документ: претензию, заявление, жалобу или обращение. Дальше сервис ведёт «дело»: помнит дату отправки и контрольный срок, напоминает о нём и предлагает следующий документ, если ответа нет.
Результат MVP — работающий на сервере заказчика сервис, в котором весь этот путь проходится без участия разработчика, а ситуации, шаблоны, анкеты, промпты, модели и тарифы меняются из админки.
Мобильные приложения, бот в MAX, проверка документа живым юристом, сложный визуальный редактор шаблонов. Архитектура не мешает добавить их позже: бот в MAX — ещё один канал уведомлений, проверка юристом — ещё один статус документа.
| Роль | Что может |
|---|---|
| Гость | Читает каталог и блог, проходит мастер до предпросмотра. Черновик привязан к сессии и переезжает в аккаунт после входа. |
| Пользователь | Скачивает документы в пределах лимита или после оплаты, ведёт дела, получает напоминания, управляет подпиской, удаляет свои данные. |
| Редактор | В админке: ситуации, анкеты, шаблоны, промпты, SEO-поля, блог. |
| Поддержка | В админке: пользователи, дела, платежи, возвраты. Без доступа к настройкам. |
| Владелец | Всё, включая модели ИИ, тарифы, роли и журнал расходов. |
| Адрес | Назначение | В поиске |
|---|---|---|
/ | Главная: поле «опишите ситуацию», популярные ситуации, как это работает, тарифы | да |
/situacii, /situacii/{категория} | Каталог с категориями | да |
/situacii/{slug} | Страница ситуации: когда подходит, что понадобится, срок ответа, образец, вопросы и ответы, кнопка «Составить» | да |
/blog, /blog/{slug} | Заготовка блога: список и статья | да |
/oferta, /politika | Оферта и политика, текст правится в админке | да |
/sozdat/{uuid} | Мастер: анкета, сборка, предпросмотр | нет |
/vhod | Вход по коду из письма или через Telegram | нет |
/kabinet, /kabinet/dela/{id} | Список дел и карточка дела | нет |
/kabinet/tarif | Лимиты, подписка, история платежей | нет |
/hooks/yookassa, /hooks/telegram | Входящие уведомления платёжной системы и бота | нет |
/admin | Панель Filament | нет |
/sitemap.xml, /robots.txt | Собираются автоматически по опубликованным страницам | — |
PostgreSQL 16. У сущностей, общих для будущих сервисов, есть поле service_id: Гендок — первая запись в таблице сервисов.
| Таблица | Что хранит |
|---|---|
users | e-mail, Telegram ID, ФИО, адрес, телефон, часовой пояс, каналы уведомлений, версия принятого согласия |
login_codes | Хеш кода, срок жизни, число попыток |
services | Сервисы на общем ядре |
categories, situations | Ситуация: название, slug, документ, адресат, срок ответа (дни, календарные или рабочие), следующий шаг, SEO-поля, статус публикации |
questions | Вопросы анкеты: ключ, тип, обязательность, подсказка, пример, условие показа, признак персональных данных, порядок |
templates | Файл DOCX, версия, список найденных переменных и блоков, правила проверки реквизитов |
prompts | Задача, версия, текст, параметры модели, JSON-схема ответа |
ai_providers | Драйвер, модель, приоритет, включён/выключен, таймаут, цена токенов, лимит расхода в день |
ai_requests | Журнал: задача, провайдер, попытка, статус, время, токены, стоимость, версия промпта, обезличенные запрос и ответ |
cases | Дело: пользователь, ситуация, статус, дата отправки, контрольный срок, исход |
documents | Документ дела: ответы анкеты, блоки текста, версия шаблона, пути к DOCX и PDF, признак «текст без ИИ» |
case_events | История дела: что и когда произошло |
reminders, notifications | Запланированные напоминания и журнал отправок по каналам со статусом доставки |
tariffs, payments, subscriptions, entitlements | Тарифы, платежи ЮKassa, подписки, остаток доступных скачиваний |
holidays | Производственный календарь для расчёта рабочих дней |
posts, pages | Блог и служебные страницы |
черновик → ситуация определена → анкета → сборка → готов → скачан. Каждое состояние сохраняется: вкладку можно закрыть и вернуться по ссылке или из кабинета.
У шаблона есть список обязательных переменных и правила. Перед скачиванием сервис показывает список: что заполнено, чего нет. Незаполненные места в предпросмотре выделены. Документ с пропусками скачать можно, но только после явного подтверждения.
Документ хранится как набор блоков: шапка, заголовок, абзацы, требования, подпись. Реквизиты меняются через анкету, текст абзацев — прямо в предпросмотре. Правки сохраняются как блоки, поэтому DOCX и PDF всегда собираются из актуального текста, а не из HTML. Кнопка «Собрать заново» возвращает текст модели.
Обращение к ИИ и сборка файлов идут в очереди. Страница опрашивает статус раз в секунду и показывает, что происходит: «определяем ситуацию», «пишем текст», «собираем файл». Запросы пользователей не занимают PHP-процессы на время ответа нейросети.
interface LlmDriver {
public function complete(LlmRequest $request): LlmResponse;
}
// YandexGptDriver, GigaChatDriver, OpenAiCompatibleDriver
Резерв подключается через OpenAiCompatibleDriver: адрес, ключ и название модели задаются в админке, поэтому смена резервного провайдера не требует правки кода. Особенности провайдеров спрятаны в драйверах: у GigaChat токен доступа живёт 30 минут и кешируется в Redis, в контейнер ставятся сертификаты Минцифры; у YandexGPT — ключ сервисного аккаунта и идентификатор каталога.
| Задача | На входе | На выходе (JSON по схеме) |
|---|---|---|
| Определение ситуации | Текст пользователя, список ситуаций | slug ситуации, уверенность, извлечённые поля анкеты |
| Текст обстоятельств | Обезличенные ответы анкеты | 1–3 абзаца фактов для документа |
| Следующий шаг | Дело, исход, история | Рекомендация и следующий документ из разрешённого списка |
Таймаут, число повторов и порог предохранителя — настройки, а не константы в коде.
[ФИО], [АДРЕС]) и подставляются обратно уже на сервере.${fio}, ${sum}. Условные блоки: ${expertiza}…${/expertiza}. Повторяющиеся строки таблиц — через клонирование строки. Обработка — PhpWord TemplateProcessor.docs, цель — до 5 секунд на документ.документ готов → отправлено, ждём ответа → срок истёк → ответ получен (удовлетворено / отказ / частично) → закрыто. Из «срок истёк» и «отказ» доступен переход к следующему документу.
У ситуации задано число дней и способ счёта — календарные или рабочие. Срок считается от даты отправки, которую отмечает пользователь. Рабочие дни считаются по производственному календарю из таблицы holidays; календарь обновляется раз в год и правится в админке.
notify. У напоминания уникальный ключ «дело + тип», повторной отправки не будет.У ситуации в админке задаются следующие документы и условие: нет ответа или отказ. Новый документ создаётся в том же деле, получает ответы предыдущей анкеты, дату первой претензии и задаёт только недостающие вопросы.
payment.succeeded. Уведомление проверяется встречным запросом статуса платежа; повторное уведомление ничего не начисляет дважды.entitlements и списывает его. Повторное скачивание того же документа бесплатно.Одна панель Filament на все будущие сервисы. Общее ядро — пользователи, роли, платежи, ИИ-слой, уведомления, журнал — отделено от модуля «Гендок». Новый сервис добавляет свой модуль и группу в меню, а не вторую админку.
| Раздел | Что делает |
|---|---|
| Ситуации и категории | Название, документ, адресат, срок ответа, следующий шаг, публикация, SEO-поля |
| Анкеты | Вопросы ситуации: тип, обязательность, подсказка, пример, условие показа; порядок перетаскиванием; предпросмотр анкеты |
| Шаблоны | Загрузка DOCX, версии, сверка переменных, пробная сборка на тестовых ответах |
| Промпты | Текст, версия, параметры, пробный запуск; откат на прошлую версию |
| Модели ИИ | Провайдеры, ключи, приоритет, включение, таймаут, цена токенов, дневной лимит, кнопка «проверить» |
| Журнал ИИ | Все запросы с цепочкой попыток, фильтры, расход |
| Тарифы | Лимиты и цены |
| Пользователи | Профиль, дела, платежи, блокировка, выдача доступа вручную |
| Дела | Список с фильтрами по статусу и сроку, история, документы |
| Платежи | Статусы, возвраты, подписки |
| Блог и страницы | Статьи, оферта, политика |
| Настройки | Тексты уведомлений, производственный календарь, счётчик Метрики |
Роли: владелец, редактор, поддержка. Вход в админку — с двухфакторной проверкой. Изменения ситуаций, шаблонов, промптов и тарифов пишутся в журнал действий: кто, что и когда поменял.
sitemap.xml и robots.txt собираются автоматически; черновики и служебные страницы закрыты от индексации.nginx раздача статики, HTTPS app PHP 8.3-FPM, Laravel 12 horizon очереди: ai, docs, notify, default scheduler напоминания, сверка платежей, продление подписок postgres PostgreSQL 16 redis очереди, кеш, предохранители моделей gotenberg DOCX → PDF
.env на сервере, в репозитории их нет.| Область | Требование |
|---|---|
| Скорость | Публичная страница — ответ сервера до 300 мс из кеша. Документ при работающей основной модели — до 30 секунд от отправки анкеты. |
| Нагрузка | 50 одновременных сборок проходят через очередь без ошибок; число обработчиков настраивается. |
| Безопасность | Пользователь видит только свои дела и файлы; защита форм от подделки запросов; ограничение частоты на вход, сборку и оплату; подписанные ссылки на файлы; шифрование чувствительных полей в базе. |
| 152-ФЗ | Данные хранятся в России; согласие и политика; удаление по запросу; в логах и в запросах к ИИ персональных данных нет. Уведомление Роскомнадзора подаёт заказчик как оператор. |
| Код | PSR-12, автоформатирование, статический анализ, миграции и сиды с демо-данными, ежедневные коммиты в репозиторий заказчика, README с запуском, деплоем и восстановлением. |
| Тесты | Автотесты на то, что дорого ломать: цепочка моделей и предохранитель, сборка шаблона с условными блоками, расчёт срока в рабочих днях, обработка уведомлений ЮKassa, списание лимита. |
| Браузеры | Две последние версии Chrome, Яндекс Браузера, Safari и Firefox, включая мобильные. |
Каждый этап принимается на тестовом сервере по списку ниже и оплачивается через безопасную сделку Kwork.
| Этап | Что сдаётся | Как проверить | Цена |
|---|---|---|---|
| 1. Каркас дни 1–3 | Репозиторий, Docker Compose, тестовый сервер, деплой. Вход по коду. Админка: категории, ситуации, анкеты, SEO-поля. Главная, каталог, страница ситуации, оферта, политика, sitemap. | Ситуация, созданная в админке, появляется в каталоге со своими SEO-полями. Вход по коду из письма работает. Проект поднимается по README одной командой. | 24 000 ₽ |
| 2. Ядро дни 4–8 | Мастер. ИИ-слой с тремя драйверами, автопереключение, журнал, расходы, промпты в админке. Шаблоны DOCX, PDF, проверка реквизитов, правка в браузере. | Три ситуации проходят путь от текста до DOCX и PDF. При выключенной основной модели документ собирается, в журнале видно переключение и стоимость. При выключенных всех — документ собирается по шаблону. | 42 000 ₽ |
| 3. Кабинет дни 9–12 | Дела, сроки, напоминания по e-mail и в Telegram, вход через Telegram, следующий документ. ЮKassa: разовая покупка, подписка, лимиты. | Тестовый платёж открывает скачивание, повторное уведомление не начисляет дважды. Напоминание приходит в оба канала. «Ответ не пришёл» предлагает следующий документ с перенесёнными данными. | 36 000 ₽ |
| 4. Сдача дни 13–14 | Заготовка блога, Метрика с целями, бэкапы, перенос на боевое окружение, README, исправления по итогам приёмки. | Боевой сайт работает. Бэкап восстановлен на тестовом окружении. Цели видны в Метрике. | 18 000 ₽ |
| Итого | 14 дней, затем 30 дней бесплатных исправлений | 120 000 ₽ | |
| К началу этапа | Что |
|---|---|
| 1 | Доступ к репозиторию и серверу, домен, почтовый сервис. Список ситуаций на старт. |
| 2 | Ключи YandexGPT и GigaChat, данные резервного провайдера. Шаблоны и анкеты минимум для трёх ситуаций. |
| 3 | Тестовый магазин ЮKassa, токен Telegram-бота, тарифы и лимиты. |
| 4 | Счётчик Метрики, хранилище для бэкапов, тексты оферты и политики, остальные шаблоны. |
| Риск | Что с ним делаем |
|---|---|
| Плотный срок — 14 дней | Материалы и доступы приходят к началу этапа по таблице выше. Задержка материалов сдвигает срок этапа на столько же дней. |
| Одобрение автоплатежей в ЮKassa | Подписка сдаётся на тестовом магазине, в боевом включается после одобрения. |
| PDF отличается от DOCX | Оба файла из одного шаблона, шрифты установлены в контейнер, пробная сборка в админке показывает результат до публикации шаблона. |
| Ошибки нейросети | Нормы и требования только из шаблона, ответ проверяется по схеме, пользователь видит и правит текст до скачивания. |
| Все модели недоступны | Сервис продолжает выдавать документы по шаблону, запрос доделывается из очереди. |
| Юридическая точность шаблонов | Тексты готовит и утверждает заказчик; сервис отвечает за точную подстановку. |