Fix medium/low priority review items; update README

Medium:
- Frontend: Error-Handling in fetchUsers/fetchApiKeys (try/catch)
- Frontend: Loading-Race behoben (Promise.all + .finally)
- Frontend: API-Keys maskiert (nur letzte 4 Zeichen sichtbar)
- Tests: Setup-Code aus test_auth.py in conftest.py konsolidiert
- Tests: Fixture-Scope vereinheitlicht (function statt session)

Low:
- bare except in database.py → except Exception
- datetime.utcnow → datetime.now(timezone.utc) durchgängig
- DateTime(timezone=True) in allen Modell-Spalten
- .gitignore hinzugefügt (.env, *.db, __pycache__, .idea, node_modules)

Docs:
- README aktualisiert (Sicherheit, Konfiguration, Projektstruktur, Tests)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Oliver Hofmann
2026-04-27 21:48:26 +02:00
co-authored by Claude Sonnet 4.6
parent bf694b79e2
commit cfa874a4c3
9 changed files with 188 additions and 214 deletions
+20 -10
View File
@@ -2,33 +2,43 @@ import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './styles.css';
const maskKey = (key) => `••••••••${key.slice(-4)}`;
function App() {
const [users, setUsers] = useState([]);
const [apiKeys, setApiKeys] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetchUsers();
fetchApiKeys();
setLoading(false);
Promise.all([fetchUsers(), fetchApiKeys()]).finally(() => setLoading(false));
}, []);
const fetchUsers = async () => {
const res = await axios.get('/api/users');
setUsers(res.data);
try {
const res = await axios.get('/api/users');
setUsers(res.data);
} catch (err) {
setError('Benutzer konnten nicht geladen werden.');
}
};
const fetchApiKeys = async () => {
const res = await axios.get('/api/api-keys');
setApiKeys(res.data);
try {
const res = await axios.get('/api/api-keys');
setApiKeys(res.data);
} catch (err) {
setError('API-Keys konnten nicht geladen werden.');
}
};
if (loading) return <div>Loading...</div>;
if (error) return <div className="error">{error}</div>;
return (
<div className="container">
<h1>Ollama Proxy Admin</h1>
<section>
<h2>Users</h2>
<table>
@@ -70,7 +80,7 @@ function App() {
<tr key={key.id}>
<td>{key.id}</td>
<td>{key.name}</td>
<td>{key.key}</td>
<td>{maskKey(key.key)}</td>
<td>{key.user_id}</td>
<td>{key.is_active ? 'Active' : 'Inactive'}</td>
</tr>
@@ -82,4 +92,4 @@ function App() {
);
}
export default App;
export default App;