chore: align infrastructure with server
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
const { Pool } = require('pg')
|
||||
|
||||
// Connection string from .env
|
||||
const DB_URL = 'postgresql://xflow:xflow_pass@localhost:5433/xflow'
|
||||
const pool = new Pool({ connectionString: DB_URL })
|
||||
|
||||
const CANVAS_ID = 'xflow-project-brief'
|
||||
const OWNER_ID = 'GqbpMyUW0NaxjIy5nvCiXCiQu9t2'
|
||||
|
||||
const nodes = [
|
||||
{
|
||||
id: 'main',
|
||||
type: 'text',
|
||||
x: 0, y: 0,
|
||||
width: 450, height: 220,
|
||||
label: '🤖 XFlow — Project Brief',
|
||||
text: `# 🤖 XFlow\n\n**Visual CRM/ERP system based on Obsidian Canvas.**\n\n- **Owner:** Alex Ives (almalexyz@gmail.com)\n- **Firebase UID:** \`GqbpMyUW0NaxjIy5nvCiXCiQu9t2\`\n- **Repo:** [git.a-crm.controlsystem.kz](http://git.a-crm.controlsystem.kz/AVTEX/XFlow)\n- **Prod:** [a-crm.controlsystem.kz](https://a-crm.controlsystem.kz)\n- **Local:** [localhost:3000](http://localhost:3000)`
|
||||
},
|
||||
{
|
||||
id: 'tech-stack',
|
||||
type: 'text',
|
||||
x: 600, y: -250,
|
||||
width: 400, height: 350,
|
||||
label: '🏗️ Tech Stack',
|
||||
text: `# 🏗️ Стек технологий\n\n- **Frontend:** Nuxt 3 (SSR + API routes)\n- **Canvas Engine:** Vue Flow\n- **Styling:** TailwindCSS\n- **ORM:** Prisma 7 + @prisma/adapter-pg\n- **Database:** PostgreSQL 16 (Docker)\n- **Auth:** Firebase Auth + JWT\n- **PWA:** @vite-pwa/nuxt\n- **CI/CD:** Gitea Actions`
|
||||
},
|
||||
{
|
||||
id: 'infrastructure',
|
||||
type: 'text',
|
||||
x: 600, y: 250,
|
||||
width: 400, height: 350,
|
||||
label: '🖥️ Infrastructure',
|
||||
text: `# 🖥️ Инфраструктура\n\n- **VM (Debian):** 10.0.0.120\n- **Docker Network:** \`infra\`\n- **Services:**\n - \`postgres:5432\` (Shared DB)\n - \`gitea:3001\` (Git server)\n - \`xflow:3002\` (Production app)\n - \`npb-app:3000\` (Other project)\n- **Reverse Proxy:** Nginx (FastPanel)\n\n[🔗 Перейти к карте инфраструктуры](canvas/infrastructure)`
|
||||
},
|
||||
{
|
||||
id: 'database',
|
||||
type: 'text',
|
||||
x: 1100, y: 0,
|
||||
width: 400, height: 300,
|
||||
label: '🗄️ Database Schema',
|
||||
text: `# 🗄️ Prisma Schema\n\n- **User:** Firebase ID, Email, Role (admin/user)\n- **Canvas:** ID, Name, Owner, Public, Nodes (Json), Edges (Json)\n\n⚠️ **Важно:** Узлы хранятся как JSON-массив. При обновлении нужно перезаписывать весь массив.`
|
||||
},
|
||||
{
|
||||
id: 'auth-flow',
|
||||
type: 'text',
|
||||
x: -600, y: -250,
|
||||
width: 400, height: 300,
|
||||
label: '🔐 Auth Flow',
|
||||
text: `# 🔐 Аутентификация\n\n1. Client logins via Firebase Google Auth.\n2. Token sent to \`/api/auth/google\`.\n3. Server upserts user (ID = Firebase UID).\n4. Returns JWT in \`xflow_token\` cookie.\n5. \`requireAuth\` middleware protects routes.\n\n⚠️ User.id MUST match Firebase UID.`
|
||||
},
|
||||
{
|
||||
id: 'features',
|
||||
type: 'text',
|
||||
x: -600, y: 250,
|
||||
width: 400, height: 420,
|
||||
label: '✅ Features',
|
||||
text: `# ✅ Реализовано\n\n- **Canvas:** Interactive Vue Flow editor\n- **Nodes:** text, task, ai, webhook, file, git\n- **Kanban:** Board (/tasks) with DnD\n- **AI:** Execution with context from neighbors\n- **Webhooks:** GET/POST execution\n- **Git:** Sync maps with Gitea\n- **Auth:** RBAC (user/admin) & Firebase\n- **PWA:** Service Worker & Manifest`
|
||||
},
|
||||
{
|
||||
id: 'todo',
|
||||
type: 'text',
|
||||
x: 0, y: 450,
|
||||
width: 400, height: 320,
|
||||
label: '🔴 To-Do',
|
||||
text: `# 🔴 Что нужно доделать\n\n- **AI Key:** Get a working Groq key (llama-3.3-70b).\n- **Dashboard:** Main page with stats.\n- **Webhooks:** Telegram notifications.\n- **Users:** Invitation system.\n- **Stability:** Fix PWA service worker caching issue.`
|
||||
},
|
||||
{
|
||||
id: 'dev-tips',
|
||||
type: 'text',
|
||||
x: 0, y: -450,
|
||||
width: 450, height: 320,
|
||||
label: '💡 Dev Tips',
|
||||
text: `# 💡 Советы по разработке\n\n- **Local run:** \`npm run dev\`\n- **DB Tunnel:** \`ssh -J alex@178.238.78.98 -L 5433:localhost:5432 root@10.0.0.120\`\n- **Check DB:** \`node scripts/list_users.cjs\`\n- **Test AI:** \`node scripts/test_qwen.cjs\`\n- **Note:** Don't use \`git push && ...\` in PowerShell.`
|
||||
},
|
||||
{
|
||||
id: 'issues',
|
||||
type: 'text',
|
||||
x: -1100, y: 0,
|
||||
width: 400, height: 280,
|
||||
label: '🐛 Known Issues',
|
||||
text: `# 🐛 Известные проблемы\n\n- **PWA:** Clear site data if non-precached-url error occurs.\n- **Gitea:** 403 error on push if token expired.\n- **Logs:** Remove debug logs from \`execute.post.ts\` before prod.`
|
||||
}
|
||||
]
|
||||
|
||||
const edges = [
|
||||
{ id: 'e1', source: 'main', target: 'tech-stack' },
|
||||
{ id: 'e2', source: 'main', target: 'infrastructure' },
|
||||
{ id: 'e3', source: 'main', target: 'features' },
|
||||
{ id: 'e4', source: 'main', target: 'auth-flow' },
|
||||
{ id: 'e5', source: 'main', target: 'todo' },
|
||||
{ id: 'e6', source: 'main', target: 'dev-tips' },
|
||||
{ id: 'e7', source: 'tech-stack', target: 'database' },
|
||||
{ id: 'e8', source: 'infrastructure', target: 'database' },
|
||||
{ id: 'e9', source: 'features', target: 'issues' }
|
||||
]
|
||||
|
||||
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), '🤖 XFlow — Project Brief', CANVAS_ID]
|
||||
)
|
||||
console.log('✅ XFlow 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, '🤖 XFlow — Project Brief', OWNER_ID, JSON.stringify(nodes), JSON.stringify(edges)]
|
||||
)
|
||||
console.log('✅ XFlow Brief canvas created!')
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('❌ Error:', e.message)
|
||||
} finally {
|
||||
await pool.end()
|
||||
}
|
||||
}
|
||||
|
||||
run()
|
||||
Reference in New Issue
Block a user