231 lines
9.7 KiB
Markdown
231 lines
9.7 KiB
Markdown
# Бизнес-требования: Портал приложений (apps.mva154.duckdns.org)
|
||
|
||
## 1. Проблема
|
||
|
||
Сейчас веб-приложения разбросаны по разным адресам:
|
||
• `openclaw.mva154.duckdns.org/noisemap/`
|
||
• `openclaw.mva154.duckdns.org/snowbike-rag/`
|
||
• и т.д.
|
||
|
||
Нет единой точки входа. При добавлении нового приложения нужно править конфиг nginx.
|
||
|
||
---
|
||
|
||
## 2. Что хотим получить
|
||
|
||
Страницу-портал по адресу `apps.mva154.duckdns.org`, на которой отображаются кнопки/карточки наших приложений. Нажал — перешёл на нужное приложение.
|
||
|
||
**Главное требование:** добавление нового приложения — это только добавление строки в конфиг-файл приложения, без правки nginx.
|
||
|
||
---
|
||
|
||
## 3. Функциональные требования
|
||
|
||
### 3.1 Главная страница
|
||
• Адрес: `apps.mva154.duckdns.org`
|
||
• Сетка карточек приложений (grid, 2–4 колонки на десктопе, 1 колонка на мобильном)
|
||
• Каждая карточка:
|
||
- Иконка (emoji или SVG)
|
||
- Название приложения
|
||
- Краткое описание (1 строка)
|
||
- Клик → переход на приложение
|
||
|
||
### 3.2 Карточки приложений
|
||
• Приложения загружаются из JSON-конфига (не из кода)
|
||
• Новые приложения добавляются в конфиг — портал обновляется автоматически
|
||
• Порядок: из конфига (поле `order`)
|
||
• Активные/неактивные: поле `enabled: true/false` — скрыть если false
|
||
|
||
### 3.3 Навигация
|
||
• Клик по карточке → переход на URL приложения
|
||
• Открывается в той же вкладке (или в новой — настройка в конфиге)
|
||
• URL приложений — относительные пути на `openclaw.mva154.duckdns.org`
|
||
|
||
---
|
||
|
||
## 4. Архитектура
|
||
|
||
### 4.1 Схема
|
||
|
||
```
|
||
apps.mva154.duckdns.org
|
||
│
|
||
▼
|
||
Nginx (location /)
|
||
│
|
||
▼
|
||
Flask (порт 5560) ← читает config.json
|
||
│
|
||
▼
|
||
HTML (карточки приложений)
|
||
│
|
||
▼
|
||
Клик → переход на openclaw.mva154.duckdns.org/{путь}
|
||
```
|
||
|
||
### 4.2 Конфиг приложений
|
||
|
||
Файл: `config/apps.json`
|
||
|
||
```json
|
||
[
|
||
{
|
||
"id": "noisemap",
|
||
"name": "Карта шума",
|
||
"description": "Карта шумового загрязнения от авиации",
|
||
"icon": "🛩️",
|
||
"url": "https://openclaw.mva154.duckdns.org/noisemap/",
|
||
"enabled": true,
|
||
"order": 1
|
||
},
|
||
{
|
||
"id": "snowbike-rag",
|
||
"name": "Snowbike Поиск",
|
||
"description": "Семантический поиск по базе знаний сноубайков",
|
||
"icon": "🏔️",
|
||
"url": "https://openclaw.mva154.duckdns.org/snowbike-rag/",
|
||
"enabled": true,
|
||
"order": 2
|
||
}
|
||
]
|
||
```
|
||
|
||
**Поля:**
|
||
• `id` — уникальный ID (используется для имени файла аватарки)
|
||
• `name` — название
|
||
• `description` — описание
|
||
• `icon` — emoji для аватарки (используется при генерации)
|
||
• `url` — ссылка на приложение
|
||
• `enabled` — показывать на портале
|
||
• `order` — порядок сортировки
|
||
• `avatar` — (опционально) путь к кастомной аватарке; если отсутствует — генерируется автоматически
|
||
|
||
### 4.3 Добавление нового приложения
|
||
|
||
1. Добавить строку в `config/apps.json`
|
||
2. При первом запуске Flask автоматически сгенерирует аватарку в `static/avatars/{id}.png`
|
||
3. Готово — портал показывает новое приложение
|
||
|
||
**НЕ нужно:**
|
||
• Править nginx
|
||
• Перезапускать Flask (конфиг перечитывается при старте)
|
||
• Создавать аватарку вручную
|
||
|
||
---
|
||
|
||
## 5. Требования к дизайну
|
||
|
||
### 5.1 Стиль
|
||
• Светлая тема (по мотивам snowbike-rag, но светлее)
|
||
• Фон: #F8FAFC (светло-серый)
|
||
• Карточки: белые (#FFFFFF), скруглённые углы (16px), лёгкая тень
|
||
• Шрифт: Inter
|
||
• Акцентный цвет: #3B82F6 (синий)
|
||
• Текст: #0F172A (тёмный)
|
||
|
||
### 5.2 Карточка приложения
|
||
|
||
```
|
||
┌────────────────────────┐
|
||
│ │
|
||
│ ┌──────────┐ │
|
||
│ │ аватарка │ │
|
||
│ │ 80×80 │ │
|
||
│ └──────────┘ │
|
||
│ │
|
||
│ Название приложения │
|
||
│ Краткое описание │
|
||
│ │
|
||
└────────────────────────┘
|
||
```
|
||
|
||
• Аватарка: квадратная, скруглённая (12px), 80×80px, по центру карточки
|
||
• Название: жирный шрифт, 18px, тёмный
|
||
• Описание: обычный шрифт, 14px, серый (#64748B)
|
||
• Hover: подсветка рамки синим, lift-эффект (тень), масштаб 1.02
|
||
• Аватарка — первое что бросается в глаза
|
||
|
||
### 5.3 Аватарки приложений
|
||
|
||
**Автоматическая генерация при добавлении нового приложения:**
|
||
|
||
При добавлении строки в `config/apps.json` Flask автоматически генерирует аватарку, если файл не существует.
|
||
|
||
**Способ генерации:**
|
||
• Градиентный фон (по хэшу названия приложения → уникальный цвет)
|
||
• По центру — первая буква названия или emoji иконка (крупно, белым цветом)
|
||
• Сохраняется в `static/avatars/{app_id}.png`
|
||
• Генерация: Python PIL/Pillow (без внешних API)
|
||
• Размер: 200×200px (масштабируется в CSS)
|
||
|
||
**Примеры:**
|
||
```
|
||
🛩️ на синем градиенте → «Карта шума»
|
||
🏔️ на зелёном градиенте → «Snowbike Поиск»
|
||
🔍 на оранжевом градиенте → «Портал поиска»
|
||
```
|
||
|
||
**Правила:**
|
||
• Если в конфиге указано поле `avatar` — используется указанное изображение
|
||
• Если `avatar` отсутствует — генерируется автоматически
|
||
• Цвет градиента определяется по хэшу `name` (детерминированно — всегда одинаковый для одного названия)
|
||
• Формат: PNG, 200×200px
|
||
|
||
### 5.4 Заголовок
|
||
• Название портала: «Мои приложения»
|
||
• Подзаголовок: «N активных приложений»
|
||
• Светлый фон, тёмный текст
|
||
|
||
### 5.5 Адаптивность
|
||
• Десктоп: 3–4 колонки
|
||
• Планшет: 2 колонки
|
||
• Мобильный: 1 колонка
|
||
|
||
---
|
||
|
||
## 6. Технические требования
|
||
|
||
### 6.1 Стек
|
||
• Flask (порт 5560)
|
||
• HTML + CSS + JS (один файл, inline)
|
||
• Tailwind CSS через CDN
|
||
• Google Fonts (Inter) через CDN
|
||
|
||
### 6.2 Nginx
|
||
• Домен `apps.mva154.duckdns.org` → location `/` → proxy_pass `http://172.19.0.2:5560/`
|
||
• Один location block, без правок при добавлении приложений
|
||
• SSL через Certbot (как у основного домена)
|
||
|
||
### 6.3 Flask
|
||
• `GET /` — главная страница (рендерит HTML из конфига)
|
||
• `GET /api/apps` — JSON-список приложений (для отладки)
|
||
• Конфиг: `config/apps.json`
|
||
|
||
---
|
||
|
||
## 7. Что НЕ входит
|
||
|
||
• Авторизация
|
||
• Админка для добавления приложений (через JSON-файл)
|
||
• Мониторинг статуса приложений (online/offline)
|
||
• Уведомления о новых приложениях
|
||
|
||
---
|
||
|
||
## 8. Критерии приёмки
|
||
|
||
✅ Открывается `apps.mva154.duckdns.org` — видно карточки приложений
|
||
✅ Клик по карточке — переход на нужное приложение
|
||
✅ Добавил строку в `apps.json` — портал показывает новое приложение с аватаркой
|
||
✅ Аватарка генерируется автоматически (градиент + emoji)
|
||
✅ НЕ нужно править nginx для нового приложения
|
||
✅ Хорошо выглядит на телефоне
|
||
✅ Светлая тема, похожая на snowbike-rag
|
||
|
||
---
|
||
|
||
## 9. Приоритет
|
||
|
||
**Сейчас:** Главная страница + карточки + автогенерация аватарок
|
||
**Позже:** Анимации, кастомные аватарки, мониторинг статуса
|