""" Migration: v2 Neue Struktur (Aufmaß-Entity + Rechtesystem) - users: neue Spalten (darf_*) + rolle admin -> firmadmin - neu: aufmass Tabelle + project_access Tabelle - positionen: neue Spalte aufmass_id """ import sys import os sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) from app import create_app from app.extensions import db from app.models.user import User from app.models.project import Project from app.models.position import Position from app.models.aufmass import Aufmass from app.models.project_access import ProjectAccess from sqlalchemy import inspect, text app = create_app() def _spalte_existiert(table, column): insp = inspect(db.engine) cols = [c['name'] for c in insp.get_columns(table)] return column in cols def _tabelle_existiert(table): insp = inspect(db.engine) return table in insp.get_table_names() with app.app_context(): print("=== Migration v2 starten ===") # 1. User-Spalten hinzufügen if not _spalte_existiert('users', 'darf_projekte_anlegen'): with db.engine.connect() as conn: conn.execute(text("ALTER TABLE users ADD COLUMN darf_projekte_anlegen BOOLEAN DEFAULT 0")) conn.execute(text("ALTER TABLE users ADD COLUMN darf_lv_verwalten BOOLEAN DEFAULT 0")) conn.execute(text("ALTER TABLE users ADD COLUMN darf_preise_sehen BOOLEAN DEFAULT 0")) conn.execute(text("ALTER TABLE users ADD COLUMN darf_aufmass_verwalten BOOLEAN DEFAULT 0")) conn.commit() print(" -> User-Spalten hinzugefügt") else: print(" -> User-Spalten bereits vorhanden") # 2. Rolle migrieren: admin -> firmadmin, mitarbeiter bleibt count = User.query.filter_by(rolle='admin').update({'rolle': 'firmadmin'}) db.session.commit() print(f" -> {count} User von 'admin' -> 'firmadmin' migriert") # 3. firmadmin bekommt automatisch alle Rechte for u in User.query.filter_by(rolle='firmadmin').all(): u.darf_projekte_anlegen = True u.darf_lv_verwalten = True u.darf_preise_sehen = True u.darf_aufmass_verwalten = True db.session.commit() print(" -> firmadmin-Rechte gesetzt") # 4. Aufmass-Tabelle anlegen (wenn nicht vorhanden, wird von db.create_all() erstellt) db.create_all() print(" -> Tabellen erstellt/aktualisiert") # 5. aufmass_id zu positionen hinzufügen if not _spalte_existiert('positionen', 'aufmass_id'): with db.engine.connect() as conn: conn.execute(text("ALTER TABLE positionen ADD COLUMN aufmass_id INTEGER REFERENCES aufmass(id)")) conn.commit() print(" -> aufmass_id zu positionen hinzugefügt") else: print(" -> aufmass_id bereits vorhanden") # 6. Für jedes Projekt ohne Aufmaß ein Standard-Aufmaß anlegen projekte = Project.query.all() for p in projekte: bestand = Aufmass.query.filter_by(project_id=p.id).first() if not bestand: a = Aufmass(project_id=p.id, name='Standard', typ='', sortierung=0) db.session.add(a) db.session.flush() # Bestehende Positionen an das Standard-Aufmaß hängen Position.query.filter_by(project_id=p.id, aufmass_id=None).update({'aufmass_id': a.id}) print(f" -> Standard-Aufmaß für Projekt {p.id} ({p.sm_nr}) angelegt") db.session.commit() # 7. Noch verwaiste Positionen ohne aufmass_id rest = Position.query.filter_by(aufmass_id=None).count() if rest: print(f" -> WARNUNG: {rest} Positionen ohne aufmass_id!") # Für jedes Projekt ohne aufmass_id die erste gefundene Position suchen orphans = Position.query.filter_by(aufmass_id=None).all() for pos in orphans: a = Aufmass.query.filter_by(project_id=pos.project_id).first() if a: pos.aufmass_id = a.id db.session.commit() print(f" -> {len(orphans)} verwaiste Positionen zugeordnet") print("=== Migration v2 abgeschlossen ===")