diff --git a/README.md b/README.md new file mode 100644 index 0000000..6fbd938 --- /dev/null +++ b/README.md @@ -0,0 +1,244 @@ +# Вот промпт, который можно уложить в кодекс: +Ты — опытный senior full‑stack архитектор и разработчик. +Твоя задача — спроектировать и сгенерировать ПОЛНЫЙ каркас проекта +(backend + frontend + инфраструктура), который будет использоваться +для конвейера PDF→структурированный JSON→DOCX по шаблонам Word. + +ВАЖНО: +- Нужен готовый проект с понятной файловой структурой, рабочим билдом + и запуском в Docker. +- Нужна поддержка git: .gitignore, базовые скрипты, README. +- Шаблоны Word создавать НЕ нужно. Нужно предусмотреть каталог, + конфигурацию и код для их загрузки/использования, чтобы я мог сам + положить .docx и сразу ими пользоваться. +- Проект должен быть написан максимально понятно и аккуратно, с + комментариями в ключевых местах. + +--- + +## Технологический стек (можешь предлагать улучшения, но по умолчанию так): + +### Общие требования +- Ориентируемся на развёртывание в Linux‑среде, запуск через docker-compose. +- Backend и frontend запускаются в отдельных контейнерах. +- В перспективе backend будет общаться с локальной LLM (Qwen) через + OpenAI‑совместимый API на внешнем сервере (например, Ollama), + но до развёртывания этой модели мы будем ходить в облачную LLM. +- Поэтому нужна конфигурируемая переменная окружения + `LLM_BASE_URL` и `LLM_API_KEY`, а логика работы с LLM должна быть + изолирована в отдельном слое‑адаптере. + +### Backend +- Язык: TypeScript. +- Фреймворк: Node.js + NestJS ИЛИ Express + modular architecture + (если считаешь, что Nest избыточен, обоснуй в комментариях README). +- HTTP API (REST), без GraphQL. +- Работа с файлами: загружать PDF, временно хранить их на диске, + отдавать готовый DOCX, хранить метаданные задач в БД. +- База данных: PostgreSQL (через Prisma или TypeORM — выбери один и + задокументируй выбор). +- Логирование: простой логгер (winston/pino) с выводом в консоль. +- Конфигурация: через .env (используй библиотеку наподобие + dotenv / @nestjs/config). +- Поддержка CORS для фронтенда. + +### Frontend +- Язык: TypeScript. +- Фреймворк: React + Vite или Next.js (на твой выбор, но без SSR‑сложностей, + достаточно SPA, если берёшь Vite/React). +- UI‑задача: + - Страница с формой загрузки PDF: + - поле выбора файла; + - выбор типа документа/шаблона (просто select с dummy‑значениями + вроде "ГОСТ‑1", "ГОСТ‑2" — пока они только передаются на backend); + - кнопка «Отправить на обработку». + - Отображение списка задач: + - идентификатор задачи; + - имя исходного файла; + - статус (QUEUED / PROCESSING / DONE / ERROR); + - ссылка для скачивания результата, если есть DOCX. + - Простая страница деталей задачи (по id): + - метаданные; + - простой лог/ошибки, если были. +- Верстка может быть минимальной, без сложного дизайна, главное — + чистая архитектура и удобство доработки. + +--- + +## Бизнес‑логика, которую нужно учесть + +Цель системы: офисные сотрудники загружают PDF‑файл с технической документацией (ТЗ по ГОСТу и т.п.). +Backend: + +1. Принимает PDF и создаёт “задачу обработки” в БД. +2. Сохраняет PDF в файловой системе (например, каталог `storage/input`). +3. Отправляет PDF в отдельный n8n‑workflow ИЛИ обрабатывает локально + цепочкой шагов (сейчас — просто заглушка, позже я подвяжу n8n). +4. В перспективе pipeline будет такой: + - PDF → парсер (вытаскиваем текст/Markdown); + - Markdown → LLM (Qwen) → унифицированный JSON структуры документа; + - JSON + Word‑шаблон → генератор DOCX; + - результат сохраняем как DOCX в `storage/output`. + Но в рамках этого задания тебе нужно: + - СДЕЛАТЬ кодовые заготовки для этих шагов (интерфейсы, классы, + абстракции, контроллеры, DTO, сервисы), + - Реализовать «заглушки» (например, вместо реального вызова LLM и + генератора DOCX возвращать фиктивный JSON/файл), + - Чётко показать точки интеграции, где я потом подключу реальную + обработку. + +5. Backend должен предоставлять API: + - `POST /api/jobs` — загрузка PDF: + - multipart/form-data, поле `file`, опционально `templateType`. + - возвращает объект задачи `{ id, status, fileName, createdAt }`. + - `GET /api/jobs` — список задач (с пагинацией, query‑параметры). + - `GET /api/jobs/:id` — детальная информация о задаче, включая + путь/URL к результату, лог ошибок. + - `GET /api/jobs/:id/result` — скачивание готового DOCX. + - `GET /api/templates` — список доступных Word‑шаблонов (backend + должен сканировать папку `templates/` и возвращать названия файлов / + метаданные; сами .docx я положу вручную). + - `POST /api/templates/reload` — принудительное перечитывание списка + шаблонов (на будущее). + +6. Статусы задач: + - QUEUED, PROCESSING, DONE, ERROR. + - Нужен enum и таблица/модель `Job` с полями: + - id (uuid), + - originalFileName, + - storedFilePath, + - resultFilePath (nullable), + - status, + - errorMessage (nullable), + - templateType (строка), + - createdAt, updatedAt. + +7. Адаптер к LLM: + - Нужен отдельный сервис/модуль (например, `llm/llmClient.ts`), + который: + - берёт на вход текст/markdown и возвращает JSON структуры + документа (пока можно вернуть фиктивный JSON). + - конфигурируется через переменные окружения: + - `LLM_BASE_URL` — URL OpenAI‑совместимого API + (в будущем это будет адрес локального Qwen на сервере Ollama). + - `LLM_API_KEY` — токен для облачной модели (сейчас). + - `LLM_MODEL` — имя модели (например, `gpt-4.1-mini` или другое). + - Весь остальной код НЕ должен знать детали формата API конкретного + поставщика, только использовать этот клиент/адаптер. + +8. Адаптер генерации DOCX: + - Отдельный сервис (например, `docx/docxGenerator.ts`), который: + - принимает JSON структуры и имя шаблона; + - находит шаблон в папке `templates/` (но сам шаблон не создаёт); + - создаёт DOCX в `storage/output/.docx`. + - На этом этапе достаточно сделать заглушку: + - например, создать простой текстовый DOCX через любую + библиотеку (или даже временно создавать `.txt` файл, но + оставить интерфейс и структуру под DOCX). + - Важно: предусмотреть удобное место, куда я положу свои .docx + шаблоны, и в README описать, как они должны называться + и как выбираются. + +*** + +## Инфраструктура и структура проекта + +Пожалуйста, СГЕНЕРИРУЙ и ОПИШИ: + +1. Общая структура репозитория (monorepo или два отдельных проекта — opиши выбор). + Пример, если это monorepo: + - `backend/` + - `frontend/` + - `docker/` (общие конфиги) + - `templates/` (каталог для Word‑шаблонов) + - `storage/input/` (исходные PDF, .gitignore внутри) + - `storage/output/` (результирующие DOCX, .gitignore внутри) + - `README.md` + - `.gitignore` + - `docker-compose.yml` + +2. Файловая структура backend: + - `src/main.ts`, `src/app.module.ts` (для Nest) или аналог для Express. + - Модуль/пакет `jobs`: + - контроллер для API задач; + - сервис работы с задачами; + - DTO и entity/модель для БД. + - Модуль/пакет `files`: + - загрузка файлов; + - валидация типов; + - работа с путями хранения. + - Модуль/пакет `llm`: + - клиент для LLM; + - интерфейсы типов ответов. + - Модуль/пакет `docx`: + - генератор DOCX; + - адаптер к будущему шаблонизатору Docx (docxtemplater/Pandoc/и т.п.). + - Общий модуль `config` для работы с .env. + - Конфиг Prisma/TypeORM и миграции для таблицы `Job`. + +3. Файловая структура frontend: + - Точка входа и маршрут `/` с формой загрузки и списком задач. + - Компоненты: + - `UploadForm` + - `JobsList` + - `JobDetails` + - Сервис для общения с backend (например, `api/client.ts`), где: + - базовый URL API берётся из env (`VITE_API_BASE_URL` и т.п.). + - Простая система типов TypeScript для сущностей Job и Template. + +4. .gitignore: + - Исключить: + - node_modules, + - build‑артефакты, + - .env и другие секреты, + - `storage/input`, `storage/output`, + - временные файлы IDE. + +5. Docker: + - `Dockerfile` для backend. + - `Dockerfile` для frontend. + - `docker-compose.yml`, который поднимает: + - `backend` (с зависимостью от `db`); + - `frontend`; + - `db` (PostgreSQL); + - Переменные окружения для docker‑compose с примером (файл `.env.example`). + +6. README: + - Пошаговая инструкция: + - как установить зависимости; + - как запустить проект локально без Docker; + - как запустить через `docker-compose up`; + - как добавить новый Word‑шаблон (куда положить .docx, как он + подхватывается API `/api/templates`). + - Пример запроса к API загрузки файла (curl). + - Краткое объяснение архитектуры: + - где слой LLM‑адаптера; + - где слой генерации DOCX; + - как в будущем подключить n8n и локальную Qwen. + +*** + +## Формат ответа + +Сформируй ответ в три части: + +1. Краткое текстовое объяснение архитектуры (2–3 абзаца). +2. Подробная структура файлов/папок в формате дерева с комментариями. +3. Основные файлы кода как СНИППЕТЫ: + - `docker-compose.yml`; + - `backend/Dockerfile`, `frontend/Dockerfile`; + - key‑файлы backend (main, контроллер задач, модель Job, LLM‑клиент, + заглушка генератора DOCX); + - key‑файлы frontend (главная страница, клиент API); + - `.gitignore`; + - `.env.example`; + - выдержки из README с инструкциями. + +Код можно не доводить до идеального продакшена, но он должен быть: +- компилируемым, +- структурированным, +- с понятными комментариями, что и где доработать, чтобы подключить + реальную LLM и реальный генератор DOCX по шаблонам Word. + +Не упрощай задачу: сгенерируй именно полноценный каркас проекта, +как если бы ты начинал реальный коммерческий проект под эту задачу. \ No newline at end of file