v3.0.1: qualité & stabilité — tests, sécurité, UX consolidée
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped

🧪 Tests: 73 → 130 (+57 tests)
- Upload API, labels sync, commit history (401/400/502/cached)
- File create/update (sha=null, sha=abc)
- Admin delete cascade (12 tests: oauth, tags, workspaces, pages…)
- Gitea status (linked/unlinked/disconnect)
- OAuth link mode (session, redirect, callback)

🔒 Sécurité
- ContentSecurityPolicyMiddleware (CSP headers)
- RateLimitMiddleware (100 req/min/IP)
- Pydantic models: ErrorResponse, SuccessResponse
- Input validation upload (10MB, allowed extensions)
- Pydantic request models

🎨 UX
- static/css/design-tokens.css (500 lines, thèmes + skeletons)
- Toast system: 16 alert() remplacés par toast()
- 59 lignes CSS dupliquées retirées (6 templates)
- Skeletons cohérents sur toutes les vues

⚡ Performance
- Cache TTL sur get_file_commits (consistant avec les autres méthodes)
This commit is contained in:
2026-07-13 23:08:53 -04:00
parent e04b3a38a4
commit de40c2d83e
12 changed files with 1679 additions and 88 deletions
+3 -17
View File
@@ -57,15 +57,6 @@
.color-swatch:hover{transform:scale(1.15);}
.color-swatch.selected{border-color:var(--text);box-shadow:0 0 0 2px var(--accent);}
/* Modal (for tag delete/rename) */
.modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.85);display:flex;align-items:center;justify-content:center;z-index:999;}
.modal-box{background:var(--bg-primary);border:1px solid var(--border);border-radius:12px;padding:24px;min-width:320px;box-shadow:0 12px 40px rgba(0,0,0,.8);}
.modal-box h3{font-size:16px;font-weight:600;color:#fff;}
.settings-input{background:var(--bg-tertiary);border:1px solid var(--border);border-radius:6px;color:var(--text);font-size:13px;padding:6px 10px;outline:none;width:100%;}
.settings-input:focus{border-color:var(--accent,#2383E2);box-shadow:0 0 0 2px rgba(35,131,226,.25);}
.btn-danger{background:#E03E3E;color:#fff;border:none;padding:6px 16px;border-radius:6px;cursor:pointer;font-size:13px;}
.btn-danger:hover{background:#C93535;}
/* Admin tables */
.table-wrap{overflow-x:auto;border-radius:8px;border:1px solid #333;}
.admin-table{width:100%;border-collapse:collapse;font-size:13px;}
@@ -73,7 +64,7 @@
.admin-table td{padding:8px 12px;border-top:1px solid var(--border);color:var(--text);}
.admin-table tr:hover td{background:var(--bg-secondary);}
.stat-card{background:var(--bg-tertiary);border:1px solid var(--border);border-radius:8px;padding:14px;text-align:center;}
.stat-value{font-size:22px;font-weight:700;color:var(--accent,#2383E2);}
.stat-value{font-size:22px;font-weight:700;color:var(--accent);}
.stat-label{font-size:11px;color:var(--text-dim);margin-top:2px;text-transform:uppercase;letter-spacing:.5px;}
.role-badge{display:inline-block;padding:2px 8px;border-radius:10px;font-size:11px;font-weight:500;}
.role-admin{background:rgba(35,131,226,.2);color:#4DA3F5;}
@@ -81,15 +72,10 @@
.status-dot{display:inline-block;width:6px;height:6px;border-radius:50%;margin-right:5px;vertical-align:middle;}
.status-dot.active{background:#0F7B6C;}
.status-dot.inactive{background:#E03E3E;}
.btn-sm{background:transparent;border:1px solid var(--border);color:var(--text-dim);padding:2px 6px;border-radius:4px;cursor:pointer;font-size:12px;}
.btn-sm:hover{background:var(--bg-tertiary);color:var(--text);}
.btn-sm-danger{color:#E03E3E;border-color:#542;}
/* Close button */
.settings-close{position:absolute;top:12px;right:12px;width:32px;height:32px;background:none;border:none;color:var(--text-dim);font-size:20px;cursor:pointer;border-radius:6px;display:flex;align-items:center;justify-content:center;}
.settings-close:hover{background:var(--bg-hover);color:var(--text);}
.settings-select{background:var(--bg-tertiary);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:6px 10px;font-size:13px;outline:none;cursor:pointer;min-width:140px;}
.settings-select:focus{border-color:var(--accent);}
</style>
<div class="settings-overlay" x-data="settingsInit()" @keydown.escape="window.history.back()">
@@ -662,9 +648,9 @@ document.addEventListener('alpine:init', function() {
await this.loadAdminUsers();
} else {
var d = await r.json();
alert(d.error || 'Failed to create user');
window.showToast(d.error || 'Failed to create user', 'error');
}
} catch(e) { alert('Network error'); }
} catch(e) { window.showToast('Network error', 'error'); }
},
async adminUpdateUser() {