"""Seed initial reference data. Run once after migrations: python seed.py""" import os from dotenv import load_dotenv load_dotenv() from sqlalchemy import create_engine from sqlalchemy.orm import Session from app.auth.security import hash_password from app.models import Role, User, Currency, AccountType, OperationType, Category engine = create_engine(os.environ["DATABASE_URL"]) ROLES = [ ("admin", "Full access — manages users, all financial data"), ("accountant", "Manages all financial data, cannot manage users"), ("user", "Manages own financial data"), ("viewer", "Read-only access to own data"), ] CURRENCIES = [ ("RUB", "Российский рубль", "₽"), ("USD", "Доллар США", "$"), ("EUR", "Евро", "€"), ("GBP", "Фунт стерлингов", "£"), ("CNY", "Китайский юань", "¥"), ("BTC", "Биткоин", "₿"), ] ACCOUNT_TYPES = [ ("Наличные", "wallet", "Наличные деньги"), ("Банковский счёт", "bank", "Текущий/расчётный счёт"), ("Кредитная карта", "credit-card", "Кредитная карта"), ("Накопительный", "piggy-bank", "Вклад / накопительный счёт"), ("Инвестиционный", "chart-line", "Брокерский или инвест. счёт"), ("Криптовалюта", "bitcoin", "Криптовалютный кошелёк"), ("Другое", "dots", "Прочий тип счёта"), ] OPERATION_TYPES = [ ("income", "Доход — пополнение счёта"), ("expense", "Расход — списание со счёта"), ("transfer", "Перевод между счетами"), ] CATEGORIES = [ # (name, type, icon, color) # --- Доходы --- ("Зарплата", "income", "briefcase", "#4CAF50"), ("Фриланс", "income", "laptop", "#8BC34A"), ("Инвестиции", "income", "chart-line", "#00BCD4"), ("Подарки", "income", "gift", "#E91E63"), ("Прочие доходы", "income", "plus-circle", "#9E9E9E"), # --- Расходы --- ("Продукты", "expense", "shopping-cart","#FF5722"), ("Транспорт", "expense", "car", "#FF9800"), ("ЖКХ", "expense", "home", "#795548"), ("Здоровье", "expense", "heart", "#F44336"), ("Рестораны и кафе", "expense", "utensils", "#E91E63"), ("Развлечения", "expense", "gamepad", "#9C27B0"), ("Одежда", "expense", "tshirt", "#3F51B5"), ("Образование", "expense", "book", "#2196F3"), ("Путешествия", "expense", "plane", "#03A9F4"), ("Связь и интернет", "expense", "wifi", "#009688"), ("Подписки", "expense", "repeat", "#607D8B"), ("Прочие расходы", "expense", "minus-circle", "#9E9E9E"), # --- Переводы --- ("Переводы", "transfer", "arrows-h", "#607D8B"), ] def seed(): with Session(engine) as db: # Roles role_map: dict[str, Role] = {} for name, desc in ROLES: role = db.query(Role).filter(Role.name == name).first() if not role: role = Role(name=name, description=desc) db.add(role) db.flush() role_map[name] = role # Admin user if not db.query(User).filter(User.username == "admin").first(): admin_pwd = os.getenv("ADMIN_PASSWORD", "Admin1234!") admin = User( username="admin", email="admin@finance.local", password_hash=hash_password(admin_pwd), role_id=role_map["admin"].id, ) db.add(admin) print(f"[seed] Admin user created. Password from ADMIN_PASSWORD env (default: Admin1234!)") # Currencies for code, name, symbol in CURRENCIES: if not db.query(Currency).filter(Currency.code == code).first(): db.add(Currency(code=code, name=name, symbol=symbol)) # Account types for name, icon, desc in ACCOUNT_TYPES: if not db.query(AccountType).filter(AccountType.name == name).first(): db.add(AccountType(name=name, icon=icon, description=desc)) # Operation types for name, desc in OPERATION_TYPES: if not db.query(OperationType).filter(OperationType.name == name).first(): db.add(OperationType(name=name, description=desc)) # System categories (user_id=None) for name, ctype, icon, color in CATEGORIES: if not db.query(Category).filter(Category.name == name, Category.user_id == None).first(): db.add(Category(name=name, type=ctype, icon=icon, color=color, user_id=None)) db.commit() print("[seed] Done.") if __name__ == "__main__": seed()