diff --git a/agent-ctx/9-11-api-pages.md b/agent-ctx/9-11-api-pages.md deleted file mode 100644 index 62cffcb..0000000 --- a/agent-ctx/9-11-api-pages.md +++ /dev/null @@ -1,28 +0,0 @@ -# Task 9-11 — All Remaining API Routes & Page Components - -**Status**: Completed - -## Files Created - -### API Routes (4 new) -1. `src/app/api/purchases/bulk/route.ts` — GET paginated purchases with user/product includes, status filter -2. `src/app/api/audit/bulk/route.ts` — GET paginated audit log, ordered by id DESC -3. `src/app/api/settings/route.ts` — GET hardcoded settings, PUT accept key/value -4. `src/app/api/locales/route.ts` — GET hardcoded 3-language demo data, PUT accept lang/key/value -5. `src/app/api/seed/data/route.ts` — GET check if DB has data -6. `src/app/api/seed/demo/route.ts` — POST seed demo data with reauth, clears first then seeds -7. `src/app/api/seed/clear/route.ts` — POST clear all tables with reauth, resets autoincrement - -### Page Components (7 new) -1. `src/components/purchases/purchases-page.tsx` — Status filter tabs, paginated table with copy-hash, user links -2. `src/components/audit/audit-page.tsx` — Color-coded action badges, collapsible JSON details, pagination -3. `src/components/categories/categories-page.tsx` — CRUD dialog, location select grouped, switch toggle, delete protection -4. `src/components/locations/locations-page.tsx` — CRUD dialog, switch toggle, delete protection with category check -5. `src/components/settings/settings-page.tsx` — Sectioned settings, masked secrets, per-field save, restart warning -6. `src/components/locales/locales-page.tsx` — Inline-editable table, section headers with rowSpan, blur-to-save -7. `src/components/seed/seed-page.tsx` — Super admin gate, danger cards, reauth AlertDialog, DB status indicator - -## Notes -- Categories and Locations APIs already existed from catalog agent (Task 6) -- All ESLint clean, 0 errors -- Pre-existing dev.log error (admin-header.tsx import) is unrelated \ No newline at end of file diff --git a/agent-ctx/new-features-2-main-coordinator.md b/agent-ctx/new-features-2-main-coordinator.md deleted file mode 100644 index 17ae314..0000000 --- a/agent-ctx/new-features-2-main-coordinator.md +++ /dev/null @@ -1,18 +0,0 @@ -# Task ID: new-features-2 -## Agent: Main Coordinator -## Task: Activity Feed, Export Button, Sortable Header, Clipboard Utility, Integration - -### Files Created -- `src/components/layout/activity-feed.tsx` — ActivityFeed component (fetches audit/bulk, 30s refresh, color-coded icons, relative time) -- `src/components/shared/export-button.tsx` — ExportButton component (CSV export via DropdownMenu, Blob download) -- `src/components/shared/sortable-header.tsx` — SortableHeader component (3-state sort toggle with arrow icons) -- `src/lib/clipboard.ts` — copyToClipboard utility (navigator.clipboard + textarea fallback) - -### Files Modified -- `src/components/dashboard/dashboard-page.tsx` — Replaced inline activity feed with ActivityFeed, removed unused imports/types -- `src/components/purchases/purchases-page.tsx` — Added ExportButton, SortableHeader (date/amount/status), client-side sort, clipboard util -- `src/components/audit/audit-page.tsx` — Added ExportButton, SortableHeader (action/date), client-side sort -- `src/components/users/users-page.tsx` — Added ExportButton next to search input - -### Lint Result -- ESLint: 0 errors, 0 warnings diff --git a/tool-results/read_1785928170713_f437b7015628.txt b/tool-results/read_1785928170713_f437b7015628.txt deleted file mode 100644 index 882d3dd..0000000 --- a/tool-results/read_1785928170713_f437b7015628.txt +++ /dev/null @@ -1,751 +0,0 @@ - 1→# Админ-панель Telegram Shop — Техническое описание фронтенда и API - 2→ - 3→> **Назначение документа**: комплексное ТЗ для отдела фронтенда по реализации полноценного админ-кабинета поверх существующего бэкенда. - 4→> **Версия бэкенда**: v1.2.4 (2026-08-05) - 5→> **Дата**: 2026-08-05 - 6→> **Статус**: актуально на момент передачи - 7→ - 8→--- - 9→ - 10→## Оглавление - 11→ - 12→1. [Обзор системы](#1-обзор-системы) - 13→2. [Технологический стек](#2-технологический-стек) - 14→3. [Архитектура развёртывания](#3-архитектура-развёртывания) - 15→4. [Доступ и безопасность](#4-доступ-и-безопасность) - 16→5. [Схема базы данных](#5-схема-базы-данных) - 17→6. [Карта эндпоинтов (полная)](#6-карта-эндпоинтов-полная) - 18→7. [Спецификация экранов](#7-спецификация-экранов) - 19→8. [Роли и права](#8-роли-и-права) - 20→9. [Формат данных](#9-формат-данных) - 21→10. [Существующие ограничения и подводные камни](#10-существующие-ограничения-и-подводные-камни) - 22→11. [Требования к новому фронтенду](#11-требования-к-новому-фронтенду) - 23→12. [API-контракты JSON (дополнить бэкенду)](#12-api-контракты-json-дополнить-бэкенду) - 24→13. [Чек-лист приёмки](#13-чек-лист-приёмки) - 25→ - 26→--- - 27→ - 28→## 1. Обзор системы - 29→ - 30→Telegram Shop — это **Telegram-бот-магазин** (Node.js) с **встроенной админ-панелью** на Express + EJS (шаблон SmartAdmin). Продажи идут через Telegram-бота, админка управляет всем магазином через браузер. - 31→ - 32→Бизнес-сущности: - 33→ - 34→| Сущность | Описание | - 35→|---|---| - 36→| **Users** | Покупатели из Telegram (id, ник, локация, статус, балансы, язык) | - 37→| **Locations** | Гео-иерархия: Страна → Город → Район (округа) | - 38→| **Categories / Subcategories** | Категории товаров, привязанные к локации; подкатегории внутри категории | - 39→| **Products** | Товары: цена, остаток, публичное фото, скрытый контент (фото/координаты/описание), private-заметки, цифровые (mono) | - 40→| **Purchases** | Заказы: пользователь, товар, валюта, tx_hash, количество, сумма, статус | - 41→| **Crypto Wallets** | Криптокошельки пользователей (BTC/LTC/ETH/USDT/USDC), с зашифрованными seed-фразами | - 42→| **Transactions** | Ончейн-транзакции пользователей | - 43→| **Commission payments** | Платежи комиссии владельцу платформы (SaaS-модель) | - 44→| **Audit log** | Журнал действий админов | - 45→| **Locales (i18n)** | JSON-файлы переводов бота (en/es/de), редактируются из админки | - 46→ - 47→**Ключевой факт**: бот и админка живут в **одном процессе** и используют **одну SQLite-базу** (`db/shop.db`) — поэтому любые изменения в админке мгновенно видны боту и наоборот. Отдельного REST API **нет** — админка рендерит EJS на сервере и ходит в БД напрямую. - 48→ - 49→--- - 50→ - 51→## 2. Технологический стек - 52→ - 53→### Текущий (серверная часть — НЕ трогать без отдельной задачи) - 54→ - 55→| Слой | Технология | - 56→|---|---| - 57→| Язык | Node.js ≥ 18 (ES Modules, `"type": "module"`) | - 58→| Web-фреймворк | Express 4 | - 59→| Шаблонизация | EJS + `express-ejs-layouts` (layout: `views/layout.ejs`) | - 60→| Шаблон UI | SmartAdmin (собственные партиалы в `views/partials/`, SCSS в `public/sass/`, сборка `smartapp.min.css`) | - 61→| БД | SQLite через `better-sqlite3` (обёртка `db.runAsync/allAsync/getAsync` в `src/config/database.js`) | - 62→| Загрузка файлов | Multer (только картинки jpeg/png/webp/gif, ≤ 10 МБ) в `uploads/` | - 63→| QR | `qrcode` (для seed-фраз) | - 64→| CDN-ресурсы | Bootstrap 5.3.2, FontAwesome 6.4.2 с jsDelivr (только в legacy-`layout.js`) | - 65→ - 66→### Текущий фронтенд (что есть) - 67→ - 68→- **Два параллельных набора вьюх**: - 69→ 1. **EJS-шаблоны** (`views/*.ejs`) — используются роутами (dashboard, users, wallets, purchases, audit, settings, categories, locations, payment-wallets, seed, locales, catalog, products, product-edit, user-detail). - 70→ 2. **JS-рендер-функции** (`views/*.js`) — legacy/дублирующий слой, возвращающий HTML-строки (`layout()`, `renderCatalog()`, `renderWalletLayout()` и т.д.). **На практике роуты рендерят EJS; JS-слой частично устарел** (дублирует catalog и wallets). Новый фронтенд их не использует. - 71→- Статика: Bootstrap 5 (SmartAdmin-тема), ApexCharts, jQuery, FontAwesome, собственные скрипты `public/scripts/`. - 72→- AJAX-вызовы есть только в нескольких местах (catalog-модалка, wallets-обновление балансов, locales). - 73→ - 74→--- - 75→ - 76→## 3. Архитектура развёртывания - 77→ - 78→``` - 79→Internet - 80→ │ - 81→ ├── HTTPS/LAN ───────────────► telegram_shop_prod :3001 (Express: бот + админка) - 82→ │ - 83→ └── Tor Network ──► tor-proxy ──► HiddenService :80 ──► telegram_shop_prod :3001 - 84→ (admin onion-адрес, работа без HTTPS) - 85→``` - 86→ - 87→- Единственный контейнер `telegram_shop_prod` (node:22-alpine) слушает порт `3001` (`ADMIN_PORT`). - 88→- Доступ к админке: напрямую `http://host:3001` или через `.onion` (Tor Browser). - 89→- Volume: `db/` (SQLite), `uploads/` (фото товаров, отдаются через `/uploads`), `.env` (только чтение). - 90→- WireGuard опционален (`WG_ENABLED`). - 91→ - 92→**Следствие для фронтенда**: админка доступна по **HTTP без HTTPS** (в т.ч. через Tor). Это накладывает жёсткие ограничения: - 93→- нельзя использовать Secure-куки; - 94→- нельзя полагаться на Origin-проверку (Tor) — CSRF реализован вручную (см. §10); - 95→- весь JS/CSS должен быть либо локальным, либо закешированным (CDN может быть недоступен из Tor). - 96→ - 97→--- - 98→ - 99→## 4. Доступ и безопасность - 100→ - 101→### 4.1. Аутентификация (важно для фронта) - 102→ - 103→Реализована в `src/admin/auth.js`. **Не JWT, а самописный HMAC-токен**: - 104→ - 105→| Параметр | Значение | - 106→|---|---| - 107→| Кука | `admin_token` (httpOnly, `sameSite=false`, maxAge 24ч) | - 108→| Формат токена | `base64(payload).hmac_sha256(payload)` | - 109→| Payload | `{ role, jti, iat, exp }` | - 110→| Секрет | `ADMIN_SECRET` (env) | - 111→| Вход | POST `/login` с полем `token` (пароль = админ-токен) | - 112→| Выход | GET `/logout` | - 113→ - 114→Роли (определяются **каким секретом залогинились**): - 115→ - 116→| Роль | Условие | Права | - 117→|---|---|---| - 118→| `admin` | токен = `ADMIN_SECRET` | Все страницы, кроме seed-выгрузки | - 119→| `super_admin` | токен = `SUPER_ADMIN_SECRET` (если задан и ≠ ADMIN_SECRET) | + просмотр/экспорт seed-фраз, комиссии | - 120→ - 121→При `SUPER_ADMIN_SECRET` не заданном — **все админы считаются супер-админами** (`config.SUPER_ADMIN_IDS` по умолчанию = `ADMIN_IDS`, но роли в админке задаются именно через секреты, не через `ADMIN_IDS`). - 122→ - 123→Rate-limit логина: 5 попыток / 15 минут с IP. - 124→ - 125→**Деструктивные действия** (`/seed/*`) требуют повторного ввода токена в поле `reauth_token` (middleware `requireReAuth`). - 126→ - 127→### 4.2. Защита статики и загрузок - 128→ - 129→- `/uploads/*` — только после `requireAuth`, заголовки `X-Content-Type-Options: nosniff` + `Content-Disposition: attachment` (фото не рендерятся inline из uploads, только скачивание). - 130→- Файлы uploads именуются `{timestamp}-{hex}.{ext}`, MIME-белый список. - 131→- CSRF: заглушка (`csrf.js` возвращает пустой токен и no-op) — **сознательно отключено ради совместимости с Tor**. См. §10. - 132→ - 133→### 4.3. Существующие уязвимости, которые фронтенд не должен усугублять - 134→ - 135→1. Нет реальной CSRF-защиты — все POST-формы уязвимы к cross-site-запросам. В новом фронте использовать токены, если бэкенд их вернёт, иначе как минимум не убирать подтверждения на деструктив. - 136→2. Некоторые вьюхи выводят данные с ручным `esc()`/`escapeHtml()`; часть EJS использует `<%= %>` (экранируется) — но есть места с `JSON.stringify` прямо в `