"""baseline (squashed) — pre-phase1 core schema Revision ID: 0003_add_user_active Revises: Create Date: 2026-06-26 Squashed baseline that restores the missing root of the tenant migration chain. The original 0001/0002/0003_add_user_active migrations were lost; phase1's down_revision pointed at a non-existent '0003_add_user_active', leaving the chain with no base and unbuildable by Alembic. This revision recreates the FULL current application schema (generated from the SQLAlchemy models) with INFORMATION_SCHEMA existence guards (Rule 14), so it is: * a complete no-op on existing databases (e.g. tenant-zero / LT, already at a later head) — Alembic treats it as applied ancestry and never runs it; * the schema builder for FRESH tenant databases. IMPORTANT — fresh tenant provisioning uses "upgrade to THIS revision, then stamp head" (see control/tenant_migrate.bootstrap_tenant). The historical phase1..phaseN migrations are NOT replayed on fresh DBs (several are not idempotent), so this baseline must represent the complete schema on its own. """ from alembic import op import sqlalchemy as sa revision = '0003_add_user_active' down_revision = None branch_labels = None depends_on = None def _table_exists(bind, table): return bind.execute(sa.text( "SELECT COUNT(*) FROM information_schema.tables " "WHERE table_schema = DATABASE() AND table_name = :t" ), {'t': table}).scalar() > 0 def _index_exists(bind, table, index): return bind.execute(sa.text( "SELECT COUNT(*) FROM information_schema.statistics " "WHERE table_schema = DATABASE() AND table_name = :t AND index_name = :i" ), {'t': table, 'i': index}).scalar() > 0 def upgrade(): bind = op.get_bind() if not _table_exists(bind, 'notification_matrix'): op.execute(sa.text("""CREATE TABLE notification_matrix ( id INTEGER NOT NULL AUTO_INCREMENT, event_type VARCHAR(50) NOT NULL, role_key VARCHAR(30) NOT NULL, enabled BOOL NOT NULL, custom_emails TEXT, PRIMARY KEY (id), CONSTRAINT uq_notif_matrix_event_role UNIQUE (event_type, role_key) )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'users'): op.execute(sa.text("""CREATE TABLE users ( id INTEGER NOT NULL AUTO_INCREMENT, username VARCHAR(100) NOT NULL, full_name VARCHAR(150), email VARCHAR(255) NOT NULL, password_hash VARCHAR(255) NOT NULL, `role` ENUM('admin','director','inspector','project_manager','customer') NOT NULL, created_at DATETIME, active BOOL NOT NULL, password_set BOOL NOT NULL, set_password_token VARCHAR(64), set_password_token_expires DATETIME, PRIMARY KEY (id) )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _index_exists(bind, 'users', 'ix_users_email'): op.execute(sa.text("CREATE UNIQUE INDEX ix_users_email ON users (email)")) if not _index_exists(bind, 'users', 'ix_users_set_password_token'): op.execute(sa.text("CREATE INDEX ix_users_set_password_token ON users (set_password_token)")) if not _index_exists(bind, 'users', 'ix_users_username'): op.execute(sa.text("CREATE UNIQUE INDEX ix_users_username ON users (username)")) if not _table_exists(bind, 'api_device_tokens'): op.execute(sa.text("""CREATE TABLE api_device_tokens ( id INTEGER NOT NULL AUTO_INCREMENT, user_id INTEGER NOT NULL, device_id VARCHAR(64) NOT NULL, apns_token VARCHAR(200) NOT NULL, device_name VARCHAR(100), app_version VARCHAR(20), ios_version VARCHAR(20), registered_at DATETIME NOT NULL, last_seen_at DATETIME, PRIMARY KEY (id), CONSTRAINT uq_device_token_user_device UNIQUE (user_id, device_id), FOREIGN KEY(user_id) REFERENCES users (id) ON DELETE CASCADE )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _index_exists(bind, 'api_device_tokens', 'ix_api_device_tokens_user_id'): op.execute(sa.text("CREATE INDEX ix_api_device_tokens_user_id ON api_device_tokens (user_id)")) if not _table_exists(bind, 'api_refresh_tokens'): op.execute(sa.text("""CREATE TABLE api_refresh_tokens ( id INTEGER NOT NULL AUTO_INCREMENT, user_id INTEGER NOT NULL, token_hash VARCHAR(64) NOT NULL, device_id VARCHAR(64), device_name VARCHAR(100), created_at DATETIME NOT NULL, expires_at DATETIME NOT NULL, revoked BOOL NOT NULL, PRIMARY KEY (id), FOREIGN KEY(user_id) REFERENCES users (id) ON DELETE CASCADE )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _index_exists(bind, 'api_refresh_tokens', 'ix_api_refresh_tokens_token_hash'): op.execute(sa.text("CREATE UNIQUE INDEX ix_api_refresh_tokens_token_hash ON api_refresh_tokens (token_hash)")) if not _index_exists(bind, 'api_refresh_tokens', 'ix_api_refresh_tokens_user_id'): op.execute(sa.text("CREATE INDEX ix_api_refresh_tokens_user_id ON api_refresh_tokens (user_id)")) if not _table_exists(bind, 'audit_logs'): op.execute(sa.text("""CREATE TABLE audit_logs ( id INTEGER NOT NULL AUTO_INCREMENT, user_id INTEGER, username VARCHAR(100) NOT NULL, user_role VARCHAR(20) NOT NULL, action VARCHAR(50) NOT NULL, entity_type VARCHAR(50) NOT NULL, entity_id INTEGER, entity_label VARCHAR(255), details TEXT, created_at DATETIME NOT NULL, ip_address VARCHAR(45), PRIMARY KEY (id), FOREIGN KEY(user_id) REFERENCES users (id) ON DELETE SET NULL )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _index_exists(bind, 'audit_logs', 'ix_audit_logs_action'): op.execute(sa.text("CREATE INDEX ix_audit_logs_action ON audit_logs (action)")) if not _index_exists(bind, 'audit_logs', 'ix_audit_logs_created_at'): op.execute(sa.text("CREATE INDEX ix_audit_logs_created_at ON audit_logs (created_at)")) if not _index_exists(bind, 'audit_logs', 'ix_audit_logs_entity_type'): op.execute(sa.text("CREATE INDEX ix_audit_logs_entity_type ON audit_logs (entity_type)")) if not _table_exists(bind, 'broadcasts'): op.execute(sa.text("""CREATE TABLE broadcasts ( id INTEGER NOT NULL AUTO_INCREMENT, title VARCHAR(255) NOT NULL, body TEXT NOT NULL, target_roles JSON NOT NULL, sent_by_id INTEGER, sent_at DATETIME NOT NULL, recipient_count INTEGER NOT NULL, PRIMARY KEY (id), FOREIGN KEY(sent_by_id) REFERENCES users (id) ON DELETE SET NULL )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'device_registrations'): op.execute(sa.text("""CREATE TABLE device_registrations ( id INTEGER NOT NULL AUTO_INCREMENT, device_id VARCHAR(64) NOT NULL, user_id INTEGER NOT NULL, device_name VARCHAR(255) NOT NULL, app_version VARCHAR(32) NOT NULL, ios_version VARCHAR(32) NOT NULL, registered_at DATETIME NOT NULL, last_seen_at DATETIME NOT NULL, PRIMARY KEY (id), FOREIGN KEY(user_id) REFERENCES users (id) )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _index_exists(bind, 'device_registrations', 'ix_device_registrations_device_id'): op.execute(sa.text("CREATE UNIQUE INDEX ix_device_registrations_device_id ON device_registrations (device_id)")) if not _index_exists(bind, 'device_registrations', 'ix_device_registrations_user_id'): op.execute(sa.text("CREATE INDEX ix_device_registrations_user_id ON device_registrations (user_id)")) if not _table_exists(bind, 'inspection_templates'): op.execute(sa.text("""CREATE TABLE inspection_templates ( id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL, description TEXT, frequency ENUM('daily','weekly','monthly','quarterly'), created_by INTEGER, created_at DATETIME, form_schema JSON, active BOOL NOT NULL, PRIMARY KEY (id), FOREIGN KEY(created_by) REFERENCES users (id) )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'notification_preferences'): op.execute(sa.text("""CREATE TABLE notification_preferences ( id INTEGER NOT NULL AUTO_INCREMENT, user_id INTEGER NOT NULL, event_type VARCHAR(50) NOT NULL, email_enabled BOOL NOT NULL, digest_mode BOOL NOT NULL, digest_frequency VARCHAR(10) NOT NULL, PRIMARY KEY (id), CONSTRAINT uq_notif_pref_user_event UNIQUE (user_id, event_type), FOREIGN KEY(user_id) REFERENCES users (id) ON DELETE CASCADE )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _index_exists(bind, 'notification_preferences', 'ix_notification_preferences_user_id'): op.execute(sa.text("CREATE INDEX ix_notification_preferences_user_id ON notification_preferences (user_id)")) if not _table_exists(bind, 'projects'): op.execute(sa.text("""CREATE TABLE projects ( id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL, description TEXT, project_manager_id INTEGER, active BOOL NOT NULL, created_at DATETIME NOT NULL, PRIMARY KEY (id), FOREIGN KEY(project_manager_id) REFERENCES users (id) )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'checklist_items'): op.execute(sa.text("""CREATE TABLE checklist_items ( id INTEGER NOT NULL AUTO_INCREMENT, template_id INTEGER NOT NULL, category VARCHAR(100), item_description TEXT NOT NULL, scoring_type ENUM('pass_fail','rating_5','rating_10'), weight NUMERIC(3, 2), requires_photo BOOL, display_order INTEGER, PRIMARY KEY (id), FOREIGN KEY(template_id) REFERENCES inspection_templates (id) )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'facilities'): op.execute(sa.text("""CREATE TABLE facilities ( id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL, address TEXT, contact_person VARCHAR(100), contact_phone VARCHAR(20), active BOOL, created_at DATETIME, project_id INTEGER, PRIMARY KEY (id), FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE SET NULL )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _index_exists(bind, 'facilities', 'ix_facilities_project_id'): op.execute(sa.text("CREATE INDEX ix_facilities_project_id ON facilities (project_id)")) if not _table_exists(bind, 'inspector_assignments'): op.execute(sa.text("""CREATE TABLE inspector_assignments ( id INTEGER NOT NULL AUTO_INCREMENT, user_id INTEGER NOT NULL, project_id INTEGER NOT NULL, created_at DATETIME NOT NULL, PRIMARY KEY (id), CONSTRAINT uq_inspector_project UNIQUE (user_id, project_id), FOREIGN KEY(user_id) REFERENCES users (id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE CASCADE )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _index_exists(bind, 'inspector_assignments', 'ix_inspector_assignments_user_id'): op.execute(sa.text("CREATE INDEX ix_inspector_assignments_user_id ON inspector_assignments (user_id)")) if not _table_exists(bind, 'areas'): op.execute(sa.text("""CREATE TABLE areas ( id INTEGER NOT NULL AUTO_INCREMENT, facility_id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, area_type VARCHAR(50), PRIMARY KEY (id), FOREIGN KEY(facility_id) REFERENCES facilities (id) )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'customer_assignments'): op.execute(sa.text("""CREATE TABLE customer_assignments ( id INTEGER NOT NULL AUTO_INCREMENT, user_id INTEGER NOT NULL, project_id INTEGER NOT NULL, facility_id INTEGER, created_at DATETIME NOT NULL, PRIMARY KEY (id), CONSTRAINT uq_customer_assignment UNIQUE (user_id, project_id, facility_id), FOREIGN KEY(user_id) REFERENCES users (id) ON DELETE CASCADE, FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE CASCADE, FOREIGN KEY(facility_id) REFERENCES facilities (id) ON DELETE CASCADE )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _index_exists(bind, 'customer_assignments', 'ix_customer_assignments_facility_id'): op.execute(sa.text("CREATE INDEX ix_customer_assignments_facility_id ON customer_assignments (facility_id)")) if not _index_exists(bind, 'customer_assignments', 'ix_customer_assignments_project_id'): op.execute(sa.text("CREATE INDEX ix_customer_assignments_project_id ON customer_assignments (project_id)")) if not _index_exists(bind, 'customer_assignments', 'ix_customer_assignments_user_id'): op.execute(sa.text("CREATE INDEX ix_customer_assignments_user_id ON customer_assignments (user_id)")) if not _table_exists(bind, 'facility_score_alerts'): op.execute(sa.text("""CREATE TABLE facility_score_alerts ( id INTEGER NOT NULL AUTO_INCREMENT, facility_id INTEGER NOT NULL, sent_at DATETIME NOT NULL, current_avg NUMERIC(5, 2) NOT NULL, prior_avg NUMERIC(5, 2) NOT NULL, delta NUMERIC(5, 2) NOT NULL, PRIMARY KEY (id), FOREIGN KEY(facility_id) REFERENCES facilities (id) ON DELETE CASCADE )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'scheduled_reports'): op.execute(sa.text("""CREATE TABLE scheduled_reports ( id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL, report_type ENUM('summary','facility','issues') NOT NULL, frequency ENUM('daily','weekly','monthly') NOT NULL, facility_id INTEGER, recipients JSON NOT NULL, include_pdf BOOL NOT NULL, include_csv BOOL NOT NULL, active BOOL NOT NULL, created_by INTEGER, created_at DATETIME NOT NULL, last_sent_at DATETIME, next_send_at DATETIME, PRIMARY KEY (id), FOREIGN KEY(facility_id) REFERENCES facilities (id) ON DELETE SET NULL, FOREIGN KEY(created_by) REFERENCES users (id) ON DELETE SET NULL )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'support_tickets'): op.execute(sa.text("""CREATE TABLE support_tickets ( id INTEGER NOT NULL AUTO_INCREMENT, customer_id INTEGER, facility_id INTEGER, subject VARCHAR(200) NOT NULL, body TEXT NOT NULL, status VARCHAR(20) NOT NULL, created_at DATETIME NOT NULL, PRIMARY KEY (id), FOREIGN KEY(customer_id) REFERENCES users (id) ON DELETE SET NULL, FOREIGN KEY(facility_id) REFERENCES facilities (id) ON DELETE SET NULL )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'inspections'): op.execute(sa.text("""CREATE TABLE inspections ( id INTEGER NOT NULL AUTO_INCREMENT, template_id INTEGER NOT NULL, facility_id INTEGER NOT NULL, area_id INTEGER, inspector_id INTEGER NOT NULL, inspection_date DATETIME NOT NULL, overall_score NUMERIC(5, 2), status ENUM('in_progress','completed','flagged'), notes TEXT, form_data JSON, completed_at DATETIME, mobile_local_id VARCHAR(64), submit_latitude NUMERIC(10, 7), submit_longitude NUMERIC(10, 7), parent_inspection_id INTEGER, follow_up_required BOOL NOT NULL, follow_up_note TEXT, PRIMARY KEY (id), FOREIGN KEY(template_id) REFERENCES inspection_templates (id), FOREIGN KEY(facility_id) REFERENCES facilities (id), FOREIGN KEY(area_id) REFERENCES areas (id), FOREIGN KEY(inspector_id) REFERENCES users (id), FOREIGN KEY(parent_inspection_id) REFERENCES inspections (id) ON DELETE SET NULL )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _index_exists(bind, 'inspections', 'ix_inspections_mobile_local_id'): op.execute(sa.text("CREATE INDEX ix_inspections_mobile_local_id ON inspections (mobile_local_id)")) if not _table_exists(bind, 'support_ticket_replies'): op.execute(sa.text("""CREATE TABLE support_ticket_replies ( id INTEGER NOT NULL AUTO_INCREMENT, ticket_id INTEGER NOT NULL, user_id INTEGER, body TEXT NOT NULL, created_at DATETIME NOT NULL, PRIMARY KEY (id), FOREIGN KEY(ticket_id) REFERENCES support_tickets (id) ON DELETE CASCADE, FOREIGN KEY(user_id) REFERENCES users (id) ON DELETE SET NULL )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'inspection_results'): op.execute(sa.text("""CREATE TABLE inspection_results ( id INTEGER NOT NULL AUTO_INCREMENT, inspection_id INTEGER NOT NULL, checklist_item_id INTEGER NOT NULL, score NUMERIC(5, 2), passed BOOL, comments TEXT, photo_path VARCHAR(255), PRIMARY KEY (id), FOREIGN KEY(inspection_id) REFERENCES inspections (id), FOREIGN KEY(checklist_item_id) REFERENCES checklist_items (id) )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'issues'): op.execute(sa.text("""CREATE TABLE issues ( id INTEGER NOT NULL AUTO_INCREMENT, inspection_id INTEGER, area_id INTEGER, facility_id INTEGER, severity ENUM('low','medium','high','critical') NOT NULL, description TEXT NOT NULL, photo_path VARCHAR(255), status ENUM('open','in_progress','resolved','pending_verification'), assigned_to INTEGER, reported_by INTEGER, reported_at DATETIME, resolved_at DATETIME, result_notes TEXT, result_photos JSON, mobile_photo_paths JSON, verified_by INTEGER, verified_at DATETIME, verification_note TEXT, sla_notified VARCHAR(10), mobile_local_id VARCHAR(64), vendor_name VARCHAR(100), vendor_contact VARCHAR(200), vendor_notes TEXT, PRIMARY KEY (id), FOREIGN KEY(inspection_id) REFERENCES inspections (id), FOREIGN KEY(area_id) REFERENCES areas (id), FOREIGN KEY(facility_id) REFERENCES facilities (id), FOREIGN KEY(assigned_to) REFERENCES users (id), FOREIGN KEY(reported_by) REFERENCES users (id) ON DELETE SET NULL, FOREIGN KEY(verified_by) REFERENCES users (id) ON DELETE SET NULL )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _index_exists(bind, 'issues', 'ix_issues_mobile_local_id'): op.execute(sa.text("CREATE INDEX ix_issues_mobile_local_id ON issues (mobile_local_id)")) if not _table_exists(bind, 'issue_comments'): op.execute(sa.text("""CREATE TABLE issue_comments ( id INTEGER NOT NULL AUTO_INCREMENT, issue_id INTEGER NOT NULL, user_id INTEGER NOT NULL, status_at_time VARCHAR(20), body TEXT NOT NULL, created_at DATETIME NOT NULL, is_customer_visible BOOL NOT NULL, PRIMARY KEY (id), FOREIGN KEY(issue_id) REFERENCES issues (id), FOREIGN KEY(user_id) REFERENCES users (id) )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'issue_followers'): op.execute(sa.text("""CREATE TABLE issue_followers ( id INTEGER NOT NULL AUTO_INCREMENT, issue_id INTEGER NOT NULL, user_id INTEGER NOT NULL, created_at DATETIME NOT NULL, PRIMARY KEY (id), CONSTRAINT uq_issue_follower UNIQUE (issue_id, user_id), FOREIGN KEY(issue_id) REFERENCES issues (id) ON DELETE CASCADE, FOREIGN KEY(user_id) REFERENCES users (id) ON DELETE CASCADE )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _table_exists(bind, 'notifications'): op.execute(sa.text("""CREATE TABLE notifications ( id INTEGER NOT NULL AUTO_INCREMENT, user_id INTEGER NOT NULL, title VARCHAR(255) NOT NULL, body TEXT NOT NULL, link VARCHAR(512), is_read BOOL NOT NULL, created_at DATETIME NOT NULL, issue_id INTEGER, inspection_id INTEGER, event_type VARCHAR(50), digest_pending BOOL NOT NULL, PRIMARY KEY (id), FOREIGN KEY(user_id) REFERENCES users (id), FOREIGN KEY(issue_id) REFERENCES issues (id) ON DELETE CASCADE, FOREIGN KEY(inspection_id) REFERENCES inspections (id) ON DELETE CASCADE )DEFAULT CHARSET=utf8mb4 ENGINE=InnoDB""")) if not _index_exists(bind, 'notifications', 'ix_notifications_digest_pending'): op.execute(sa.text("CREATE INDEX ix_notifications_digest_pending ON notifications (digest_pending)")) if not _index_exists(bind, 'notifications', 'ix_notifications_user_id'): op.execute(sa.text("CREATE INDEX ix_notifications_user_id ON notifications (user_id)")) # phase33 — per-tenant branding settings if not _table_exists(bind, 'tenant_settings'): op.execute(sa.text("""CREATE TABLE tenant_settings ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, company_name VARCHAR(150) NULL, logo_url VARCHAR(500) NULL, primary_color VARCHAR(7) NOT NULL DEFAULT '#1a56db', accent_color VARCHAR(7) NOT NULL DEFAULT '#16a34a', support_email VARCHAR(255) NULL, updated_at DATETIME NOT NULL, updated_by INT NULL, CONSTRAINT fk_tenant_settings_user FOREIGN KEY (updated_by) REFERENCES users(id) ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4""")) def downgrade(): bind = op.get_bind() if _table_exists(bind, 'tenant_settings'): op.execute(sa.text('DROP TABLE tenant_settings')) if _table_exists(bind, 'notifications'): op.execute(sa.text('DROP TABLE notifications')) if _table_exists(bind, 'issue_followers'): op.execute(sa.text('DROP TABLE issue_followers')) if _table_exists(bind, 'issue_comments'): op.execute(sa.text('DROP TABLE issue_comments')) if _table_exists(bind, 'issues'): op.execute(sa.text('DROP TABLE issues')) if _table_exists(bind, 'inspection_results'): op.execute(sa.text('DROP TABLE inspection_results')) if _table_exists(bind, 'support_ticket_replies'): op.execute(sa.text('DROP TABLE support_ticket_replies')) if _table_exists(bind, 'inspections'): op.execute(sa.text('DROP TABLE inspections')) if _table_exists(bind, 'support_tickets'): op.execute(sa.text('DROP TABLE support_tickets')) if _table_exists(bind, 'scheduled_reports'): op.execute(sa.text('DROP TABLE scheduled_reports')) if _table_exists(bind, 'facility_score_alerts'): op.execute(sa.text('DROP TABLE facility_score_alerts')) if _table_exists(bind, 'customer_assignments'): op.execute(sa.text('DROP TABLE customer_assignments')) if _table_exists(bind, 'areas'): op.execute(sa.text('DROP TABLE areas')) if _table_exists(bind, 'inspector_assignments'): op.execute(sa.text('DROP TABLE inspector_assignments')) if _table_exists(bind, 'facilities'): op.execute(sa.text('DROP TABLE facilities')) if _table_exists(bind, 'checklist_items'): op.execute(sa.text('DROP TABLE checklist_items')) if _table_exists(bind, 'projects'): op.execute(sa.text('DROP TABLE projects')) if _table_exists(bind, 'notification_preferences'): op.execute(sa.text('DROP TABLE notification_preferences')) if _table_exists(bind, 'inspection_templates'): op.execute(sa.text('DROP TABLE inspection_templates')) if _table_exists(bind, 'device_registrations'): op.execute(sa.text('DROP TABLE device_registrations')) if _table_exists(bind, 'broadcasts'): op.execute(sa.text('DROP TABLE broadcasts')) if _table_exists(bind, 'audit_logs'): op.execute(sa.text('DROP TABLE audit_logs')) if _table_exists(bind, 'api_refresh_tokens'): op.execute(sa.text('DROP TABLE api_refresh_tokens')) if _table_exists(bind, 'api_device_tokens'): op.execute(sa.text('DROP TABLE api_device_tokens')) if _table_exists(bind, 'users'): op.execute(sa.text('DROP TABLE users')) if _table_exists(bind, 'notification_matrix'): op.execute(sa.text('DROP TABLE notification_matrix'))