diff --git a/SPECIFICATION.md b/spec/SPECIFICATION-aurora.md
similarity index 54%
rename from SPECIFICATION.md
rename to spec/SPECIFICATION-aurora.md
index 603c15b..61f52ff 100644
--- a/SPECIFICATION.md
+++ b/spec/SPECIFICATION-aurora.md
@@ -1,7 +1,8 @@
-# Team Board — Полная Спецификация
+# Team Board — Полная Спецификация (Aurora Edition)
-Версия: 1.0
+Версия: 1.1
Дата: 2026-03-13
+Автор: Аврора
Статус: В разработке
---
@@ -21,6 +22,13 @@
11. [Инфраструктура](#11-инфраструктура)
12. [Функциональность](#12-функциональность)
13. [Дорожная карта](#13-дорожная-карта)
+14. [Разработка и деплой](#14-разработка-и-деплой)
+15. [Тестирование](#15-тестирование)
+16. [Производительность](#16-производительность)
+17. [Безопасность](#17-безопасность)
+18. [Мониторинг и логирование](#18-мониторинг-и-логирование)
+19. [Troubleshooting](#19-troubleshooting)
+20. [Приложения](#20-приложения)
---
@@ -799,4 +807,730 @@ MIT
---
+## 14. Разработка и деплой
+
+### 14.1 Локальная разработка
+
+**Backend (Tracker):**
+```bash
+cd /root/projects/team-board/tracker
+python -m venv venv
+source venv/bin/activate
+pip install -r requirements.txt
+alembic upgrade head
+uvicorn app.main:app --reload --port 8100
+```
+
+**Frontend:**
+```bash
+cd /root/projects/team-board/web-client-vite
+npm install
+npm run dev
+```
+
+**Agent (Picogent):**
+```bash
+cd /root/projects/team-board/picogent
+npm install
+npm run build
+npm run start --config agent.json
+```
+
+### 14.2 Docker деплой
+
+**Сборка:**
+```bash
+docker-compose build
+```
+
+**Запуск:**
+```bash
+docker-compose up -d
+```
+
+**Логи:**
+```bash
+docker-compose logs -f tracker
+```
+
+**Остановка:**
+```bash
+docker-compose down
+```
+
+### 14.3 Миграции БД
+
+**Создание миграции:**
+```bash
+alembic revision --autogenerate -m "Add new table"
+alembic upgrade head
+```
+
+**Откат:**
+```bash
+alembic downgrade -1
+```
+
+**История:**
+```bash
+alembic history
+```
+
+### 14.4 Переменные окружения
+
+**Tracker (.env):**
+```bash
+DATABASE_URL=postgresql://user:pass@localhost:5432/teamboard
+JWT_SECRET=your-secret-key
+CORS_ORIGINS=https://dev.team.uix.su,https://team.uix.su
+UPLOAD_DIR=/var/www/team-board/uploads
+```
+
+**Picogent (.env):**
+```bash
+TRACKER_URL=http://localhost:8100
+AGENT_TOKEN=tb-agent-xxx
+MODEL=claude-sonnet-4
+```
+
+---
+
+## 15. Тестирование
+### 15.1 Backend тесты
+
+**Стек:** pytest, pytest-asyncio
+
+**Структура:**
+```
+tests/
+├── conftest.py
+├── test_auth.py
+├── test_tasks.py
+├── test_projects.py
+└── test_agents.py
+```
+
+**Пример:**
+```python
+import pytest
+from httpx import AsyncClient
+
+@pytest.mark.asyncio
+async def test_create_task(client: AsyncClient, auth_headers):
+ response = await client.post(
+ "/api/projects/test-project/tasks",
+ json={"title": "Test task"},
+ headers=auth_headers
+ )
+ assert response.status_code == 201
+ data = response.json()
+ assert data["title"] == "Test task"
+```
+
+**Запуск:**
+```bash
+pytest tests/ -v
+pytest tests/ --cov=app
+```
+
+### 15.2 Frontend тесты
+
+**Стек:** Vitest, React Testing Library
+
+**Пример:**
+```typescript
+import { render, screen } from '@testing-library/react'
+import { KanbanBoard } from './KanbanBoard'
+
+test('renders kanban board', () => {
+ render()
+ expect(screen.getByText('To Do')).toBeInTheDocument()
+})
+```
+
+**Запуск:**
+```bash
+npm run test
+npm run test:coverage
+```
+
+### 15.3 E2E тесты
+
+**Стек:** Playwright
+
+**Пример:**
+```typescript
+test('user can create task', async ({ page }) => {
+ await page.goto('/projects/test-project')
+ await page.click('[data-testid="add-task"]')
+ await page.fill('[data-testid="task-title"]', 'New task')
+ await page.click('[data-testid="save-task"]')
+ await expect(page.locator('.task-card')).toBeVisible()
+})
+```
+
+### 15.4 CI/CD
+
+**GitHub Actions:**
+```yaml
+name: Tests
+on: [push, pull_request]
+
+jobs:
+ backend:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
+ with:
+ python-version: '3.11'
+ - run: pip install -r requirements.txt
+ - run: pytest --cov=app
+
+ frontend:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3
+ with:
+ node-version: '20'
+ - run: npm ci
+ - run: npm run test
+```
+
+---
+
+## 16. Производительность
+
+### 16.1 Оптимизации БД
+
+**Индексы:**
+```sql
+CREATE INDEX idx_tasks_project_status ON tasks(project_id, status);
+CREATE INDEX idx_tasks_assignee ON tasks(assignee_id);
+CREATE INDEX idx_messages_project_created ON messages(project_id, created_at DESC);
+CREATE INDEX idx_members_slug ON members(slug);
+```
+
+**Connection pooling:**
+```python
+from sqlalchemy.ext.asyncio import create_async_engine
+
+engine = create_async_engine(
+ DATABASE_URL,
+ pool_size=20,
+ max_overflow=10,
+ pool_pre_ping=True,
+ pool_recycle=3600
+)
+```
+
+### 16.2 Кэширование
+
+**Redis (будущее):**
+```python
+import aioredis
+
+redis = await aioredis.create_redis_pool(REDIS_URL)
+
+# Cache project tasks
+async def get_cached_tasks(project_id: UUID):
+ cached = await redis.get(f"tasks:{project_id}")
+ if cached:
+ return json.loads(cached)
+
+ tasks = await fetch_tasks_from_db(project_id)
+ await redis.setex(f"tasks:{project_id}", 300, json.dumps(tasks))
+ return tasks
+```
+
+### 16.3 WebSocket масштабирование
+
+**Текущее:** In-memory connections dict
+
+**Будущее:** Redis Pub/Sub
+```python
+# Horizontal scaling with Redis
+await redis.publish("ws:broadcast", json.dumps({
+ "project_id": str(project_id),
+ "event": event_type,
+ "data": data
+}))
+
+# Each worker subscribes
+async def redis_subscriber():
+ pubsub = redis.pubsub()
+ await pubsub.subscribe("ws:broadcast")
+ async for message in pubsub.listen():
+ event = json.loads(message["data"])
+ await broadcast_to_local_connections(event)
+```
+
+### 16.4 Фронтенд оптимизации
+
+**Code splitting:**
+```typescript
+const KanbanBoard = lazy(() => import('./KanbanBoard'))
+const Chat = lazy(() => import('./Chat'))
+```
+
+**Bundle analysis:**
+```bash
+npm run build -- --mode analyze
+```
+
+**Asset optimization:**
+- Image compression (WebP)
+- Lazy loading images
+- Service Worker для offline
+
+---
+
+## 17. Безопасность
+
+### 17.1 JWT Security
+
+**Token rotation:**
+```python
+# Short-lived access token (15 min)
+access_token = create_access_token(user_id, expires_delta=timedelta(minutes=15))
+
+# Long-lived refresh token (7 days)
+refresh_token = create_refresh_token(user_id, expires_delta=timedelta(days=7))
+```
+
+**Token validation:**
+```python
+async def get_current_user(token: str = Depends(oauth2_scheme)):
+ try:
+ payload = jwt.decode(token, JWT_SECRET, algorithms=["HS256"])
+ if payload["exp"] < time.time():
+ raise HTTPException(401, "Token expired")
+ return await get_user(payload["sub"])
+ except jwt.InvalidTokenError:
+ raise HTTPException(401, "Invalid token")
+```
+
+### 17.2 Input Validation
+
+**Pydantic schemas:**
+```python
+from pydantic import BaseModel, validator
+
+class TaskCreate(BaseModel):
+ title: str
+ description: str | None
+ priority: Priority = Priority.medium
+
+ @validator('title')
+ def validate_title(cls, v):
+ if len(v) < 3:
+ raise ValueError('Title must be at least 3 characters')
+ if len(v) > 200:
+ raise ValueError('Title too long')
+ return v
+```
+
+### 17.3 SQL Injection Protection
+
+**SQLAlchemy параметризованные запросы:**
+```python
+# ✅ Безопасно
+tasks = await session.execute(
+ select(Task).where(Task.project_id == :project_id),
+ {"project_id": project_id}
+)
+
+# ❌ НЕБЕЗОПАСНО (никогда не использовать)
+query = f"SELECT * FROM tasks WHERE project_id = '{project_id}'"
+```
+
+### 17.4 XSS Protection
+
+**Frontend sanitization:**
+```typescript
+import DOMPurify from 'dompurify'
+
+const SafeHTML = ({ content }) => (
+
+)
+```
+
+### 17.5 Rate Limiting
+
+**Slowapi:**
+```python
+from slowapi import Limiter
+from slowapi.util import get_remote_address
+
+limiter = Limiter(key_func=get_remote_address)
+
+@app.post("/api/tasks")
+@limiter.limit("10/minute")
+async def create_task(request: Request, task: TaskCreate):
+ ...
+```
+
+### 17.6 CORS
+
+**Настройка:**
+```python
+from fastapi.middleware.cors import CORSMiddleware
+
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=[
+ "https://dev.team.uix.su",
+ "https://team.uix.su"
+ ],
+ allow_credentials=True,
+ allow_methods=["*"],
+ allow_headers=["*"],
+)
+```
+
+---
+
+## 18. Мониторинг и логирование
+### 18.1 Структура логов
+
+**Уровни:** DEBUG, INFO, WARNING, ERROR, CRITICAL
+
+**Формат:**
+```python
+import logging
+import json
+
+class JSONFormatter(logging.Formatter):
+ def format(self, record):
+ log_obj = {
+ "timestamp": record.created,
+ "level": record.levelname,
+ "logger": record.name,
+ "message": record.getMessage(),
+ "module": record.module,
+ "function": record.funcName,
+ }
+ if record.exc_info:
+ log_obj["exception"] = self.formatException(record.exc_info)
+ return json.dumps(log_obj)
+
+logging.setFormatter(JSONFormatter())
+```
+
+### 18.2 Prometheus метрики
+
+**Custom metrics:**
+```python
+from prometheus_client import Counter, Histogram
+
+# Counters
+tasks_created = Counter('tasks_created_total', 'Tasks created')
+messages_sent = Counter('messages_sent_total', 'Messages sent')
+agents_active = Counter('agents_active', 'Active agents')
+
+# Histograms
+request_duration = Histogram(
+ 'http_request_duration_seconds',
+ 'HTTP request duration',
+ ['method', 'endpoint']
+)
+
+@app.middleware("http")
+async def metrics_middleware(request: Request, call_next):
+ start = time.time()
+ response = await call_next(request)
+ duration = time.time() - start
+
+ request_duration.labels(request.method, request.url.path).observe(duration)
+
+ return response
+```
+
+### 18.3 Health Checks
+
+**Endpoint:**
+```python
+@app.get("/api/health")
+async def health_check():
+ checks = {
+ "database": await check_database(),
+ "redis": await check_redis() if REDIS_URL else "disabled",
+ "storage": check_storage(),
+ }
+
+ all_healthy = all(v == "ok" for v in checks.values())
+ status_code = 200 if all_healthy else 503
+
+ return JSONResponse(
+ content={"status": "healthy" if all_healthy else "unhealthy", "checks": checks},
+ status_code=status_code
+ )
+```
+
+### 18.4 Error Tracking
+
+**Sentry интеграция:**
+```python
+import sentry_sdk
+from sentry_sdk.integrations.fastapi import FastApiIntegration
+
+sentry_sdk.init(
+ dsn=SENTRY_DSN,
+ integrations=[FastApiIntegration()],
+ traces_sample_rate=0.1,
+ environment=ENVIRONMENT,
+)
+```
+
+### 18.5 Log Aggregation
+
+**ELK Stack (будущее):**
+- Filebeat → Logstash → Elasticsearch → Kibana
+- Или: Loki + Grafana
+
+---
+
+## 19. Troubleshooting
+### 19.1 Частые проблемы
+
+**Проблема:** WebSocket отключается
+```
+Решение:
+- Проверить nginx конфигурацию (proxy_read_timeout)
+- Проверить keepalive настройки
+- Клиент: reconnect logic
+```
+
+**Проблема:** Агент не видит задачи
+```
+Решение:
+- Проверить agent token
+- Проверить project membership
+- Проверить listen mode (all vs mentions)
+```
+
+**Проблема:** Медленные запросы к БД
+```
+Решение:
+- Проверить индексы
+- Проверить connection pool
+- Включить slow query log
+- EXPLAIN ANALYZE запроса
+```
+
+### 19.2 Диагностика
+
+**Проверка здоровья системы:**
+```bash
+# Backend
+curl http://localhost:8100/api/health
+
+# Database
+psql -c "SELECT 1"
+
+# Redis (если есть)
+redis-cli ping
+
+# Disk space
+df -h /var/www/team-board
+```
+
+**Логи:**
+```bash
+# Tracker logs
+docker-compose logs tracker | grep ERROR
+
+# Nginx logs
+tail -f /var/log/nginx/error.log
+
+# System logs
+journalctl -u picogent -f
+```
+
+**Database queries:**
+```sql
+-- Активные подключения
+SELECT count(*) FROM pg_stat_activity;
+
+-- Медленные запросы
+SELECT query, calls, total_time
+FROM pg_stat_statements
+ORDER BY total_time DESC
+LIMIT 10;
+
+-- Размер таблиц
+SELECT schemaname, tablename,
+ pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
+FROM pg_tables
+WHERE schemaname = 'public'
+ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
+```
+
+### 19.3 Recovery процедуры
+
+**Восстановление БД:**
+```bash
+# Backup
+pg_dump teamboard > backup_$(date +%Y%m%d).sql
+
+# Restore
+psql teamboard < backup_20260313.sql
+```
+
+**Откат миграции:**
+```bash
+alembic downgrade -1
+```
+
+**Перезапуск сервисов:**
+```bash
+docker-compose restart tracker
+sudo systemctl restart picogent
+sudo systemctl reload nginx
+```
+
+---
+
+## 20. Приложения
+### D. Глоссарий
+
+| Термин | Определение |
+|--------|------------|
+| **Tracker** | Единый backend-сервис |
+| **Picogent** | AI-агент фреймворк |
+| **Member** | Участник (человек или агент) |
+| **Project** | Проект с задачами и чатом |
+| **Task** | Задача на канбан-доске |
+| **MCP** | Model Context Protocol |
+| **BFF** | Backend for Frontend (не используется) |
+
+### E. Changelog
+
+**2026-03-13 (v1.1):**
+- Добавлены разделы 14-19 (Deployment, Testing, Performance, Security, Monitoring, Troubleshooting)
+- Расширена документация
+- Aurora Edition
+
+**2026-03-13 (v1.0):**
+- Initial specification
+- Все основные разделы
+
+### F. Roadmap Details
+
+**Q1 2026:**
+- RBAC implementation
+- Advanced permissions
+- Audit logging
+
+**Q2 2026:**
+- GitHub/GitLab integration
+- Webhooks
+- External API
+
+**Q3 2026:**
+- Multi-tenant architecture
+- SaaS preparation
+- Enterprise features
+
+**Q4 2026:**
+- Mobile application (React Native)
+- Offline support
+- Push notifications
+
+### G. API Response Examples
+
+**GET /api/projects:**
+```json
+{
+ "projects": [
+ {
+ "id": "uuid",
+ "slug": "my-project",
+ "name": "My Project",
+ "description": "Description",
+ "color": "#3B82F6",
+ "archived": false,
+ "created_at": "2026-03-13T10:00:00Z",
+ "members_count": 5,
+ "tasks_count": 23
+ }
+ ],
+ "total": 10,
+ "page": 1,
+ "per_page": 20
+}
+```
+
+**POST /api/projects/my-project/tasks:**
+```json
+{
+ "id": "uuid",
+ "slug": "TASK-123",
+ "title": "Implement feature X",
+ "description": "Detailed description",
+ "status": "todo",
+ "priority": "high",
+ "assignee": null,
+ "labels": [
+ {"id": "uuid", "name": "feature", "color": "#10B981"}
+ ],
+ "created_at": "2026-03-13T10:00:00Z",
+ "actor": {
+ "id": "uuid",
+ "slug": "coder",
+ "name": "Кодер"
+ }
+}
+```
+
+### H. Database Schema (ER Diagram)
+
+```
+┌─────────────┐
+│ Member │
+├─────────────┤
+│ id (PK) │
+│ slug │
+│ name │
+│ type │
+└──────┬──────┘
+ │
+ │ 1:N
+ │
+┌──────┴──────────┐
+│ ProjectMember │
+├────────────────┤
+│ project_id (FK)│
+│ member_id (FK) │
+│ role │
+└──────┬──────────┘
+ │
+ │ N:1
+ │
+┌──────┴──────────┐
+│ Project │
+├────────────────┤
+│ id (PK) │
+│ slug │
+│ name │
+└──────┬─────────┘
+ │
+ │ 1:N
+ │
+┌──────┴──────────┐
+│ Task │
+├────────────────┤
+│ id (PK) │
+│ project_id (FK)│
+│ assignee_id(FK)│
+│ parent_id (FK) │
+└────────────────┘
+```
+
+---
+
*Документ поддерживается Авророй. Последнее обновление: 2026-03-13*
+*Версия: Aurora Edition 1.1*