feat: File Locking System (Ein-/Auschecken) + Konflikt-Email
Backend - FileLock Model + API: - POST /files/<id>/lock - Datei auschecken (sperren) - POST /files/<id>/unlock - Datei einchecken (entsperren) - POST /files/<id>/heartbeat - "Datei noch offen" (alle 60s) - GET /files/<id>/lock-status - Sperrstatus abfragen - GET /files/locks - Alle aktiven Sperren auflisten - Auto-Unlock: Kein Heartbeat seit 5 Min -> Sperre wird freigegeben - 423 Locked wenn bereits von anderem User gesperrt - Admin kann fremde Sperren aufheben Dateiliste + Sync-API: - Lock-Info (locked, locked_by, locked_at) pro Datei mitgeliefert - Sync-Tree enthaelt Lock-Status fuer Desktop/Mobile-Clients Web-UI: - Schloss-Icon mit Benutzername bei gesperrten Dateien - Tooltip: "Ausgecheckt von Adam seit 14:30" - Gesperrte Dateien: "Oeffnen nicht moeglich" Toast-Meldung (eigene Sperren sind erlaubt) Konflikt-Email an Admin: - Wer hat die Konflikt-Kopie erstellt (Name + Email) - Welche Datei (Name + Ordnerpfad) - Name der Konflikt-Kopie - Von wem gesperrt (Name + Email + seit wann) - Erklaerungstext was passiert ist Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -179,3 +179,32 @@ def notify_user_created(user, created_by_username):
|
||||
f'Deine Mini-Cloud'
|
||||
)
|
||||
send_system_email(user.email, subject, body)
|
||||
|
||||
|
||||
def notify_conflict_to_admin(conflict_user, conflict_file_name, conflict_copy_name,
|
||||
folder_path, lock_user_name, lock_user_email, locked_since):
|
||||
"""Notify admin about a sync conflict (user edited a locked file)."""
|
||||
from app.models.settings import AppSettings
|
||||
|
||||
admin_email = AppSettings.get('system_email_from', '')
|
||||
if not admin_email:
|
||||
return
|
||||
|
||||
subject = f'Mini-Cloud: Datei-Konflikt - {conflict_file_name}'
|
||||
body = (
|
||||
f'Datei-Konflikt in der Mini-Cloud!\n\n'
|
||||
f'Benutzer: {conflict_user.username}'
|
||||
f'{" (" + conflict_user.email + ")" if conflict_user.email else ""}\n'
|
||||
f'Hat bearbeitet: {conflict_file_name}\n'
|
||||
f'Ordner: {folder_path}\n'
|
||||
f'Konflikt-Kopie: {conflict_copy_name}\n\n'
|
||||
f'Gesperrt von: {lock_user_name}'
|
||||
f'{" (" + lock_user_email + ")" if lock_user_email else ""}\n'
|
||||
f'Gesperrt seit: {locked_since}\n\n'
|
||||
f'Ursache: {conflict_user.username} hat die Datei lokal bearbeitet '
|
||||
f'waehrend {lock_user_name} sie ausgecheckt hatte.\n\n'
|
||||
f'Die Aenderungen von {conflict_user.username} wurden als '
|
||||
f'Konflikt-Kopie gespeichert und muessen manuell zusammengefuehrt werden.\n\n'
|
||||
f'Deine Mini-Cloud'
|
||||
)
|
||||
send_system_email(admin_email, subject, body)
|
||||
|
||||
Reference in New Issue
Block a user