Files
lux_fiscal/backend/app/cli.py
T
lauadminandClaude Opus 5.5 b8f2fe6b6e Translate UI and user-facing messages to Ukrainian (#5)
- All frontend pages, labels, notices and errors; html lang=uk, uk-UA money format
- Brand "Assistant System" in the top bar and page title
- Backend error details returned to the UI (auth, orders, receipts,
  cash registers, Checkbox/CRM/NP errors) and CLI output
- Tests updated for the new messages

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:27:39 +03:00

73 lines
2.3 KiB
Python

"""Служебные команды.
python -m app.cli bootstrap # создать первого администратора
python -m app.cli gen-keys # сгенерировать SECRET_KEY и ENCRYPTION_KEY
"""
from __future__ import annotations
import argparse
import asyncio
import secrets
import sys
from sqlalchemy import select
from app.core.config import settings
from app.core.security import hash_password
from app.db.models.user import User, UserRole
from app.db.session import session_scope
async def bootstrap() -> int:
"""Создаёт первого администратора из переменных окружения.
Идемпотентна: повторный запуск ничего не меняет и пароль не сбрасывает.
"""
if not settings.first_admin_password:
print("FIRST_ADMIN_PASSWORD не задано в .env", file=sys.stderr)
return 1
email = settings.first_admin_email.strip().lower()
async with session_scope() as session:
existing = await session.scalar(select(User).where(User.email == email))
if existing is not None:
print(f"Користувач {email} уже існує — нічого не змінено.")
return 0
session.add(
User(
email=email,
full_name=settings.first_admin_name,
password_hash=hash_password(settings.first_admin_password),
role=UserRole.ADMIN,
)
)
print(f"Адміністратора {email} створено.")
print("Змініть пароль після першого входу та приберіть FIRST_ADMIN_PASSWORD з .env.")
return 0
def gen_keys() -> int:
from cryptography.fernet import Fernet
print(f"SECRET_KEY={secrets.token_urlsafe(64)}")
print(f"ENCRYPTION_KEY={Fernet.generate_key().decode()}")
return 0
def main() -> int:
parser = argparse.ArgumentParser(prog="app.cli", description="Службові команди lux_fiscal")
parser.add_argument("command", choices=["bootstrap", "gen-keys"])
args = parser.parse_args()
if args.command == "bootstrap":
return asyncio.run(bootstrap())
return gen_keys()
if __name__ == "__main__":
raise SystemExit(main())