Files
Avtex/scripts/create_npb_brief.cjs

228 lines
12 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const { Pool } = require('pg')
// XFlow DB (through SSH tunnel)
const DB_URL = 'postgresql://xflow:xflow_pass@localhost:5433/xflow'
const pool = new Pool({ connectionString: DB_URL })
const CANVAS_ID = 'npb-aipb-project-brief'
const CANVAS_NAME = '🎨 NPB/AIPB — Project Brief'
const OWNER_ID = 'GqbpMyUW0NaxjIy5nvCiXCiQu9t2'
// ─────────────────────────────────────────────
// NODES — merged from NPB.json + XFlow pre-prompt context
// ─────────────────────────────────────────────
const nodes = [
// ── CENTRAL NODE ──────────────────────────
{
id: 'main',
type: 'text',
x: -474, y: -603,
width: 450, height: 220,
label: '🎨 AIPB — AI Portrait Builder',
text: `# 🎨 AIPB\n\n**Генератор художественных портретов с ИИ.**\n\n- **Статус:** v1.1.0 Architecture\n- **Стек:** Nuxt 3, MediaPipe, Replicate, Firebase\n- **Концепт:** Парные экраны (Display + Remote)\n- **Фишка:** Управление жестами или с планшета`,
state: 'pending',
style: { background: '#1e293b', border: '#334155' }
},
// ── TECH STACK ────────────────────────────
{
id: 'tech-stack',
type: 'text',
x: -1049, y: -262,
width: 400, height: 380,
label: '🏗️ Tech Stack',
text: `# 🏗️ Стек AIPB\n\n- **Framework:** Nuxt 3 (SSR + Nitro)\n- **CV:** MediaPipe Hands (JS)\n- **AI APIs:** Replicate (SDXL), Face Swap\n- **Backend/Sync:** Firebase RTDB\n- **Auth:** Firebase Auth\n- **State:** Pinia + Firebase Listeners\n- **UI:** TailwindCSS + Animations`,
state: 'pending',
style: { background: '#1e293b', border: '#334155' }
},
// ── AUTH SYSTEM ───────────────────────────
{
id: 'auth-system',
type: 'text',
x: -1049, y: 180,
width: 400, height: 300,
label: '🔐 Auth Stack',
text: `# 🔐 Firebase Auth & Roles\n\n- **Admin:** Управление киосками, стата\n- **Kiosk (Service):** Авторизация самой точки\n- **Remote (Anonymous):** Временный токен для планшета\n- **Security:** Firebase Rules (доступ только к своей сессии)`,
state: 'pending',
style: { background: '#1e293b', border: '#334155' }
},
// ── DUAL DEVICE ───────────────────────────
{
id: 'dual-device',
type: 'text',
x: 100, y: -603,
width: 450, height: 320,
label: '📡 Синхронизация пар',
text: `# 📡 Dual-Device Sync\n\n- **Pairing:** Генерация PIN/QR кода на ПК\n- **Connection:** Сканирование с планшета\n- **Realtime:** Firebase RTDB для синхронизации State\n- **Latency:** <100ms отклик интерфейса`,
state: 'pending',
style: { background: '#0f766e', border: '#115e59' }
},
// ── KIOSK ARCHITECTURE ────────────────────
{
id: 'architecture',
type: 'text',
x: 600, y: -603,
width: 450, height: 350,
label: '🖥️ Kiosk Architecture',
text: `# 🖥️ Разделение UI\n\n**1. Display View (ТВ/ПК):**\n- Трансляция камеры\n- Красивые idle-анимации\n- Рендер ИИ и таймеров\n- QR-код для скачивания\n\n**2. Controller View (Планшет):**\n- Кнопки выбора (Пол, Стиль, Язык)\n- Кнопка спуска затвора\n- Ввод Email/Telegram`,
state: 'pending',
style: { background: '#0f766e', border: '#115e59' }
},
// ── USER FLOW ─────────────────────────────
{
id: 'user-flow',
type: 'text',
x: -128, y: 147,
width: 450, height: 400,
label: '🔄 User Flow (8 Steps)',
text: `# 🔄 Процесс генерации\n\n1. **Welcome** — Старт на планшете/жестом\n2. **Language** — Выбор языка\n3. **Gender** — Выбор пола (M/F)\n4. **Style** — Выбор стиля\n5. **Capture** — Фото с таймером (3с)\n6. **Confirm** — Проверка кадра на планшете\n7. **Loading** — Процесс ИИ генерации (на экране)\n8. **Result** — Сохранение и шеринг`,
state: 'pending',
style: { background: '#1e293b', border: '#334155' }
},
// ── GESTURE CONTROLS ──────────────────────
{
id: 'gestures',
type: 'text',
x: -566, y: -72,
width: 400, height: 300,
label: '👋 Gesture Controls',
text: `# 👋 Управление жестами\n\n- **✊ Fist:** Клик / Выбор\n- **✌️ V-sign:** Скролл вниз\n- **🖐️ Palm:** Пауза / Стоп\n\n*Альтернатива или дополнение к планшету*\n*Используется MediaPipe Hands (WASM в браузере)*`,
state: 'pending',
style: { background: '#1e293b', border: '#334155' }
},
// ── ROADMAP ───────────────────────────────
{
id: 'roadmap',
type: 'text',
x: 380, y: 147,
width: 400, height: 300,
label: '🚀 Roadmap',
text: `# 🚀 Планы (v1.2.0+)\n\n- [ ] Прямая интеграция с TG-ботом\n- [ ] Админ-панель со статистикой\n- [ ] Оффлайн фоллбэк для обрыва связи\n- [ ] Платные премиум-стили\n- [ ] Галерея работ сообщества`,
state: 'pending',
style: { background: '#1e293b', border: '#334155' }
},
// ── AI STYLES ─────────────────────────────
{
id: 'ai-styles',
type: 'text',
x: 850, y: 147,
width: 400, height: 320,
label: '🎭 AI Styles',
text: `# 🎭 Художественные стили\n\n- **Cinematic:** Кино-освещение\n- **Anime:** Стилизация под аниме\n- **Fantasy:** Магическая атмосфера\n- **Cyberpunk:** Неон и технологии\n- **Professional:** Студийное фото\n- **Artistic:** Масляная живопись\n\n*Провайдер: Replicate (SDXL)*`,
state: 'pending',
style: { background: '#312e81', border: '#3730a3' }
},
// ── INFRASTRUCTURE (SERVER) ───────────────
{
id: 'infrastructure',
type: 'text',
x: 850, y: -603,
width: 450, height: 400,
label: '🖥️ Инфраструктура сервера',
text: `# 🖥️ Сервер\n\n- **VM (Debian):** 10.0.0.120\n- **Jump-host:** alex@178.238.78.98\n- **Docker Network:** \`infra\`\n- **Services:**\n - \`postgres:5432\` (Shared PostgreSQL)\n - \`gitea:3001\` (Git server)\n - \`xflow:3002\` (XFlow CRM)\n - \`npb-app:3000\` (NPB/AIPB — наш проект)\n- **Reverse Proxy:** Nginx (FastPanel)\n\n**SSH-туннель к БД:**\n\`\`\`\nssh -J alex@178.238.78.98 -L 5432:localhost:5432 root@10.0.0.120\n\`\`\``,
state: 'pending',
style: { background: '#1c1917', border: '#44403c' }
},
// ── DEPLOYMENT ────────────────────────────
{
id: 'deployment',
type: 'text',
x: -474, y: 650,
width: 450, height: 300,
label: '🚀 Деплой & CI/CD',
text: `# 🔄 Деплой (Gitea Actions)\n\n1. \`git push\` → Gitea\n2. Gitea Actions запускает \`deploy.yml\`\n3. Runner делает \`git pull\` на сервере\n4. Пересобирает Docker-контейнер \`npb-app\`\n\n**Время деплоя:** ~3-5 минут\n\n⚠️ В PowerShell — команды по одной, без \`&&\``,
state: 'pending',
style: { background: '#14532d', border: '#166534' }
},
// ── KNOWN ISSUES ──────────────────────────
{
id: 'known-issues',
type: 'text',
x: -1049, y: 580,
width: 400, height: 300,
label: '🐛 Известные проблемы',
text: `# 🐛 Известные проблемы\n\n- **PWA:** Clear site data при non-precached-url ошибке\n- **Gitea push 403:** Токен мог истечь — проверить \`GITEA_TOKEN\` в .env\n- **AI Key:** Groq ключ может быть невалидным — обновить в .env\n- **Logs:** Убрать debug-логи из \`execute.post.ts\` перед продом`,
state: 'pending',
style: { background: '#450a0a', border: '#7f1d1d' }
},
// ── DEV TIPS ──────────────────────────────
{
id: 'dev-tips',
type: 'text',
x: 380, y: 580,
width: 450, height: 300,
label: '💡 Dev Tips',
text: `# 💡 Советы по разработке\n\n- **Локальный запуск:** \`npm run dev\`\n- **SSH-туннель к БД:**\n \`ssh -J alex@178.238.78.98 -L 5432:localhost:5432 root@10.0.0.120\`\n- **Список пользователей:** \`node scripts/list_users.cjs\`\n- **Тест AI:** \`node scripts/test_qwen.cjs\`\n- **Не использовать \`&&\` в PowerShell!**`,
state: 'pending',
style: { background: '#1e293b', border: '#334155' }
}
]
// ─────────────────────────────────────────────
// EDGES — connections between nodes
// ─────────────────────────────────────────────
const edges = [
// Main → top cluster
{ id: 'e1', source: 'main', target: 'dual-device' },
{ id: 'e2', source: 'dual-device', target: 'architecture' },
{ id: 'e3', source: 'architecture', target: 'infrastructure' },
// Main → left cluster
{ id: 'e4', source: 'main', target: 'tech-stack' },
{ id: 'e5', source: 'tech-stack', target: 'auth-system' },
// Main → center/bottom cluster
{ id: 'e6', source: 'main', target: 'gestures' },
{ id: 'e7', source: 'main', target: 'user-flow' },
{ id: 'e8', source: 'user-flow', target: 'roadmap' },
{ id: 'e9', source: 'roadmap', target: 'ai-styles' },
// Bottom
{ id: 'e10', source: 'main', target: 'deployment' },
{ id: 'e11', source: 'auth-system', target: 'known-issues' },
{ id: 'e12', source: 'deployment', target: 'dev-tips' }
]
// ─────────────────────────────────────────────
// DB UPSERT
// ─────────────────────────────────────────────
async function run() {
try {
const check = await pool.query('SELECT id FROM "Canvas" WHERE id = $1', [CANVAS_ID])
if (check.rows.length > 0) {
await pool.query(
'UPDATE "Canvas" SET nodes = $1, edges = $2, name = $3, "updatedAt" = NOW() WHERE id = $4',
[JSON.stringify(nodes), JSON.stringify(edges), CANVAS_NAME, CANVAS_ID]
)
console.log('✅ NPB/AIPB Brief canvas UPDATED!')
} else {
await pool.query(
'INSERT INTO "Canvas" (id, name, "ownerId", "isPublic", nodes, edges, "createdAt", "updatedAt") VALUES ($1, $2, $3, true, $4, $5, NOW(), NOW())',
[CANVAS_ID, CANVAS_NAME, OWNER_ID, JSON.stringify(nodes), JSON.stringify(edges)]
)
console.log('✅ NPB/AIPB Brief canvas CREATED!')
}
console.log(`\n📊 Stats: ${nodes.length} nodes, ${edges.length} edges`)
console.log(`🔗 Canvas ID: ${CANVAS_ID}`)
} catch (e) {
console.error('❌ Error:', e.message)
} finally {
await pool.end()
}
}
run()