Files
Avtex/xflow_dump.sql
T

385 lines
30 KiB
SQL
Raw 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.
--
-- PostgreSQL database dump
--
\restrict WBcQVZEt4bd5DvAlsuuzbb0gxp17HNTWxZmQL7NVkQKdYMDtlT8MvQQsk7EOOiq
-- Dumped from database version 17.9
-- Dumped by pg_dump version 17.9
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET transaction_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
SET default_tablespace = '';
SET default_table_access_method = heap;
--
-- Name: Activity; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."Activity" (
id text NOT NULL,
"userId" text NOT NULL,
action text NOT NULL,
"targetId" text NOT NULL,
"targetType" text NOT NULL,
"timestamp" timestamp(3) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
metadata text
);
--
-- Name: Canvas; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."Canvas" (
id text NOT NULL,
name text NOT NULL,
"ownerId" text NOT NULL,
"groupId" text,
"isPublic" boolean DEFAULT false NOT NULL,
nodes jsonb DEFAULT '[]'::jsonb NOT NULL,
edges jsonb DEFAULT '[]'::jsonb NOT NULL,
"createdAt" timestamp(3) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
"updatedAt" timestamp(3) without time zone NOT NULL
);
--
-- Name: Follow; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."Follow" (
id text NOT NULL,
"followerId" text NOT NULL,
"followingId" text NOT NULL,
since timestamp(3) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
);
--
-- Name: Group; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."Group" (
id text NOT NULL,
name text NOT NULL,
description text DEFAULT ''::text NOT NULL,
"isPublic" boolean DEFAULT true NOT NULL,
"ownerId" text NOT NULL,
"createdAt" timestamp(3) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
"updatedAt" timestamp(3) without time zone NOT NULL
);
--
-- Name: GroupMember; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."GroupMember" (
id text NOT NULL,
"userId" text NOT NULL,
"groupId" text NOT NULL,
role text DEFAULT 'member'::text NOT NULL,
"joinedAt" timestamp(3) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
);
--
-- Name: Profile; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."Profile" (
id text NOT NULL,
"userId" text NOT NULL,
"displayName" text NOT NULL,
bio text DEFAULT ''::text NOT NULL,
avatar text DEFAULT ''::text NOT NULL,
"canvasCount" integer DEFAULT 0 NOT NULL,
"followerCount" integer DEFAULT 0 NOT NULL,
"followingCount" integer DEFAULT 0 NOT NULL,
"joinedAt" timestamp(3) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
);
--
-- Name: User; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."User" (
id text NOT NULL,
email text NOT NULL,
username text NOT NULL,
password text NOT NULL,
role text DEFAULT 'user'::text NOT NULL,
"createdAt" timestamp(3) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
"updatedAt" timestamp(3) without time zone NOT NULL
);
--
-- Name: _prisma_migrations; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public._prisma_migrations (
id character varying(36) NOT NULL,
checksum character varying(64) NOT NULL,
finished_at timestamp with time zone,
migration_name character varying(255) NOT NULL,
logs text,
rolled_back_at timestamp with time zone,
started_at timestamp with time zone DEFAULT now() NOT NULL,
applied_steps_count integer DEFAULT 0 NOT NULL
);
--
-- Data for Name: Activity; Type: TABLE DATA; Schema: public; Owner: -
--
COPY public."Activity" (id, "userId", action, "targetId", "targetType", "timestamp", metadata) FROM stdin;
\.
--
-- Data for Name: Canvas; Type: TABLE DATA; Schema: public; Owner: -
--
COPY public."Canvas" (id, name, "ownerId", "groupId", "isPublic", nodes, edges, "createdAt", "updatedAt") FROM stdin;
test-crm Для проверки задач GqbpMyUW0NaxjIy5nvCiXCiQu9t2 \N t [{"x": 100, "y": 100, "id": "task-1", "text": "# Создать API пользователей\\nРазработать эндпоинт для списка пользователей", "type": "task", "alarm": "2026-05-01T21:14", "label": "# Создать API пользо", "state": "in_progress", "style": {"border": "#334155", "background": "#1e293b"}, "width": 300, "height": 200, "priority": "medium", "script_id": "авяыаячс", "updatedAt": "2026-04-29T10:41:32.122Z", "assigned_to": "almalexyz"}, {"x": 450, "y": 100, "id": "task-2", "text": "# Канбан-доска\\nСделать вывод всех задач", "type": "task", "alarm": "", "label": "# Канбан-доска\\nСдела", "state": "blocked", "style": {"border": "#334155", "background": "#1e293b"}, "width": 300, "height": 200, "priority": "medium", "script_id": "", "updatedAt": "2026-04-29T10:41:31.160Z", "assigned_to": ""}, {"x": 91, "y": 438, "id": "task-3", "text": "# Проверка прав\\nНастроить доступ к картам", "type": "task", "alarm": "2026-04-25T21:14", "label": "# Проверка прав\\nНаст", "state": "review", "style": {"border": "#334155", "background": "#1e293b"}, "width": 300, "height": 200, "priority": "medium", "script_id": "тимтапр", "updatedAt": "2026-04-29T10:41:29.977Z", "assigned_to": "system"}, {"x": 450, "y": 350, "id": "task-4", "text": "# Тестирование\\nПроверить как работают бейджики", "type": "task", "alarm": "", "label": "# Тестирование\\nПрове", "state": "review", "style": {"border": "#334155", "background": "#1e293b"}, "width": 300, "height": 200, "priority": "medium", "script_id": "", "updatedAt": "2026-04-29T12:11:10.028Z", "assigned_to": ""}, {"x": 874, "y": 233, "id": "node-test-1777394609896", "text": "# My new task\\nTest", "type": "task", "alarm": "", "label": "# My new task\\nTest", "state": "completed", "style": {"border": "#334155", "background": "#1e293b"}, "width": 300, "height": 200, "priority": "high", "script_id": "", "updatedAt": "2026-04-29T12:11:14.229Z", "assigned_to": "almalexyz"}] [] 2026-04-28 20:20:03.107 2026-04-29 12:11:14.231
xflow-project 🗺️ Глобальная Архитектура XFlow GqbpMyUW0NaxjIy5nvCiXCiQu9t2 \N t [{"x": -6, "y": -136, "id": "arch-1", "text": "# 🏗️ Глобальная Архитектура\\n\\n- **Nuxt 3** - Full-stack фреймворк (SSR + API)\\n- **Prisma ORM** - Типизированный доступ к данным\\n- **PostgreSQL** - Надежное хранилище\\n- **Firebase Auth** - Вход через Google\\n- **Vue Flow** - Ядро интерактивного холста\\n- **TailwindCSS** - Современная стилизация", "type": "text", "label": "# 🏗️ Глобальная Арх", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 400, "height": 350}, {"x": -975, "y": 192, "id": "prisma-schema", "text": "# 🗄️ База Данных & Prisma\\n\\n```prisma\\nmodel User {\\n id String @id\\n email String @unique\\n username String @unique\\n role String @default(\\"user\\")\\n canvases Canvas[]\\n groups GroupMember[]\\n}\\n\\nmodel Canvas {\\n id String @id\\n name String\\n nodes Json // Obsidian format\\n edges Json\\n owner User @relation(...)\\n}\\n\\nmodel Group {\\n id String @id\\n members GroupMember[]\\n}\\n```\\n\\n**Особенности:**\\n- Использование `Json` полей для гибкости холста\\n- Каскадное удаление данных\\n- Связи многие-ко-многим для групп", "type": "text", "label": "# 🗄️ База Данных & ", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 450, "height": 500}, {"x": -706, "y": 899, "id": "auth-system", "text": "# 🔐 Безопасность и Auth\\n\\n1. **Firebase**: Клиентская аутентификация Google.\\n2. **Google Token**: Отправляется на `/api/auth/google`.\\n3. **Prisma Upsert**: Пользователь создается или обновляется в БД.\\n4. **JWT**: Сервер генерирует токен (с ID и ролью).\\n5. **Middleware**: Проверка JWT через `requireAuth` в серверных роутах.\\n6. **RBAC**: Роли `admin` и `user` контролируют доступ.", "type": "text", "label": "# 🔐 Безопасность и ", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 450, "height": 350}, {"x": 773, "y": 349, "id": "git-sync", "text": "# 🔄 Git Синхронизация (Gitea)\\n\\n- **useGitSync**: Composable для управления статусом.\\n- **Real-Sync API**: Обрабатывает `init` и `sync`.\\n- **Gitea Integration**:\\n - Автоматическое создание репозиториев.\\n - Коммиты при каждом сохранении карты.\\n - Хранение `.canvas` файлов в Git для версионности.\\n - Токены доступа через `.env` переменные.", "type": "text", "label": "# 🔄 Git Синхронизац", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 450, "height": 400}, {"x": 533, "y": 829, "id": "state-reactivity", "text": "# 🧪 Реактивность и Состояние\\n\\n- **elements**: Массив всех узлов и ребер Vue Flow.\\n- **selectedNode**: Реактивный объект для панели свойств.\\n- **useUnsavedChanges**: Отслеживание изменений (Dirty state).\\n- **commitNodeChange**: Синхронизация данных из панели свойств обратно в массив элементов перед сохранением.", "type": "text", "label": "# 🧪 Реактивность и ", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 450, "height": 350}, {"x": 2, "y": 649, "id": "feat-1", "text": "# ✨ Ключевые Фичи\\n\\n- **Кросс-ссылки**: Навигация между картами.\\n- **Канбан**: Сводная таблица задач по пользователям.\\n- **Типы Узлов**:\\n - `Text` (Markdown)\\n - `Task` (State machine)\\n - `AI Prompt` (LLM ready)\\n - `Webhook` (External trigger)\\n - `Git Sync` (Version control)\\n- **Импорт/Экспорт**: Полная совместимость с Obsidian.", "type": "text", "label": "# ✨ Ключевые Фичи\\n\\n-", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 400, "height": 450}, {"x": -267, "y": 1204, "id": "session-apr-28", "text": "# 🔥 Сессия 28 Апреля (Итоги)\\n\\n- ✅ Починена потеря метаданных в Prisma.\\n- ✅ Реализована навигация (двойной клик по ссылкам).\\n- ✅ Внедрена система ролей и прав.\\n- ✅ Добавлен выпадающий список для связей карт.\\n- ✅ Синхронизированы Firebase и БД ID.", "type": "text", "label": "# 🔥 Сессия 28 Апрел", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 400, "height": 250}, {"x": 1009, "y": 75, "id": "node-1777399734802-hmxuy9", "file": "xflow-project", "type": "file", "label": "File Node", "style": {"border": "#334155", "background": "#1e293b"}, "width": 300, "height": 200}] [{"id": "e1", "toNode": "prisma-schema", "toSide": "left", "fromNode": "arch-1", "fromSide": "right"}, {"id": "e2", "toNode": "auth-system", "toSide": "left", "fromNode": "arch-1", "fromSide": "right"}, {"id": "e3", "toNode": "git-sync", "toSide": "left", "fromNode": "arch-1", "fromSide": "right"}, {"id": "e4", "toNode": "state-reactivity", "toSide": "left", "fromNode": "arch-1", "fromSide": "right"}, {"id": "e5", "toNode": "feat-1", "toSide": "left", "fromNode": "arch-1", "fromSide": "right"}, {"id": "e6", "toNode": "session-apr-28", "toSide": "left", "fromNode": "feat-1", "fromSide": "right"}, {"id": "e7", "toNode": "auth-system", "toSide": "left", "fromNode": "prisma-schema", "fromSide": "right"}] 2026-04-28 13:51:21.138 2026-04-28 18:09:17.404
session-2026-04-23 session-2026-04-23 GqbpMyUW0NaxjIy5nvCiXCiQu9t2 \N t [{"x": -200, "y": -600, "id": "title", "text": "# Сессия 23 апреля 2026\\n## CI/CD через Gitea Actions", "type": "text", "width": 400, "height": 80}, {"x": -800, "y": -400, "id": "problem1", "text": "## ❌ Проблема 1\\n**node not in PATH**\\nRunner выполнял job на хосте без node\\n\\n**Fix:** настроить runner label\\n`ubuntu-latest:docker://node:20-alpine`", "type": "text", "width": 340, "height": 200}, {"x": -400, "y": -400, "id": "problem2", "text": "## ❌ Проблема 2\\n**getaddrinfo ENOTFOUND gitea**\\nJob контейнер не в сети infra\\n\\n**Fix:** `container.network: infra` в config.yaml runner'а", "type": "text", "width": 340, "height": 200}, {"x": 0, "y": -400, "id": "problem3", "text": "## ❌ Проблема 3\\n**actions/checkout тянет с GitHub**\\nНе знает про Gitea\\n\\n**Fix:** заменить на ручной `git clone` с токеном через env переменную", "type": "text", "width": 340, "height": 200}, {"x": 400, "y": -400, "id": "problem4", "text": "## ❌ Проблема 4\\n**bash not found**\\nnode:20-alpine не имеет bash\\n\\n**Fix:** `shell: sh` + `defaults.run.shell: sh`", "type": "text", "width": 340, "height": 200}, {"x": -800, "y": -140, "id": "problem5", "text": "## ❌ Проблема 5\\n**Token URL parse error**\\nCRLF переносы в токене ломают URL\\n\\n**Fix:**\\n```sh\\nCLEAN_TOKEN=$(printf '%s' \\"${TOKEN}\\" | tr -d '\\\\r\\\\n')\\n```", "type": "text", "width": 340, "height": 200}, {"x": -400, "y": -140, "id": "problem6", "text": "## ❌ Проблема 6\\n**rsync not found**\\nНет rsync в Alpine\\n\\n**Fix:** `apk add --no-cache openssh-client rsync`\\n\\nПотом поняли что SSH не нужен вообще — runner на том же сервере", "type": "text", "width": 340, "height": 200}, {"x": 0, "y": -140, "id": "problem7", "text": "## ❌ Проблема 7\\n**docker compose -f not found**\\ndocker-cli в Alpine не поддерживает compose\\n\\n**Fix:** `apk add docker-cli-compose`\\nИспользовать `docker-compose` (v1)", "type": "text", "width": 340, "height": 200}, {"x": 400, "y": -140, "id": "problem8", "text": "## ❌ Проблема 8\\n**Duplicate mount: /var/run/docker.sock**\\nУказали sock и в options и в volumes\\n\\n**Fix:** убрать sock из options, оставить только xflow/npb", "type": "text", "width": 340, "height": 200}, {"x": -800, "y": 120, "id": "problem9", "text": "## ❌ Проблема 9\\n**Runner label \\\\\\"ubuntu-latest\\\\\\"**\\nЭкранированные кавычки в YAML\\n\\n**Fix:** убрать кавычки вокруг лейбла в config.yaml:\\n`- ubuntu-latest:docker://node:20-alpine`", "type": "text", "width": 340, "height": 180}, {"x": -400, "y": 120, "id": "problem10", "text": "## ❌ Проблема 10\\n**No such file /opt/xflow/docker-compose.yml**\\nVolume не пробрасывался в job контейнер\\n\\n**Fix:** `container.options` в config.yaml:\\n`\\"-v /opt/xflow:/opt/xflow\\"`\\n+ `valid_volumes`", "type": "text", "width": 340, "height": 180}, {"x": 0, "y": 120, "id": "problem11", "text": "## ❌ Проблема 11\\n**env file /opt/xflow/.env not found**\\n\\n**Fix:** создать `/opt/xflow/.env` на сервере с переменными:\\nNODE_ENV, DATABASE_URL,\\nNUXT_JWT_SECRET, GITEA_URL и т.д.", "type": "text", "width": 340, "height": 180}, {"x": -200, "y": 380, "id": "solution", "text": "## ✅ Итоговый стек деплоя\\n\\n**Runner config.yaml:**\\n```yaml\\nrunner:\\n labels:\\n - ubuntu-latest:docker://node:20-alpine\\ncontainer:\\n network: infra\\n options: \\"-v /opt/xflow:/opt/xflow -v /opt/npb:/opt/npb\\"\\n valid_volumes:\\n - /opt/xflow\\n - /opt/npb\\n - /var/run/docker.sock\\n```\\n\\n**Workflow шаги:**\\n1. `git clone` через env TOKEN\\n2. `npm ci && npm run build`\\n3. `cp -r .output/ /opt/xflow/.output/`\\n4. `docker-compose up -d --force-recreate`", "type": "text", "width": 500, "height": 340}, {"x": -200, "y": 780, "id": "result", "text": "## 🎉 Результат\\n\\n- **XFlow** запущен на `http://a-crm.controlsystem.kz` (порт 3002)\\n- **NPB** деплоится на порт 3003\\n- **Gitea runner** `avtex-runner` обслуживает всю организацию AVTEX\\n- Автодеплой при каждом `git push` в master/main\\n- Секрет `GIT_TOKEN` на уровне организации\\n\\n**Следующие шаги:**\\n- `prisma migrate deploy`\\n- Переписать API с db.ts на Prisma\\n- Nginx proxy для NPB", "type": "text", "width": 500, "height": 260}, {"x": 400, "y": 380, "id": "arch", "text": "## 🏗️ Архитектура сервера\\n\\n```\\nDocker network: infra\\n├── gitea (3000/3001)\\n├── postgres (5432)\\n├── gitea-runner\\n│ ├── /var/run/docker.sock\\n│ ├── /opt/xflow (volume)\\n│ └── /opt/npb (volume)\\n├── xflow (3002→3000)\\n└── npb (3003→3000)\\n```\\n\\nJump host: `alex@178.238.78.98`\\nTarget: `root@10.0.0.120`", "type": "text", "width": 340, "height": 260}] [{"id": "e1", "toNode": "problem1", "toSide": "top", "fromNode": "title", "fromSide": "bottom"}, {"id": "e2", "toNode": "problem2", "toSide": "top", "fromNode": "title", "fromSide": "bottom"}, {"id": "e3", "toNode": "problem3", "toSide": "top", "fromNode": "title", "fromSide": "bottom"}, {"id": "e4", "toNode": "problem4", "toSide": "top", "fromNode": "title", "fromSide": "bottom"}, {"id": "e5", "toNode": "problem5", "toSide": "top", "fromNode": "problem1", "fromSide": "bottom"}, {"id": "e6", "toNode": "problem6", "toSide": "top", "fromNode": "problem3", "fromSide": "bottom"}, {"id": "e7", "toNode": "problem7", "toSide": "top", "fromNode": "problem4", "fromSide": "bottom"}, {"id": "e8", "toNode": "problem8", "toSide": "top", "fromNode": "problem2", "fromSide": "bottom"}, {"id": "e9", "toNode": "problem9", "toSide": "top", "fromNode": "problem5", "fromSide": "bottom"}, {"id": "e10", "toNode": "problem10", "toSide": "top", "fromNode": "problem6", "fromSide": "bottom"}, {"id": "e11", "toNode": "problem11", "toSide": "top", "fromNode": "problem7", "fromSide": "bottom"}, {"id": "e12", "toNode": "solution", "toSide": "top", "fromNode": "problem9", "fromSide": "bottom"}, {"id": "e13", "toNode": "solution", "toSide": "top", "fromNode": "problem10", "fromSide": "bottom"}, {"id": "e14", "toNode": "solution", "toSide": "top", "fromNode": "problem11", "fromSide": "bottom"}, {"id": "e15", "toNode": "result", "toSide": "top", "fromNode": "solution", "fromSide": "bottom"}, {"id": "e16", "toNode": "arch", "toSide": "left", "fromNode": "solution", "fromSide": "right"}] 2026-04-28 13:40:23.017 2026-04-28 13:40:23.017
master-plan 🗺️ Генеральный План Развития GqbpMyUW0NaxjIy5nvCiXCiQu9t2 \N t [{"x": -3, "y": -227, "id": "root", "text": "# План Развития XFlow\\nВизуальная CRM/ERP Система", "type": "text", "label": "# План Развития XFlo", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 400, "height": 100}, {"x": -479, "y": 162, "id": "stage1", "text": "## Этап 1: Фундамент\\nРоли (RBAC), Управление Командой, Master Canvas", "type": "text", "label": "## Этап 1: Фундамент", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 350, "height": 150}, {"x": -844, "y": 477, "id": "s1-1", "text": "Система Ролей (RBAC)", "type": "task", "alarm": "", "label": "Система Ролей (RBAC)", "state": "review", "style": {"border": "#334155", "background": "#1e293b"}, "width": 300, "height": 120, "priority": "high", "script_id": "", "updatedAt": "2026-04-29T12:11:11.768Z", "assigned_to": "admin"}, {"x": -490, "y": 705, "id": "s1-2", "text": "Интерфейс приглашения юзеров", "type": "task", "alarm": "", "label": "Интерфейс приглашени", "state": "in_progress", "style": {"border": "#334155", "background": "#1e293b"}, "width": 300, "height": 120, "priority": "medium", "script_id": "", "updatedAt": "2026-04-29T12:11:02.137Z", "assigned_to": "admin"}, {"x": 14, "y": 197, "id": "stage2", "text": "## Этап 2: Умные Узлы\\nТипизация, Панель свойств, Цветовая индикация", "type": "text", "label": "## Этап 2: Умные Узл", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 350, "height": 150}, {"x": -160, "y": 458, "id": "s2-1", "text": "Герметичное сохранение метаданных", "type": "task", "alarm": "", "label": "Герметичное сохранен", "state": "review", "style": {"border": "#334155", "background": "#1e293b"}, "width": 300, "height": 120, "priority": "high", "script_id": "", "updatedAt": "2026-04-29T12:11:07.662Z", "assigned_to": "antigravity"}, {"x": 220, "y": 687, "id": "s2-2", "text": "Типизация (Webhook, AI, Git)", "type": "task", "alarm": "", "label": "Типизация (Webhook, ", "state": "todo", "style": {"border": "#334155", "background": "#1e293b"}, "width": 300, "height": 120, "priority": "high", "script_id": "", "updatedAt": "2026-04-29T10:41:40.534Z", "assigned_to": "antigravity"}, {"x": 939, "y": 130, "id": "stage3", "text": "## Этап 3: Аналитика\\nКанбан-борд, Дашборд, Уведомления", "type": "text", "label": "## Этап 3: Аналитика", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 350, "height": 150}, {"x": 500, "y": 400, "id": "s3-1", "text": "Персональный Канбан-дашборд", "type": "task", "alarm": "", "label": "Персональный Канбан-", "state": "completed", "style": {"border": "#334155", "background": "#1e293b"}, "width": 300, "height": 120, "priority": "high", "script_id": "", "assigned_to": "antigravity"}, {"x": 900, "y": 450, "id": "s3-2", "text": "Drag-n-Drop в Канбане", "type": "task", "alarm": "", "label": "Drag-n-Drop в Канбан", "state": "in_progress", "style": {"border": "#334155", "background": "#1e293b"}, "width": 300, "height": 120, "priority": "medium", "script_id": "", "updatedAt": "2026-04-29T12:11:03.674Z", "assigned_to": "admin"}, {"x": 426, "y": 109, "id": "stage4", "text": "## Этап 4: Интеграции\\nGit/Gitea Deep Sync, S3 Storage, Workflows", "type": "text", "label": "## Этап 4: Интеграци", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 400, "height": 150}, {"x": -905, "y": -54, "id": "update", "text": "### Обновление 28.04\\n✅ Сохранение метаданных\\n✅ База под Канбан\\n✅ Типизация узлов", "type": "text", "label": "### Обновление 28.04", "state": "pending", "style": {"border": "#334155", "background": "#1e293b"}, "width": 400, "height": 200}] [{"id": "e1", "toNode": "stage1", "toSide": "left", "fromNode": "root", "fromSide": "right"}, {"id": "e2", "toNode": "stage2", "toSide": "left", "fromNode": "root", "fromSide": "right"}, {"id": "e3", "toNode": "stage3", "toSide": "left", "fromNode": "root", "fromSide": "right"}, {"id": "e4", "toNode": "stage4", "toSide": "left", "fromNode": "root", "fromSide": "right"}, {"id": "e5", "toNode": "update", "toSide": "left", "fromNode": "root", "fromSide": "right"}, {"id": "e1-1", "toNode": "s1-1", "toSide": "left", "fromNode": "stage1", "fromSide": "right"}, {"id": "e1-2", "toNode": "s1-2", "toSide": "left", "fromNode": "stage1", "fromSide": "right"}, {"id": "e2-1", "toNode": "s2-1", "toSide": "left", "fromNode": "stage2", "fromSide": "right"}, {"id": "e2-2", "toNode": "s2-2", "toSide": "left", "fromNode": "stage2", "fromSide": "right"}, {"id": "e3-1", "toNode": "s3-1", "toSide": "left", "fromNode": "stage3", "fromSide": "right"}, {"id": "e3-2", "toNode": "s3-2", "toSide": "left", "fromNode": "stage3", "fromSide": "right"}] 2026-04-28 21:57:38.688 2026-04-29 12:11:11.769
\.
--
-- Data for Name: Follow; Type: TABLE DATA; Schema: public; Owner: -
--
COPY public."Follow" (id, "followerId", "followingId", since) FROM stdin;
\.
--
-- Data for Name: Group; Type: TABLE DATA; Schema: public; Owner: -
--
COPY public."Group" (id, name, description, "isPublic", "ownerId", "createdAt", "updatedAt") FROM stdin;
\.
--
-- Data for Name: GroupMember; Type: TABLE DATA; Schema: public; Owner: -
--
COPY public."GroupMember" (id, "userId", "groupId", role, "joinedAt") FROM stdin;
\.
--
-- Data for Name: Profile; Type: TABLE DATA; Schema: public; Owner: -
--
COPY public."Profile" (id, "userId", "displayName", bio, avatar, "canvasCount", "followerCount", "followingCount", "joinedAt") FROM stdin;
\.
--
-- Data for Name: User; Type: TABLE DATA; Schema: public; Owner: -
--
COPY public."User" (id, email, username, password, role, "createdAt", "updatedAt") FROM stdin;
system system@localhost system none admin 2026-04-28 13:40:22.99 2026-04-28 13:40:22.99
GqbpMyUW0NaxjIy5nvCiXCiQu9t2 almalexyz@gmail.com almalexyz none admin 2026-04-28 20:21:01.95 2026-04-28 20:21:01.95
\.
--
-- Data for Name: _prisma_migrations; Type: TABLE DATA; Schema: public; Owner: -
--
COPY public._prisma_migrations (id, checksum, finished_at, migration_name, logs, rolled_back_at, started_at, applied_steps_count) FROM stdin;
\.
--
-- Name: Activity Activity_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Activity"
ADD CONSTRAINT "Activity_pkey" PRIMARY KEY (id);
--
-- Name: Canvas Canvas_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Canvas"
ADD CONSTRAINT "Canvas_pkey" PRIMARY KEY (id);
--
-- Name: Follow Follow_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Follow"
ADD CONSTRAINT "Follow_pkey" PRIMARY KEY (id);
--
-- Name: GroupMember GroupMember_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."GroupMember"
ADD CONSTRAINT "GroupMember_pkey" PRIMARY KEY (id);
--
-- Name: Group Group_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Group"
ADD CONSTRAINT "Group_pkey" PRIMARY KEY (id);
--
-- Name: Profile Profile_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Profile"
ADD CONSTRAINT "Profile_pkey" PRIMARY KEY (id);
--
-- Name: User User_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."User"
ADD CONSTRAINT "User_pkey" PRIMARY KEY (id);
--
-- Name: _prisma_migrations _prisma_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public._prisma_migrations
ADD CONSTRAINT _prisma_migrations_pkey PRIMARY KEY (id);
--
-- Name: Follow_followerId_followingId_key; Type: INDEX; Schema: public; Owner: -
--
CREATE UNIQUE INDEX "Follow_followerId_followingId_key" ON public."Follow" USING btree ("followerId", "followingId");
--
-- Name: GroupMember_userId_groupId_key; Type: INDEX; Schema: public; Owner: -
--
CREATE UNIQUE INDEX "GroupMember_userId_groupId_key" ON public."GroupMember" USING btree ("userId", "groupId");
--
-- Name: Profile_userId_key; Type: INDEX; Schema: public; Owner: -
--
CREATE UNIQUE INDEX "Profile_userId_key" ON public."Profile" USING btree ("userId");
--
-- Name: User_email_key; Type: INDEX; Schema: public; Owner: -
--
CREATE UNIQUE INDEX "User_email_key" ON public."User" USING btree (email);
--
-- Name: User_username_key; Type: INDEX; Schema: public; Owner: -
--
CREATE UNIQUE INDEX "User_username_key" ON public."User" USING btree (username);
--
-- Name: Activity Activity_userId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Activity"
ADD CONSTRAINT "Activity_userId_fkey" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: Canvas Canvas_groupId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Canvas"
ADD CONSTRAINT "Canvas_groupId_fkey" FOREIGN KEY ("groupId") REFERENCES public."Group"(id) ON UPDATE CASCADE ON DELETE SET NULL;
--
-- Name: Canvas Canvas_ownerId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Canvas"
ADD CONSTRAINT "Canvas_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES public."User"(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: Follow Follow_followerId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Follow"
ADD CONSTRAINT "Follow_followerId_fkey" FOREIGN KEY ("followerId") REFERENCES public."User"(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: Follow Follow_followingId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Follow"
ADD CONSTRAINT "Follow_followingId_fkey" FOREIGN KEY ("followingId") REFERENCES public."User"(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: GroupMember GroupMember_groupId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."GroupMember"
ADD CONSTRAINT "GroupMember_groupId_fkey" FOREIGN KEY ("groupId") REFERENCES public."Group"(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: GroupMember GroupMember_userId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."GroupMember"
ADD CONSTRAINT "GroupMember_userId_fkey" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- Name: Profile Profile_userId_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Profile"
ADD CONSTRAINT "Profile_userId_fkey" FOREIGN KEY ("userId") REFERENCES public."User"(id) ON UPDATE CASCADE ON DELETE CASCADE;
--
-- PostgreSQL database dump complete
--
\unrestrict WBcQVZEt4bd5DvAlsuuzbb0gxp17HNTWxZmQL7NVkQKdYMDtlT8MvQQsk7EOOiq