feat: Kanban touch drag, admins delete backups, bigger share message
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m5s

- Kanban on phones/tablets: hold a card, drag it onto a card or column, release; the page scrolls at the edges
- Admin settings: database backups can be deleted (DELETE /api/v1/admin/backups/{name})
- Share message: large Liste/Aufgabe buttons, close button, tap outside closes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-10-31 11:54:17 +01:00
1 parent da258fdce2
commit f76b0f34ff
14 files changed
+371 -57

No files matched your search

+38
View File
@@ -89,3 +89,41 @@ func mustTime(day string) (t time.Time) {
t, _ = time.Parse("2006-01-02", day)
return t
}
// Admins can delete database snapshots; members cannot, and only real backup names are accepted
func TestAdminDeletesBackups(t *testing.T) {
srv, store, token := setupTestServer(t)
router := srv.Router()
call := func(method, path, tok string) *httptest.ResponseRecorder {
req := httptest.NewRequest(method, path, nil)
req.Header.Set("Authorization", "Bearer "+tok)
rec := httptest.NewRecorder()
router.ServeHTTP(rec, req)
return rec
}
var files []storage.BackupFile
_ = json.Unmarshal(call("POST", "/api/v1/admin/backups", token).Body.Bytes(), &files)
if len(files) != 1 {
t.Fatalf("expected one snapshot, got %+v", files)
}
name := files[0].Name
_, memberToken := newTestUser(t, store, "member@example.com")
if rec := call("DELETE", "/api/v1/admin/backups/"+name, memberToken); rec.Code != http.StatusForbidden {
t.Fatalf("members must not delete backups, got %d", rec.Code)
}
if rec := call("DELETE", "/api/v1/admin/backups/..%2F..%2Fmindsift.db", token); rec.Code != http.StatusNotFound {
t.Fatalf("path tricks must be refused, got %d", rec.Code)
}
rec := call("DELETE", "/api/v1/admin/backups/"+name, token)
if rec.Code != http.StatusOK {
t.Fatalf("delete: %d %s", rec.Code, rec.Body.String())
}
_ = json.Unmarshal(rec.Body.Bytes(), &files)
if len(files) != 0 {
t.Fatalf("snapshot should be gone, got %+v", files)
}
if _, err := os.Stat(filepath.Join(srv.backupRoot(), "system", name)); !os.IsNotExist(err) {
t.Fatalf("file must be removed from disk")
}
}