from __future__ import annotations import argparse import json import sys from getpass import getpass from pathlib import Path from app.db.session import SessionLocal from app.models.user import User from app.services.reference_masterdata import ReferenceMasterdataImportService def cmd_import_reference_masterdata(args: argparse.Namespace) -> int: with SessionLocal() as session: service = ReferenceMasterdataImportService(session) result = service.import_reference_docx( Path(args.reference), dry_run=args.dry_run, update_existing=args.update_existing, create_validation=args.create_validation, ) payload = result.as_dict() if args.json_summary: print(json.dumps(payload, ensure_ascii=False, default=str)) else: for label in ["created", "updated", "unchanged", "conflicts", "errors"]: print(f"{label}: {len(payload[label])}") for item in payload[label]: print(f" - {item}") if result.validation_id: print(f"validation_id: {result.validation_id}") return 0 def cmd_reset_password(args: argparse.Namespace) -> int: from app.core.security import hash_password from sqlalchemy import select with SessionLocal() as session: user = session.scalar(select(User).where(User.email == args.email.lower())) if user is None: raise SystemExit(f"User not found: {args.email}") first = getpass("New password: ") second = getpass("Repeat password: ") if first != second: raise SystemExit("Passwords do not match") user.password_hash = hash_password(first) session.commit() print("Password updated") return 0 def cmd_create_admin(_: argparse.Namespace) -> int: from app.core.security import hash_password from app.models.user import UserRole from sqlalchemy import select email = input("E-Mail: ").strip().lower() first_name = input("Vorname: ").strip() last_name = input("Nachname: ").strip() password = getpass("Passwort: ") password_confirmation = getpass("Passwort bestätigen: ") if password != password_confirmation: raise SystemExit("Passwords do not match") with SessionLocal() as session: existing = session.scalar(select(User).where(User.email == email)) if existing is not None: raise SystemExit("User already exists") session.add( User( email=email, first_name=first_name, last_name=last_name, role=UserRole.ADMIN.value, password_hash=hash_password(password), is_active=True, must_change_password=False, ) ) session.commit() print("Admin user created") return 0 def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(prog="python -m app.cli") subparsers = parser.add_subparsers(dest="command", required=True) import_parser = subparsers.add_parser("import-reference-masterdata") import_parser.add_argument("--reference", required=True) import_parser.add_argument("--dry-run", action="store_true") import_parser.add_argument("--update-existing", action="store_true") import_parser.add_argument("--create-validation", action="store_true") import_parser.add_argument("--json-summary", action="store_true") import_parser.set_defaults(func=cmd_import_reference_masterdata) reset_parser = subparsers.add_parser("reset-password") reset_parser.add_argument("--email", required=True) reset_parser.set_defaults(func=cmd_reset_password) admin_parser = subparsers.add_parser("create-admin") admin_parser.set_defaults(func=cmd_create_admin) return parser def main(argv: list[str] | None = None) -> int: parser = build_parser() args = parser.parse_args(argv) return args.func(args) if __name__ == "__main__": raise SystemExit(main(sys.argv[1:]))