dataflow-server / database.py
Ilirt's picture
upload
5aaca54 verified
Raw History Blame Contribute Delete
9.23 kB
"""
DataFlow Server — Database Engine & Session
"""
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from sqlalchemy.orm import Session
from models import Base, User, Project, Task, Expense, Document, AIForecast, Notification, SubTask
from datetime import datetime, timedelta
from passlib.context import CryptContext
import uuid
import os
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite+aiosqlite:///./dataflow.db")
engine = create_async_engine(DATABASE_URL, echo=False)
AsyncSessionLocal = async_sessionmaker(engine, expire_on_commit=False)
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
async def get_db() -> AsyncSession:
async with AsyncSessionLocal() as session:
yield session
async def init_db():
"""Create tables and seed demo data if empty."""
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
async with AsyncSessionLocal() as db:
# Check if already seeded
from sqlalchemy import select, text
result = await db.execute(select(User).limit(1))
if result.scalar_one_or_none() is not None:
return # Already seeded
print("Seeding database with demo data...")
uid1 = str(uuid.uuid4())
uid2 = str(uuid.uuid4())
uid3 = str(uuid.uuid4())
# Users
users = [
User(id=uid1, full_name="Анастасия Иванова", email="nastya@example.com",
hashed_password=pwd_context.hash("123456"), position="Проект-менеджер", role="manager"),
User(id=uid2, full_name="Алексей Петров", email="alexey@example.com",
hashed_password=pwd_context.hash("123456"), position="Backend-разработчик", role="developer"),
User(id=uid3, full_name="Мария Сидорова", email="maria@example.com",
hashed_password=pwd_context.hash("123456"), position="Frontend-разработчик", role="developer"),
]
db.add_all(users)
await db.flush()
# Projects
p1_id = str(uuid.uuid4())
p2_id = str(uuid.uuid4())
projects = [
Project(id=p1_id, name="Мобильное приложение E-Commerce",
description="Разработка мобильного приложения для интернет-магазина",
start_date=datetime(2026, 1, 15), end_date=datetime(2026, 6, 30),
budget=5000000, spent=2750000, status="active", progress=0.55,
risk_level="yellow", owner_id=uid1),
Project(id=p2_id, name="CRM Система",
description="Внедрение CRM системы для отдела продаж",
start_date=datetime(2026, 3, 1), end_date=datetime(2026, 8, 31),
budget=3200000, spent=800000, status="active", progress=0.25,
risk_level="green", owner_id=uid1),
]
db.add_all(projects)
await db.flush()
# Tasks
t1_id = str(uuid.uuid4())
t2_id = str(uuid.uuid4())
tasks = [
Task(id=t1_id, title="Разработка API авторизации", project_id=p1_id,
status="done", priority="high", assignee_id=uid2, assignee_name="Алексей П.",
deadline=datetime(2026, 4, 15),
description="Реализовать REST API для регистрации, входа, JWT и 2FA"),
Task(id=t2_id, title="Дизайн каталога товаров", project_id=p1_id,
status="inProgress", priority="high", assignee_id=uid3, assignee_name="Мария С.",
deadline=datetime(2026, 5, 20),
description="Разработать UI/UX для каталога с фильтрами"),
Task(id=str(uuid.uuid4()), title="Интеграция платежного шлюза", project_id=p1_id,
status="todo", priority="critical", assignee_id=uid2, assignee_name="Алексей П.",
deadline=datetime(2026, 5, 30),
description="Подключить Kaspi Pay и Halyk Bank"),
Task(id=str(uuid.uuid4()), title="Анализ требований CRM", project_id=p2_id,
status="done", priority="high", assignee_id=uid3, assignee_name="Мария С.",
deadline=datetime(2026, 4, 10)),
]
db.add_all(tasks)
await db.flush()
# Subtasks
db.add_all([
SubTask(id=str(uuid.uuid4()), task_id=t1_id, title="JWT Token", completed=True),
SubTask(id=str(uuid.uuid4()), task_id=t1_id, title="Refresh Token", completed=True),
SubTask(id=str(uuid.uuid4()), task_id=t1_id, title="2FA SMS", completed=True),
SubTask(id=str(uuid.uuid4()), task_id=t2_id, title="Wireframes", completed=True),
SubTask(id=str(uuid.uuid4()), task_id=t2_id, title="Mockups", completed=True),
SubTask(id=str(uuid.uuid4()), task_id=t2_id, title="Prototype", completed=False),
])
# Expenses
db.add_all([
Expense(id=str(uuid.uuid4()), project_id=p1_id, title="Зарплата разработчиков (Март)",
amount=900000, category="personnel", status="approved",
date=datetime(2026, 3, 31)),
Expense(id=str(uuid.uuid4()), project_id=p1_id, title="Облачный хостинг AWS",
amount=150000, category="infrastructure", status="approved",
date=datetime(2026, 4, 5)),
Expense(id=str(uuid.uuid4()), project_id=p1_id, title="Лицензия Figma Team",
amount=85000, category="software", status="approved",
date=datetime(2026, 4, 10)),
Expense(id=str(uuid.uuid4()), project_id=p1_id, title="Командировка в Астану",
amount=120000, category="travel", status="pending",
date=datetime(2026, 5, 5)),
Expense(id=str(uuid.uuid4()), project_id=p2_id, title="Консультация по 1С",
amount=200000, category="training", status="approved",
date=datetime(2026, 4, 20)),
])
# Documents
db.add_all([
Document(id=str(uuid.uuid4()), project_id=p1_id,
name="Техническое задание E-Commerce.pdf", type="pdf",
size_bytes=2450000, is_favorite=True),
Document(id=str(uuid.uuid4()), project_id=p1_id,
name="Смета проекта.xlsx", type="xlsx",
size_bytes=340000, is_favorite=True),
Document(id=str(uuid.uuid4()), project_id=p1_id,
name="Счёт AWS Март 2026.pdf", type="pdf", size_bytes=120000,
detected_type="invoice", recognition_confidence=0.97,
extracted_text="Сумма: 150 000 KZT\nДата: 31.03.2026\nПоставщик: Amazon Web Services",
extracted_amount=150000, extracted_supplier="Amazon Web Services"),
])
# AI Forecasts
db.add_all([
AIForecast(id=str(uuid.uuid4()), project_id=p1_id,
current_spent=2750000, planned_budget=5000000,
risk_level="yellow", overrun_probability=35.0,
optimistic_forecast=4600000, realistic_forecast=5200000, pessimistic_forecast=5800000,
recommendations='["Оптимизировать расходы на облачную инфраструктуру","Рассмотреть аутсорсинг QA-тестирования","Пересмотреть приоритеты задач","Использовать Open Source альтернативы"]'),
AIForecast(id=str(uuid.uuid4()), project_id=p2_id,
current_spent=800000, planned_budget=3200000,
risk_level="green", overrun_probability=12.0,
optimistic_forecast=2800000, realistic_forecast=3100000, pessimistic_forecast=3400000,
recommendations='["Проект идёт в рамках бюджета","Рекомендуется создать резерв на интеграцию с 1С"]'),
])
# Notifications
db.add_all([
Notification(id=str(uuid.uuid4()), user_id=uid1,
title="AI прогноз: Внимание",
body="Проект 'E-Commerce' — риск перерасхода 35%",
type="ai"),
Notification(id=str(uuid.uuid4()), user_id=uid1,
title="Новый расход на согласование",
body="Командировка в Астану — 120 000 ₸",
type="expense"),
])
await db.commit()
print("Database seeded successfully!")