Refactor: Name-Feld entfernen, Email als einziger Identifier

- Name-Spalte aus Nutzertabelle entfernt
- Anzeigename-Feld aus Nutzer-Anlegen-Dialog entfernt
- Username wird automatisch aus Email-Prefix generiert
- UserCreate Model: username jetzt optional

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
claude-dev
2026-03-05 18:55:30 +01:00
Ursprung e5a11d3549
Commit af6040cbf6
4 geänderte Dateien mit 5 neuen und 11 gelöschten Zeilen

Datei anzeigen

@@ -56,7 +56,7 @@ class LicenseResponse(BaseModel):
class UserCreate(BaseModel): class UserCreate(BaseModel):
email: str = Field(min_length=3, max_length=200) email: str = Field(min_length=3, max_length=200)
username: str = Field(min_length=1, max_length=100) username: Optional[str] = Field(default=None, max_length=100)
role: str = Field(default="member", pattern="^(org_admin|member)$") role: str = Field(default="member", pattern="^(org_admin|member)$")

Datei anzeigen

@@ -66,11 +66,12 @@ async def create_user(
if await cursor.fetchone(): if await cursor.fetchone():
raise HTTPException(status_code=400, detail="E-Mail bereits vergeben") raise HTTPException(status_code=400, detail="E-Mail bereits vergeben")
username = data.username if data.username else email.split("@")[0]
now = datetime.now(timezone.utc).isoformat() now = datetime.now(timezone.utc).isoformat()
cursor = await db.execute( cursor = await db.execute(
"""INSERT INTO users (email, username, password_hash, organization_id, role, is_active, created_at) """INSERT INTO users (email, username, password_hash, organization_id, role, is_active, created_at)
VALUES (?, ?, '', ?, ?, 1, ?)""", VALUES (?, ?, '', ?, ?, 1, ?)""",
(email, data.username, org_id, data.role, now), (email, username, org_id, data.role, now),
) )
user_id = cursor.lastrowid user_id = cursor.lastrowid
@@ -91,7 +92,7 @@ async def create_user(
from email_utils.sender import send_email from email_utils.sender import send_email
from email_utils.templates import invite_email from email_utils.templates import invite_email
link = f"{MAGIC_LINK_BASE_URL}/auth/verify?token={token}" link = f"{MAGIC_LINK_BASE_URL}/auth/verify?token={token}"
subject, html = invite_email(data.username, org["name"], code, link) subject, html = invite_email(username, org["name"], code, link)
await send_email(email, subject, html) await send_email(email, subject, html)
except Exception: except Exception:
pass # E-Mail-Fehler nicht fatal pass # E-Mail-Fehler nicht fatal

Datei anzeigen

@@ -101,7 +101,6 @@
<thead> <thead>
<tr> <tr>
<th>E-Mail</th> <th>E-Mail</th>
<th>Name</th>
<th>Rolle</th> <th>Rolle</th>
<th>Status</th> <th>Status</th>
<th>Aktionen</th> <th>Aktionen</th>
@@ -234,10 +233,6 @@
<label for="newUserEmail">E-Mail</label> <label for="newUserEmail">E-Mail</label>
<input type="email" id="newUserEmail" required> <input type="email" id="newUserEmail" required>
</div> </div>
<div class="form-group">
<label for="newUserName">Anzeigename</label>
<input type="text" id="newUserName" required>
</div>
<div class="form-group"> <div class="form-group">
<label for="newUserRole">Rolle</label> <label for="newUserRole">Rolle</label>
<select id="newUserRole"> <select id="newUserRole">

Datei anzeigen

@@ -232,13 +232,12 @@ async function loadOrgUsers(orgId) {
const tbody = document.getElementById("userTable"); const tbody = document.getElementById("userTable");
if (users.length === 0) { if (users.length === 0) {
tbody.innerHTML = '<tr><td colspan="5" class="text-muted">Keine Nutzer</td></tr>'; tbody.innerHTML = '<tr><td colspan="4" class="text-muted">Keine Nutzer</td></tr>';
return; return;
} }
tbody.innerHTML = users.map(u => ` tbody.innerHTML = users.map(u => `
<tr> <tr>
<td>${esc(u.email)}</td> <td>${esc(u.email)}</td>
<td>${esc(u.username)}</td>
<td> <td>
<select class="btn btn-secondary btn-small" onchange="changeRole(${u.id}, this.value)" style="padding: 4px 8px;"> <select class="btn btn-secondary btn-small" onchange="changeRole(${u.id}, this.value)" style="padding: 4px 8px;">
<option value="member" ${u.role === "member" ? "selected" : ""}>Mitglied</option> <option value="member" ${u.role === "member" ? "selected" : ""}>Mitglied</option>
@@ -426,7 +425,6 @@ function setupForms() {
try { try {
await API.post(`/api/users?org_id=${currentOrgId}`, { await API.post(`/api/users?org_id=${currentOrgId}`, {
email: document.getElementById("newUserEmail").value, email: document.getElementById("newUserEmail").value,
username: document.getElementById("newUserName").value,
role: document.getElementById("newUserRole").value, role: document.getElementById("newUserRole").value,
}); });
closeModal("modalNewUser"); closeModal("modalNewUser");