Merge dev into main (v0.17.3)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 27s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 27s
This commit is contained in:
commit
ec54b9c4f7
6 files changed
+54
-7
No files matched your search
+7
-1
@@ -6,6 +6,11 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.17.3] - 2026-10-31
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fälligkeits-Benachrichtigungen kamen nach jedem Verschieben im Kanban-Board erneut: Beim Verschieben wurde für alle offenen Aufgaben der betroffenen Spalten vermerkt, dass ihr Alarm noch aussteht. Jetzt bekommt nur eine Aufgabe, die von „Erledigt“ wieder geöffnet wird, ihren Alarm erneut.
|
||||||
|
|
||||||
## [0.17.2] - 2026-10-31
|
## [0.17.2] - 2026-10-31
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
@@ -413,7 +418,8 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V
|
|||||||
- Geteilte Listen (Einkaufs-, Pack- und Checklisten) mit `#Kategorie`-Gruppierung, Mengenangaben und Echtzeit-Abhaken.
|
- Geteilte Listen (Einkaufs-, Pack- und Checklisten) mit `#Kategorie`-Gruppierung, Mengenangaben und Echtzeit-Abhaken.
|
||||||
- Benutzer-, Gruppen- und Admin-Verwaltung (Ersteinrichtungs-Assistent, Einladungscodes, Profilbilder, persönliche API-Keys & Webhook-Ingest `/api/v1/webhooks/ingest`, JSON-Datenexport) sowie CSS-Theme-Engine mit 4 Themes (`Dark`, `Light`, `High Contrast`, `Soft`) und PWA-Unterstützung.
|
- Benutzer-, Gruppen- und Admin-Verwaltung (Ersteinrichtungs-Assistent, Einladungscodes, Profilbilder, persönliche API-Keys & Webhook-Ingest `/api/v1/webhooks/ingest`, JSON-Datenexport) sowie CSS-Theme-Engine mit 4 Themes (`Dark`, `Light`, `High Contrast`, `Soft`) und PWA-Unterstützung.
|
||||||
|
|
||||||
[Unreleased]: https://git.dsit.me/sandrodach/MindSift/compare/v0.17.2...dev
|
[Unreleased]: https://git.dsit.me/sandrodach/MindSift/compare/v0.17.3...dev
|
||||||
|
[0.17.3]: https://git.dsit.me/sandrodach/MindSift/compare/v0.17.2...v0.17.3
|
||||||
[0.17.2]: https://git.dsit.me/sandrodach/MindSift/compare/v0.17.1...v0.17.2
|
[0.17.2]: https://git.dsit.me/sandrodach/MindSift/compare/v0.17.1...v0.17.2
|
||||||
[0.17.1]: https://git.dsit.me/sandrodach/MindSift/compare/v0.17.0...v0.17.1
|
[0.17.1]: https://git.dsit.me/sandrodach/MindSift/compare/v0.17.0...v0.17.1
|
||||||
[0.17.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.16.1...v0.17.0
|
[0.17.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.16.1...v0.17.0
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[](#)
|
[](#)
|
||||||
[](#-schnellstart)
|
[](#-schnellstart)
|
||||||
[](#-deine-daten-gehören-dir)
|
[](#-deine-daten-gehören-dir)
|
||||||
[](CHANGELOG.md)
|
[](CHANGELOG.md)
|
||||||
|
|
||||||
**MindSift** ist eine selbst gehostete Schaltstelle für spontane Gedanken, Aufgaben mit Kanban-Board, hierarchische Outliner-Notizen, die mehrere Personen gleichzeitig bearbeiten können, und gemeinsame Listen. Alles läuft als ein einzelner Container mit eingebetteter SQLite-Datenbank, auf deinem eigenen Server.
|
**MindSift** ist eine selbst gehostete Schaltstelle für spontane Gedanken, Aufgaben mit Kanban-Board, hierarchische Outliner-Notizen, die mehrere Personen gleichzeitig bearbeiten können, und gemeinsame Listen. Alles läuft als ein einzelner Container mit eingebetteter SQLite-Datenbank, auf deinem eigenen Server.
|
||||||
|
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "mindsift-frontend",
|
"name": "mindsift-frontend",
|
||||||
"version": "0.17.2",
|
"version": "0.17.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mindsift-frontend",
|
"name": "mindsift-frontend",
|
||||||
"version": "0.17.2",
|
"version": "0.17.3",
|
||||||
"license": "Unlicense",
|
"license": "Unlicense",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource-variable/inter": "5.3.0",
|
"@fontsource-variable/inter": "5.3.0",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "mindsift-frontend",
|
"name": "mindsift-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.17.2",
|
"version": "0.17.3",
|
||||||
"license": "Unlicense",
|
"license": "Unlicense",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -139,6 +139,44 @@ func TestAlarmResetsOnNewDueDateOrReopen(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A Kanban move sends every task of the touched columns: only a task that goes from done back to open
|
||||||
|
// may get its due alarm again, the others must not be notified a second time
|
||||||
|
func TestKanbanMoveKeepsSentAlarms(t *testing.T) {
|
||||||
|
store, err := NewStore(filepath.Join(t.TempDir(), "kanban-alarm.db"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewStore: %v", err)
|
||||||
|
}
|
||||||
|
defer store.Close()
|
||||||
|
u, _ := store.CreateUser("anna@example.com", "hash", "Anna", "member")
|
||||||
|
tl, _ := store.CreateTaskList(u.ID, "", "", "Haushalt", "🏠", "")
|
||||||
|
task, _ := store.CreateThoughtWithDetails(u.ID, "Heizung entlüften", "normal", "manual", "2026-10-31 09:00", tl.ID, "todo", "")
|
||||||
|
_, _ = store.UpdateThoughtTriage(u.ID, task.ID, "keep", "task", "", "", tl.ID)
|
||||||
|
sent := func() bool {
|
||||||
|
th, _ := store.GetThoughtByID(u.ID, task.ID)
|
||||||
|
return th.AlarmSent
|
||||||
|
}
|
||||||
|
move := func(status string) {
|
||||||
|
if err := store.ReorderTasks(tl.ID, []domain.ThoughtReorderItem{{ID: task.ID, SortOrder: 0, KanbanStatus: &status}}); err != nil {
|
||||||
|
t.Fatalf("ReorderTasks: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = store.MarkTaskAlarmSent(task.ID)
|
||||||
|
move("in_progress")
|
||||||
|
move("todo")
|
||||||
|
if !sent() {
|
||||||
|
t.Errorf("moving an open task between columns must not re-arm its alarm")
|
||||||
|
}
|
||||||
|
move("done")
|
||||||
|
if !sent() {
|
||||||
|
t.Errorf("completing keeps the flag")
|
||||||
|
}
|
||||||
|
move("todo")
|
||||||
|
if sent() {
|
||||||
|
t.Errorf("reopening via the board must re-arm the alarm")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAlarmGivesUpAfterThreeFailedRuns(t *testing.T) {
|
func TestAlarmGivesUpAfterThreeFailedRuns(t *testing.T) {
|
||||||
store, err := NewStore(filepath.Join(t.TempDir(), "alarmfail.db"))
|
store, err := NewStore(filepath.Join(t.TempDir(), "alarmfail.db"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -243,10 +243,13 @@ func (s *Store) ReorderTasks(taskListID string, items []domain.ThoughtReorderIte
|
|||||||
completed = append(completed, it.ID)
|
completed = append(completed, it.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Only a reopened task (done -> open) gets its due alarm again. A Kanban move sends every task
|
||||||
|
// of the touched columns, so resetting all open ones re-sent "due today" for each of them.
|
||||||
|
// (is_completed in the CASE is still the value before this UPDATE.)
|
||||||
_, err = tx.Exec(
|
_, err = tx.Exec(
|
||||||
`UPDATE thoughts SET sort_order = ?, kanban_status = ?, is_completed = ?,
|
`UPDATE thoughts SET sort_order = ?, kanban_status = ?, is_completed = ?,
|
||||||
alarm_sent = CASE WHEN ? = 0 THEN 0 ELSE alarm_sent END,
|
alarm_sent = CASE WHEN ? = 0 AND is_completed = 1 THEN 0 ELSE alarm_sent END,
|
||||||
alarm_failures = CASE WHEN ? = 0 THEN 0 ELSE alarm_failures END WHERE id = ?`,
|
alarm_failures = CASE WHEN ? = 0 AND is_completed = 1 THEN 0 ELSE alarm_failures END WHERE id = ?`,
|
||||||
it.SortOrder, *it.KanbanStatus, isCompleted, isCompleted, isCompleted, it.ID,
|
it.SortOrder, *it.KanbanStatus, isCompleted, isCompleted, isCompleted, it.ID,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in new issue
Block a user