From 8f3851290ea787822b338f0dfca6292a0b9fff87 Mon Sep 17 00:00:00 2001 From: Till Tomczak Date: Thu, 29 May 2025 12:15:18 +0200 Subject: [PATCH] "feat: Enhanced DETACHED_INSTANCE documentation and related changes" --- .../DETACHED_INSTANCE_FIX_DOCUMENTATION.md | 1 + backend/app/blueprints/guest.py | 12 ++++++++---- backend/app/database/myp.db-wal | Bin 4152 -> 41232 bytes backend/app/migrate_admin_features.py | 1 + backend/app/models.py | 14 +++++++++++++- 5 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 backend/app/DETACHED_INSTANCE_FIX_DOCUMENTATION.md create mode 100644 backend/app/migrate_admin_features.py diff --git a/backend/app/DETACHED_INSTANCE_FIX_DOCUMENTATION.md b/backend/app/DETACHED_INSTANCE_FIX_DOCUMENTATION.md new file mode 100644 index 000000000..0519ecba6 --- /dev/null +++ b/backend/app/DETACHED_INSTANCE_FIX_DOCUMENTATION.md @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/app/blueprints/guest.py b/backend/app/blueprints/guest.py index cbefce7f5..5222f36c0 100644 --- a/backend/app/blueprints/guest.py +++ b/backend/app/blueprints/guest.py @@ -36,7 +36,9 @@ def approver_required(f): def guest_request_form(): """Formular für Gastanfragen anzeigen.""" with get_cached_session() as db_session: - printers = db_session.query(Printer).filter_by(active=True) + printers = db_session.query(Printer).filter_by(active=True).all() + # Drucker-Liste von der Session trennen für Template-Verwendung + db_session.expunge_all() return render_template('guest_request.html', printers=printers) @guest_blueprint.route('/requests/overview', methods=['GET']) @@ -44,8 +46,10 @@ def guest_requests_overview(): """Öffentliche Übersicht aller Druckanträge mit zensierten persönlichen Daten.""" try: with get_cached_session() as db_session: - # Alle Gastanfragen laden, sortiert nach Erstellungsdatum (neueste zuerst) - guest_requests = db_session.query(GuestRequest).order_by(desc(GuestRequest.created_at)).all() + # Alle Gastanfragen mit eager loading des printer-Relationships laden + guest_requests = db_session.query(GuestRequest).options( + joinedload(GuestRequest.printer) + ).order_by(desc(GuestRequest.created_at)).all() # Daten für Gäste aufbereiten (persönliche Daten zensieren) public_requests = [] @@ -77,7 +81,7 @@ def guest_requests_overview(): else: censored_reason = req.reason[:10] + "***" if len(req.reason) > 10 else "***" - # Drucker-Info laden + # Drucker-Info laden (jetzt durch eager loading verfügbar) printer_name = "Unbekannt" if req.printer: printer_name = req.printer.name diff --git a/backend/app/database/myp.db-wal b/backend/app/database/myp.db-wal index f0d2f4a945c4f58f39df388c821c28606b16f535..40f73abb45ded1d46c5387b74053c4cd52c631a2 100644 GIT binary patch literal 41232 zcmeI4&u`mg7{{Idu4od9=n4!rD-?BQ#C_k_er?A^qNymXqGN5>0)j*3CT{CBNn6L= z3S~k;;<5`!Fl`b-;s6J3oDlp01H_I00PV698k)Fq;dPc~c8N;pI%w(FZCd+v^1NSv z>b}zZeV@n1dmZmf>6?#9(!)})c~^(eT>Ryct*4G%|6rT}T)7q8y!_NT8ce0uhi zXP*ojJK{H`hwR7|Qdv#vI_ zFJYOksDv9_tEm!&Z%CKea{)mP6=TwIxbX=*87C@*hJURo~X=N44=ZSB(7#GC$$Z=A~paow^n z+?7?Y8m(@yaG9!>D$Ed~=!9yN)z1iThgzC29t#O+47mz9P1v2v8G=v8E0zKlEuICHPJaZv_b&*~O ze1W#aH7WUB(o3EeJJ>(~1V8`;KmY_l00ck)1V8`;K;YjaQ0Z;!lDY>g)7h@24PlPV zd(L|Bdn;AjnRoLkOE#X9Qzg6Th}~4+p`^rd&T~ZhLw?@&gVuX1<+DK*M94o0-dpx< zf1@0{ujZztF5mk=wQQpH0nSxzytPy6?mL_93VPZ~6`gX~UaEFoEo~^R`tG8etJX&B z3{xwP&>7eD@s>S?shb;2~ZOd&A=Dv=t)V* zw-VnZdgFzjAH)GR5C8!X009sH0T2KI5CDNAN}!VJNJuC9Mh1rm`}>b~WwTSBTk;)G z)~6`tuRGp~Of({=yxrcm7ss?Ld?F)hX|Eo+TaOBb^nJ#x010$u&F zy0|C;IQ5yCE;C|L!{VA^P?FJk{YV~REG&{XE7H)_-AKk7i=<78Bw>+3&I1jLB+ZKC>W+UL;g0Z(qG>A8RWYbV ze1Wg8T#xtNHhzRJa72fDTs8=R00@8p2!H?xfB*4u)t10T2KI5C8!X009sHfg?%)zQFzX0@2y*0e!we zR3v dict: """ @@ -781,8 +788,13 @@ class GuestRequest(Base): "status": self.status, "printer_id": self.printer_id, "job_id": self.job_id, + "processed_by": self.processed_by, + "processed_at": self.processed_at.isoformat() if self.processed_at else None, + "approval_notes": self.approval_notes, + "rejection_reason": self.rejection_reason, "printer": self.printer.to_dict() if self.printer else None, - "job": self.job.to_dict() if self.job else None + "job": self.job.to_dict() if self.job else None, + "processed_by_user": self.processed_by_user.to_dict() if self.processed_by_user else None } def generate_otp(self) -> str: