Spaces:
Sleeping
Sleeping
File size: 9,234 Bytes
5aaca54 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | """
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!")
|