""" control/cli.py -------------- Thin operator CLI for the control plane. Schema changes go through Alembic (`alembic -c control/migrations/alembic.ini upgrade head`); this CLI covers the bootstrap actions on top of an already-migrated control DB. python -m control.cli seed python -m control.cli create-superadmin --username admin --email you@example.com python -m control.cli list-plans """ import argparse import getpass import sys from control.base import control_session from control.models import Plan, Superadmin from control.seed import seed_plans def _cmd_seed(_args): created, updated = seed_plans() print(f'Plans seeded — created={created} updated={updated}') def _cmd_list_plans(_args): with control_session() as s: plans = s.query(Plan).order_by(Plan.id).all() if not plans: print('No plans found. Run: python -m control.cli seed') return for p in plans: print(f' [{p.code}] {p.name} ' f'users={p.max_users} facilities={p.max_facilities} ' f'insp/mo={p.max_inspections_month} issues/mo={p.max_issues_month} ' f'custom_domain={p.allow_custom_domain} mobile={p.allow_mobile_api} ' f'sched_reports={p.allow_scheduled_reports} branding={p.allow_branding}') def _cmd_create_superadmin(args): with control_session() as s: if s.query(Superadmin).filter_by(username=args.username).first(): print(f"Superadmin '{args.username}' already exists.") sys.exit(1) if s.query(Superadmin).filter_by(email=args.email).first(): print(f"Email '{args.email}' already in use.") sys.exit(1) password = args.password or getpass.getpass('Password: ') if not password: print('Password cannot be empty.') sys.exit(1) sa = Superadmin(username=args.username, email=args.email, active=True) sa.set_password(password) s.add(sa) print(f"Superadmin '{args.username}' created.") def main(argv=None): parser = argparse.ArgumentParser(prog='control.cli', description='JQC control-plane CLI') sub = parser.add_subparsers(dest='command', required=True) sub.add_parser('seed', help='Seed/upsert baseline plans').set_defaults(func=_cmd_seed) sub.add_parser('list-plans', help='List plans').set_defaults(func=_cmd_list_plans) p_sa = sub.add_parser('create-superadmin', help='Create a superadmin account') p_sa.add_argument('--username', required=True) p_sa.add_argument('--email', required=True) p_sa.add_argument('--password', default=None, help='Omit to be prompted securely.') p_sa.set_defaults(func=_cmd_create_superadmin) args = parser.parse_args(argv) args.func(args) if __name__ == '__main__': main()