14 KiB
Промпт для ИИ: Перенос паттерна Прайслист
Используй этот документ как промпт для ИИ при переносе реализации прайслиста в другой проект.
Задача
Я имею рабочую реализацию окна "Прайслист" в проекте QuoteForge. Нужно перенести эту реализацию в проект [ДОП_ПРОЕКТ_НАЗВАНИЕ], сохраняя структуру, логику и UI/UX.
Что перенести
Frontend - Лист прайслистов (/pricelists)
Файл источник: QuoteForge/web/templates/pricelists.html
Компоненты:
-
Таблица - список прайслистов с колонками:
- Версия (монофонт)
- Тип (estimate/warehouse/competitor)
- Дата создания
- Автор (обычно "sync")
- Позиций (количество товаров)
- Исп. (использований)
- Статус (зеленый "Активен" / серый "Неактивен")
- Действия (Просмотр, Удалить если не используется)
-
Пагинация - навигация по страницам с активной страницей выделена
-
Модальное окно - "Создать прайслист" (если есть прав на запись)
Что копировать:
- HTML структуру таблицы из lines 10-30
- JavaScript функции:
loadPricelists(page)- загрузка спискаrenderPricelists(items)- рендер таблицыrenderPagination(total, page, perPage)- пагинацияcheckPricelistWritePermission()- проверка прав- Модальные функции:
openCreateModal(),closeCreateModal(),createPricelist()
- CSS классы Tailwind (скопируются как есть)
Где использовать в дочернем проекте:
- URL:
/pricelists(или адаптировать под ваши маршруты) - API:
GET /api/pricelists?page=1&per_page=20
Frontend - Детали прайслиста (/pricelists/:id)
Файл источник: QuoteForge/web/templates/pricelist_detail.html
Компоненты:
-
Хлебная крошка - кнопка назад на список
-
Инфо-панель - сводка по прайслисту:
- Версия (монофонт)
- Дата создания
- Автор
- Позиций (количество)
- Использований (в скольких конфигах)
- Статус (зеленый/серый)
- Истекает (дата или "-")
-
Таблица товаров - с поиском и пагинацией:
- Артикул (монофонт, lot_name)
- Категория (извлекается первая часть до "_")
- Описание (обрезается до 60 символов с "...")
- [УСЛОВНО] Доступно (qty) - только для warehouse источника
- [УСЛОВНО] Partnumbers - только для warehouse источника
- Цена, $ (с 2 знаками после запятой)
- Настройки (аббревиатуры: РУЧН, Сред, Взвеш.мед, периоды (1н, 1м, 3м, 1г), коэффициент, МЕТА)
-
Поиск - дебаунс 300мс, поиск по lot_name
-
Динамические колонки - qty и partnumbers скрываются/показываются в зависимости от source (warehouse или нет)
Что копировать:
- HTML структуру из lines 4-78
- JavaScript функции:
loadPricelistInfo()- загрузка деталей прайслистаloadItems(page)- загрузка товаровrenderItems(items)- рендер таблицы товаровrenderItemsPagination(total, page, perPage)- пагинация товаровisWarehouseSource()- проверка источникаtoggleWarehouseColumns()- показать/скрыть conditional колонкиformatQty(qty)- форматирование количестваformatPriceSettings(item)- форматирование строки настроекescapeHtml(text)- экранирование HTML- Debounce для поиска (lines 300-306)
- CSS классы Tailwind
- Логику conditional колонок (lines 152-164)
Где использовать в дочернем проекте:
- URL:
/pricelists/:id - API:
GET /api/pricelists/:idGET /api/pricelists/:id/items?page=1&per_page=50&search=...
Backend - Handler
Файл источник: QuoteForge/internal/handlers/pricelist.go
Методы для реализации:
-
List (lines 23-89)
- Параметры:
page,per_page,source(фильтр),active_only - Логика:
- Получить все прайслисты
- Отфильтровать по source (case-insensitive)
- Отсортировать по CreatedAt DESC (свежее сверху)
- Пагинировать
- Для каждого: посчитать товары (CountLocalPricelistItems), использования (IsUsed)
- Вернуть JSON с полями: id, source, version, created_by, item_count, usage_count, is_active, created_at, synced_from
- Параметры:
-
Get (lines 92-116)
- Параметр:
id(uint из URL) - Логика:
- Получить прайслист по ID
- Вернуть его детали (id, source, version, item_count, is_active, created_at)
- 404 если не найден
- Параметр:
-
GetItems (lines 119-181)
- Параметры:
id(URL),page,per_page,search(query) - Логика:
- Получить прайслист по ID
- Получить товары этого прайслиста
- Фильтровать по lot_name LIKE search (если передан)
- Посчитать total
- Пагинировать
- Для каждого товара: извлечь категорию из lot_name (первая часть до "_")
- Вернуть JSON: source, items (id, lot_name, price, category, available_qty, partnumbers), total, page, per_page
- Параметры:
-
GetLotNames (lines 183-211)
- Параметр:
id(URL) - Логика:
- Получить все lot_names из этого прайслиста
- Отсортировать alphabetically
- Вернуть JSON: lot_names (array of strings), total
- Параметр:
-
GetLatest (lines 214-233)
- Параметр:
source(query, default "estimate") - Логика:
- Нормализовать source (case-insensitive)
- Получить самый свежий прайслист по этому source
- Вернуть его детали
- 404 если не найден
- Параметр:
Регистрация маршрутов:
pricelists := api.Group("/pricelists")
{
pricelists.GET("", handler.List)
pricelists.GET("/latest", handler.GetLatest)
pricelists.GET("/:id", handler.Get)
pricelists.GET("/:id/items", handler.GetItems)
pricelists.GET("/:id/lots", handler.GetLotNames)
}
Адаптация для другого проекта
Что нужно изменить
-
Источник данных
- QuoteForge использует local DB (LocalPricelist, LocalPricelistItem)
- В вашем проекте: замените на ваши структуры/таблицы
- Сущность "прайслист" может называться по-другому
-
API маршруты
/api/pricelists→ ваш путь:id- может быть UUID вместо int, адаптировать parsing
-
Имена полей
- Если у вас нет поля
version- используйте ID или дату - Если нет
source- опустить фильтр - Если нет
IsUsed- считать как всегда 0
- Если у вас нет поля
-
Структуры данных
- Pricelist должна иметь: id, name/version, created_at, source, item_count
- PricelistItem должна иметь: id, lot_name, price, available_qty, partnumbers
-
Условные колонки
- Логика: если source == "warehouse", показать qty и partnumbers
- Адаптировать под ваши источники/типы
Что копировать как есть
- HTML структура - таблицы, модали, классы Tailwind
- JavaScript логика - все функции загрузки, рендера, пагинации
- CSS классы - Tailwind работает везде одинаково
- Форматирование функций - formatPrice, formatQty, formatDate
Пошаговая инструкция для ИИ
-
Прочитай оба файла:
- QuoteForge/web/templates/pricelists.html (список)
- QuoteForge/web/templates/pricelist_detail.html (детали)
- QuoteForge/internal/handlers/pricelist.go (backend)
-
Определи структуры данных в дочернем проекте:
- Какая таблица хранит "прайслисты"?
- Какие у неё поля?
- Как связаны товары?
-
Адаптируй Backend:
- Скопируй методы Handler
- Замени DB вызовы на вызовы вашего хранилища
- Замени имена полей в JSON ответах если нужно
- Убедись, что API возвращает нужный формат
-
Адаптируй Frontend - Список:
- Скопируй HTML таблицу
- Скопируй функции load/render/pagination
- Замени маршруты
/pricelists→ ваши - Замени API endpoint → ваш
- Протестируй список загружается
-
Адаптируй Frontend - Детали:
- Скопируй HTML для деталей
- Скопируй функции loadInfo/loadItems/render
- Замени маршруты и endpoints
- Особое внимание на conditional колонки (toggleWarehouseColumns)
- Протестируй поиск работает
-
Протестируй:
- Список загружается
- Пагинация работает
- Детали открываются
- Поиск работает
- Conditional колонки показываются/скрываются правильно
- Форматирование цен и дат работает
Пример адаптации
Backend (было):
func (h *PricelistHandler) List(c *gin.Context) {
localPLs, err := h.localDB.GetLocalPricelists()
// ...
}
Backend (стало):
func (h *CatalogHandler) List(c *gin.Context) {
catalogs, err := h.service.GetAllCatalogs(page, perPage)
// ...
}
Frontend (было):
const resp = await fetch(`/api/pricelists?page=${page}&per_page=20`);
Frontend (стало):
const resp = await fetch(`/api/catalogs?page=${page}&per_page=20`);
Качество результата
Когда закончишь:
- ✅ Список и детали выглядят идентично QuoteForge
- ✅ Все функции работают (load, render, pagination, search, conditional columns)
- ✅ Обработка ошибок (404, empty list, network errors)
- ✅ Таблицы с Tailwind классами оформлены одинаково
- ✅ Форматирование чисел/дат совпадает
Вопросы для ИИ
Перед тем как давать этот промпт, ответь на эти вопросы:
-
Какие у тебя структуры данных для "прайслиста"?
- Пример: какие поля, как называется таблица
-
Какие API endpoints уже есть?
- Или нужно создать с нуля?
-
Есть ли уже разница в источниках (estimate/warehouse)?
- Или все одного типа?
-
Нужна ли возможность создавать прайслисты?
- Или только просмотр?
Чеклист для проверки
После переноса проверь:
- Backend: List возвращает правильный JSON
- Backend: Get возвращает детали
- Backend: GetItems возвращает товары с поиском
- Frontend: Список загружается на
/pricelists - Frontend: Клик на прайслист открывает
/pricelists/:id - Frontend: Таблица на детальной странице рендеритсяся
- Frontend: Поиск работает с дебаунсом
- Frontend: Пагинация работает
- Frontend: Conditional колонки показываются/скрываются
- Frontend: Форматирование цен работает (2 знака)
- Frontend: Форматирование дат работает (ru-RU)
- UI: Выглядит идентично QuoteForge