feat: Vor-/Nachname, geteilte Listen zeigen Eigentuemer
Backend: - User.first_name / User.last_name (nullable, Auto-Migrate fuegt sie an) full_name/display_name als Properties + in to_dict - TaskList.owner-Relationship ergaenzt (fehlte, daher wurden geteilte Listen beim Empfaenger nicht korrekt aufgeloest) - /auth/me GET + PUT (Profil bearbeiten: Vorname, Nachname, E-Mail) - /users/search findet jetzt auch nach Vor-/Nachname und liefert full_name/display_name mit - list_tasklists/list_calendars/list_addressbooks liefern owner_full_name und owner_display_name Frontend: - Sidebars bei Kontakten/Kalender/Aufgaben: "(geteilt von <Voller Name>)" mit Fallback auf Username - User-Search-Popup zeigt vollen Namen neben Username - SettingsView: Vorname/Nachname/E-Mail bearbeiten Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,8 @@ class User(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
username = db.Column(db.String(80), unique=True, nullable=False, index=True)
|
||||
email = db.Column(db.String(255), unique=True, nullable=True)
|
||||
first_name = db.Column(db.String(100), nullable=True)
|
||||
last_name = db.Column(db.String(100), nullable=True)
|
||||
password_hash = db.Column(db.String(255), nullable=False)
|
||||
role = db.Column(db.String(20), default='user', nullable=False) # 'admin' or 'user'
|
||||
master_key_salt = db.Column(db.LargeBinary, nullable=True) # For password manager
|
||||
@@ -23,6 +25,7 @@ class User(db.Model):
|
||||
foreign_keys='File.owner_id')
|
||||
calendars = db.relationship('Calendar', backref='owner', lazy='dynamic')
|
||||
address_books = db.relationship('AddressBook', backref='owner', lazy='dynamic')
|
||||
task_lists = db.relationship('TaskList', backref='owner', lazy='dynamic')
|
||||
email_accounts = db.relationship('EmailAccount', backref='user', lazy='dynamic',
|
||||
order_by='EmailAccount.sort_order')
|
||||
password_folders = db.relationship('PasswordFolder', backref='owner', lazy='dynamic')
|
||||
@@ -33,10 +36,25 @@ class User(db.Model):
|
||||
def check_password(self, password):
|
||||
return bcrypt.check_password_hash(self.password_hash, password)
|
||||
|
||||
@property
|
||||
def full_name(self) -> str:
|
||||
"""Vor- + Nachname zusammengesetzt, sonst Leerstring."""
|
||||
parts = [self.first_name or '', self.last_name or '']
|
||||
return ' '.join(p.strip() for p in parts if p and p.strip())
|
||||
|
||||
@property
|
||||
def display_name(self) -> str:
|
||||
"""Voller Name falls vorhanden, sonst Username."""
|
||||
return self.full_name or self.username
|
||||
|
||||
def to_dict(self, include_email=False):
|
||||
data = {
|
||||
'id': self.id,
|
||||
'username': self.username,
|
||||
'first_name': self.first_name or '',
|
||||
'last_name': self.last_name or '',
|
||||
'full_name': self.full_name,
|
||||
'display_name': self.display_name,
|
||||
'role': self.role,
|
||||
'is_active': self.is_active,
|
||||
'storage_quota_mb': self.storage_quota_mb,
|
||||
|
||||
Reference in New Issue
Block a user