# ============================================================================== # Formeleon - Multi-tenant Form Generator # Author: Björn Runden # Module: utils/cli.py # Description: CLI Commands for database seeding and administration. # ============================================================================== import uuid import click from flask.cli import with_appcontext from models import db, Tenant, User, UserRole, FormConfig, TenantStatus def register_cli_commands(app): """ Register custom CLI commands for the application. :param app: Flask application instance """ @app.cli.command('seed-db') @with_appcontext def seed_db(): """Seed the database with test data for development.""" # Check if data already exists if Tenant.query.first(): print('Database already contains data. Use --force to overwrite.') return # Create dev tenant tenant = Tenant( id='tenant_dev_123', name='Development Tenant', public_key='dev-public-key-12345', allowed_origins='http://localhost:5000,http://localhost:8080', status=TenantStatus.ACTIVE ) db.session.add(tenant) # Create sample form sample_form = FormConfig( id='form_sample_001', tenant_id='tenant_dev_123', name='Contact Form', description='Sample contact form for testing', form_structure={ 'version': '1.0', 'fields': [ { 'name': 'name', 'type': 'text', 'label': 'Your Name', 'required': True, 'validation': {'min_length': 2, 'max_length': 100} }, { 'name': 'email', 'type': 'email', 'label': 'Email Address', 'required': True, 'validation': {'pattern': r'^[^@]+@[^@]+\.[^@]+$'} }, { 'name': 'subject', 'type': 'text', 'label': 'Subject', 'required': True }, { 'name': 'message', 'type': 'textarea', 'label': 'Message', 'required': True, 'validation': {'min_length': 10} } ], 'submit_button': { 'text': 'Send Message', 'style': 'primary' } }, settings={ 'email_notification': { 'enabled': False, 'recipients': ['admin@formeleon.local'] }, 'success_message': 'Thank you for your message!', 'recaptcha_enabled': True } ) db.session.add(sample_form) # Create dev admin user admin_user = User( id='user_dev_admin_001', email=app.config.get('DEV_USER_EMAIL', 'dev@formeleon.local'), name=app.config.get('DEV_USER_NAME', 'Dev Admin'), role=UserRole.ADMIN, sub='dev-admin-sub-123' ) db.session.add(admin_user) # Associate user with tenant from models import user_tenant_association db.session.execute( user_tenant_association.insert().values( user_id=admin_user.id, tenant_id=tenant.id ) ) db.session.commit() print(f'Seeded database with tenant {tenant.id}, form {sample_form.id}, and user {admin_user.id}') @app.cli.command('create-tenant') @click.argument('name') @click.argument('public_key') @click.option('--allowed-origins', default='*', help='Comma-separated allowed origins') @with_appcontext def create_tenant(name, public_key, allowed_origins): """Create a new tenant.""" tenant_id = f'tenant_{name.lower().replace(" ", "_")}_{str(uuid.uuid4())[:8]}' tenant = Tenant( id=tenant_id, name=name, public_key=public_key, allowed_origins=allowed_origins ) db.session.add(tenant) db.session.commit() print(f'Created tenant {tenant_id} with public key {public_key}') @app.cli.command('create-user') @click.argument('email') @click.argument('name') @click.option('--role', default='user', help='User role: admin, tenant_admin, user, viewer') @with_appcontext def create_user(email, name, role): """Create a new user.""" from models import UserRole as UR role_enum = getattr(UR, role.upper(), UR.USER) user_id = f'user_{email.split("@")[0]}_{str(uuid.uuid4())[:8]}' user = User( id=user_id, email=email, name=name, role=role_enum ) db.session.add(user) db.session.commit() print(f'Created user {user_id} with email {email} and role {role}')