Commit Graph
279 Commits
Author SHA1 Message Date
sandrodachandClaude Opus 5.5 6d720c0c36 feat(ui): round icon-only search button in the title bar
The shortcut moves from the visible ⌘K badge into the tooltip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 12:42:25 +01:00
sandrodachandClaude Opus 5.5 b5f926bcf7 fix(auth): new passwords need at least 8 characters (FLAW-09)
auth.ValidatePassword checks every way a password is set: setup,
registration, profile, admin create and reset, reset by mail. Same rule
in the browser before sending (lib/password.ts), with our own German
message instead of the browser popup. Existing shorter passwords still
log in. Profile and admin reset no longer trim the password, which made
passwords with surrounding spaces unusable for login.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 12:20:46 +01:00
sandrodachandClaude Opus 5.5 f8989d0c44 fix(theme): readable text on the Polarized teal accent
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m34s
White on #14b8a6 reaches only 2.5:1; dark teal #042f2e gives 5.8:1 for
primary buttons, counters and active filters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:08:39 +01:00
sandrodachandClaude Opus 5.5 ee60a03e8c Merge branch 'theme/polarized-teal' into dev: Polarized in green/teal
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m36s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:04:31 +01:00
sandrodach 51a41df14b feat(theme): revise Polarized to classic green/teal dark palette 2026-10-29 09:15:20 +01:00
sandrodachandClaude Opus 5.5 4b9cf332b3 release: v0.4.1 – Polarized and Suri themes, due times, notes trash, backlinks, password reset, offline PWA
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m43s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 09:07:16 +01:00
sandrodachandClaude Opus 5.5 a9933b837e Merge branch 'theme/polarized-suri' into dev: Polarized and Suri themes
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m32s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:42:04 +01:00
sandrodachandClaude Opus 5.5 7bba174454 feat(pwa): start and keep working offline
The service worker now caches the app shell: page loads are network
first with the last index.html as fallback, hashed bundles come from the
cache, icons and manifest are refreshed in the background; API calls are
never intercepted. GET answers are kept per user in IndexedDB and served
when the server cannot be reached, so the app starts logged in with the
last known thoughts, tasks and lists. Captured thoughts and checked tasks
or list items go to an outbox that is sent in order when the connection
returns (also at start and every 30 s). A banner shows offline state and
waiting changes. Logging out clears cache and outbox.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:11:47 +01:00
sandrodachandClaude Opus 5.5 5e20710aa7 feat(auth): reset a forgotten password by mail
"Passwort vergessen?" appears on the login screen when SMTP and BASE_URL
are configured. The request always gets the same answer and sends the mail
in the background (at most every 2 minutes per account). The link holds a
random token valid once for one hour; only its SHA-256 is stored. Setting
the new password invalidates all open links and ends every session. The
app removes the token from the address bar and offers a way back for
expired links.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:06:56 +01:00
sandrodachandClaude Opus 5.5 677fe0fc0a feat(workspace): backlinks at the end of a note
GET /documents/{id}/backlinks lists the notes the user can open whose
blocks link [[Title]] (also |alias and #section, case-insensitive),
excluding the note itself and the trash. The collapsible "Verlinkt auf
diese Notiz" section shows each note with folder and the linking bullets;
a click jumps straight to the bullet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:00:57 +01:00
sandrodach 8619008aaa feat(theme): add Polarized and Suri purple dark themes 2026-10-29 07:58:33 +01:00
sandrodachandClaude Opus 5.5 f69f74fdc7 feat(workspace): trash for notes
Deleting a note (or its folder) moves it to the trash instead of erasing
it. Trashed notes leave the tree, search, export and stats and are hidden
from everyone they were shared with; the owner sees them read-only with a
restore banner. New endpoints list, restore, purge and empty the trash;
restoring recreates a deleted folder. Sidebar entry and mobile menu item
with counter, list view with two-tap permanent delete.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 07:57:42 +01:00
sandrodachandClaude Opus 5.5 344f5e4ab2 feat(tasks): due dates with optional time; alarms at the right moment
Due dates can carry a time (YYYY-MM-DDTHH:MM). Alarms fire at that time,
or 09:00 for all-day tasks, minus the user's lead time, in TZ (default
Europe/Berlin, tzdata embedded). A new due date or reopening a task
re-arms the alarm. Recurrence keeps the time; Markdown export/import
carry it. The UI shows relative labels ("Heute, 14:30"), marks overdue
tasks to the minute and groups by local day instead of the UTC date.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 07:48:37 +01:00
sandrodachandClaude Opus 5.5 62463bc6fd fix(security): SSRF protection for alarm webhooks (FLAW-05)
Discord and custom webhook URLs are checked when saved and before every
call: https only, Discord URLs must point to discord.com. A guarded HTTP
client resolves hosts itself and connects only to allowed IPs; localhost,
link-local and cloud metadata are always blocked, LAN ranges (incl.
Tailscale CGNAT) and plain http only with the new admin switch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 07:37:39 +01:00
sandrodachandClaude Opus 5.5 beeacf8943 release: v0.4 – import, backup ZIP, account self-service, repeating tasks
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 1m48s
- Import of MindSift data (add or restore) and Obsidian vaults, backup as ZIP
- Danger zone (delete own data / account), last admin protected
- Repeating tasks, SMTP AUTH LOGIN fallback and port fix
- Mobile: sheets above the keyboard, emoji picker fixes, blue splash screen
- Package version 0.4.0, README badge/screenshots renewed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 07:30:08 +01:00
sandrodachandClaude Opus 5.5 588c679c6a feat(tasks): repeating tasks (daily, weekly, monthly, yearly)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m28s
- recurrence on tasks, set in the detail dialog; 🔁 on rows and Kanban cards
- Completing a repeating task (detail, list, Kanban drag to done, note
  checkbox) creates the next one: title, tags, priority, notes, list,
  assignees and rule copied, subtasks reset, first open column, due date
  one interval later (month end clamped); pushed live as TASK_CREATED
- Each task spawns at most once (re-open + complete makes no duplicate)
- Export/import keep the rule (Obsidian Tasks "🔁 every week", JSON field)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 07:23:09 +01:00
sandrodachandClaude Opus 5.5 0e9fd1b3ad feat(account): danger zone, restore import, larger API key field on phones
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m27s
- Danger zone in settings: delete all own data or the account, both with
  password confirmation; the last server admin cannot delete the account
- DELETE /user/data and /user/account; PurgeUserData removes everything a
  user owns in one transaction (others' tasks in shared lists stay theirs),
  also used by admin user deletion
- MindSift import: 'Hinzufügen' or 'Wiederherstellen' (mode=restore, wipes
  own data only after the file is fully validated, confirm checkbox)
- API key name field and button 44 px on phones (flex-1 collapsed them)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 07:13:29 +01:00
sandrodachandClaude Opus 5.5 9bc8716f41 feat(pwa): blue splash screen with the logo, status bar follows the theme
Manifest: short name, blue background/theme colour for the Android splash.
index.html shows a plain blue screen with the logo until React mounts.
theme-color starts blue and then follows the active theme background.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 07:13:29 +01:00
sandrodachandClaude Opus 5.5 a3a709440f fix(admin): SMTP port can be cleared and saves without 'Ungültiges JSON'
The UI sent the port as a number while the server expects text, so every
save failed; the field also jumped back to 587 when emptied. The port is
now edited as text (digits only), and the server accepts number or text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 07:13:29 +01:00
sandrodachandClaude Opus 5.5 eaabe469d5 fix(mobile): sheets above the keyboard, emoji picker, cleaner header
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m25s
- FormSheet: create dialogs (task list, shopping list, folder) as bottom
  sheet right above the on-screen keyboard (visualViewport), large fields;
  centred or anchored dialog on desktop
- Emoji picker: category icons keep their sprite size (no doubled icons,
  round highlight), one 'Zuletzt verwendet' (library category, German
  names), sheet and picker height follow the keyboard
- Mobile header no longer repeats the current section next to the logo

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 06:43:51 +01:00
sandrodachandClaude Opus 5.5 1df32ece92 feat(backup): download the full backup as ZIP
GET /export?format=zip streams the JSON backup compressed (plain JSON stays
the API default). The MindSift import recognises the backup ZIP next to the
plain JSON and the Markdown archive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 06:43:50 +01:00
sandrodachandClaude Opus 5.5 1601a6a2d5 feat(import): restore MindSift data and import Obsidian vaults
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m28s
- Two separate paths: POST /import/mindsift (JSON backup or the Markdown
  archive) and POST /import/obsidian (vault ZIP into a folder named after it)
- Everything is planned and validated first; ?preview=1 returns what would
  be created and what is skipped (with reason), nothing is written
- MindSift data round-trips: folders, note structure, task lists with
  subtasks/due dates/priorities/notes, lists with quantity/category/done,
  triage thoughts from the JSON backup
- Markdown to outliner: nested lists, heading sections, callouts, code,
  paragraphs; front matter tags become hashtags; .obsidian/attachments skipped
- Limits against zip bombs and path tricks (100 MB upload, 10 MB per note,
  500 MB unpacked, 20k files, no .. escapes)
- Settings: two import cards with drag & drop, preview, confirm, result;
  touch-sized buttons; mobile download/upload verified

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 06:10:21 +01:00
sandrodachandClaude Opus 5.5 75a7b67d09 release: v0.3 – organizations, assignments, themes, search, export
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m32s
- Organizations decide who sees whom (private / organizations / open),
  owner-only sharing, rights follow visibility
- Task assignment in shared lists, unified people search, avatar stacks,
  CountBadge, tinted theme colours
- Custom CSS themes per user, legal notices, "Über MindSift", Unlicense
- SMTP hardening with per-step errors and skip-verify
- Global FTS5 search with Cmd+K, full emoji picker, Markdown/Obsidian export,
  new help page, demo mode resets on start
- Package version 0.3.0, README badge/screenshots renewed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 00:07:18 +01:00
sandrodachandClaude Opus 5.5 acefa3160c chore: release MindSift under The Unlicense (public domain)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m33s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 23:56:13 +01:00
sandrodachandClaude Opus 5.5 1fac1a80b7 fix(ui): opacity modifiers for theme colours (bg-accent/15 etc. were never generated)
Theme colours are CSS variables, so Tailwind produced no CSS for /NN
modifiers and all tinted backgrounds were missing. Colours now mix the
variable with transparent via color-mix() for modifiers only; plain
classes keep the bare variable. Aliases for colour names used but never
defined (primary, secondary, success, warning, danger, info).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 23:56:13 +01:00
sandrodachandClaude Opus 5.5 a62b1893b4 fix(search): themed highlight in the command palette (accent tint instead of browser yellow)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m34s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 23:28:01 +01:00
sandrodachandClaude Opus 5.5 a044620cec Merge branch 'feature/search-emoji-demo' into dev
Gemini: full emoji picker (desktop + mobile bottom sheet), global search
with SQLite FTS5 and Cmd+K palette (access-checked), demo mode resets the
database on every start.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 23:27:22 +01:00
sandrodachandClaude Opus 5.5 b07a7acf42 fix(ui): tab counters sit on the label like in the nav bar
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 23:21:20 +01:00
sandrodachandClaude Opus 5.5 e509f685c1 feat(export): Obsidian-compatible Markdown vault as streamed ZIP
- GET /export/markdown streams the workspace as ZIP (no temp files):
  notes as .md with YAML front matter in the user's folder structure
  (shared notes and mounted folders included, empty folders kept)
- Clean Markdown: top-level headings/dividers/callouts/code as real blocks
  (their children move up a level), lists with tabs, todos as - [ ]
- Aufgaben/<list>.md in Obsidian Tasks format (due date, priority,
  subtasks, notes), Listen/<list>.md for shopping and other lists
- Safe, unique file names; download button in settings (mobile-safe)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 23:21:20 +01:00
sandrodachandClaude Opus 5.5 d6c70d7a8e feat(legal): imprint & privacy notices, "Über MindSift"
- LEGAL_IMPRINT_/LEGAL_PRIVACY_ URL and Markdown (inline or *_FILE);
  only http(s) URLs accepted
- /auth/status exposes legal info; public GET /legal/{imprint|privacy}
- Links on login/setup screen and in the settings footer: URL opens a new
  tab, Markdown a reading modal; hidden when nothing is configured
- "Über MindSift" modal (version, license, repository) in settings and help
- Docs and compose/env examples

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 23:10:27 +01:00
sandrodach 0e9bfab943 Doku: REST-API-Suche, Moduldokumentation, FLAW-18 und Hilfe-Seite aktualisiert 2026-10-28 23:08:05 +01:00
sandrodach 71fa53ead3 Paket B: Globale Suche mit SQLite FTS5, BM25-Ranking, Zugriffsprüfung und Cmd+K-Palette 2026-10-28 23:00:19 +01:00
sandrodachandClaude Opus 5.5 a62b204e14 feat(ui): one CountBadge for all counters; counters on tab corners
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m30s
- CountBadge component (accent / muted, inline / corner, 99+, showZero);
  used in the nav bar, task list and list tabs, admin organizations and
  numeric badges of the mobile menu; old badge-count removed
- Counters sit on the top right corner of tabs; "Alle Aufgaben" gets one
  (desktop tab and mobile menu)
- Open/done task counters include tasks in shared lists, matching what
  "Alle Aufgaben" shows (nav counter was too low)
- Theme template derives --accent-dim/--accent-border from the accent
- Docs: ui-patterns counters section

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 22:54:15 +01:00
sandrodach 633bd6f1ef Paket A: Vollständige Emoji-Auswahl für Notiz-Icons mit Lazy-Loading und Mobile Bottom-Sheet 2026-10-28 22:44:21 +01:00
sandrodachandClaude Opus 5.5 a354f3d008 Merge branch 'help_page' into dev
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m24s
New help page with search (Gemini). Updated to the current features while
merging: organizations, groups and owner-only sharing, task assignment,
custom themes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 22:30:41 +01:00
sandrodachandClaude Opus 5.5 ce321ce579 fix(smtp): proper SMTP dialogue, encoded mails, optional skip-verify
- Explicit SMTP flow (dial -> EHLO -> STARTTLS -> AUTH -> MAIL/RCPT/DATA)
  with errors naming the refusing step (also logged as smtp_step)
- EHLO with the sender's domain instead of "localhost"
- Envelope gets the bare address; "Name <addr>" stays in the From header
  (was rejected as invalid MAIL FROM)
- Date and Message-ID headers, RFC 2047 subject, quoted-printable body
- SMTP_SKIP_VERIFY / admin switch for self-signed certificates;
  SMTP checkboxes are switches now
- Tests against a fake SMTP server (STARTTLS, 451, display names)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 22:28:26 +01:00
sandrodach 2eff9319b5 Aktualisiere Hilfe-Seite: Veraltete Inhalte korrigiert, Suchfunktion und neue Features ergänzt 2026-10-28 22:17:29 +01:00
sandrodachandClaude Opus 5.5 bf0d68e7e1 feat(themes): custom CSS themes per user (upload, paste, live)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m21s
- Theme manager in settings: upload a .css file or paste CSS, template
  download/copy/insert, edit and delete; custom themes show up in the
  gallery and the quick switchers
- Themes are injected live as <style id="mindsift-custom-theme">; the
  active one is cached so it applies on boot without flashing
- Backend: user_themes table and GET/POST /themes, DELETE /themes/{id}
  (per user, max 200 KB)
- Docs: theming, REST, database

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 22:12:27 +01:00
sandrodachandClaude Opus 5.5 84395f3322 feat: organizations decide who sees whom; sharing only by owners
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m30s
- Server admins manage organizations (one per user); new admin section,
  organization on user creation and invites, setup creates the first one
- Sharing modes private / organizations / open, enforced centrally
  (CanSee, CanShareWith) for directory, all shares and groups; unknown and
  invisible targets give the same error
- Losing visibility (org change, mode change, leaving a group) prunes shares,
  group memberships and task assignments; dry run warns before tightening
- Only owners share; editors can no longer reshare lists or remove others'
  shares; legacy task_lists.team_id and old /organizations endpoints removed
  (FLAW-06, FLAW-10, FLAW-24)
- Schema version: outdated databases are wiped and recreated on start
- Fix setup sample data (createSampleData was ignored); setup and admin
  use a shared ToggleSwitch instead of checkboxes
- Docs: sharing-and-permissions rewritten, ui-patterns, REST, DB, flaws

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 22:00:33 +01:00
sandrodachandClaude Opus 5.5 73fad1c5db feat(tasks): assign tasks in shared lists, unified people search, list avatars
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m36s
- Tasks in shared task lists can be assigned to one or more people with access
  (task_assignees); assignments are pruned whenever access is lost
- UserAutocomplete: type-to-search everywhere, nothing before typing, max 3 results,
  first match preselected
- Task list and list tabs: avatar stack of members and round monochrome counter
- Shared list items remember who added them (list_items.created_by)
- Doku/ui-patterns.md documents the shared UI patterns

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 20:26:55 +01:00
sandrodachandClaude Opus 5.5 1bd38f4d50 feat(notes): presence as avatar stack, drop guide lines, fix stuck bullet focus
- Leaving a block now clears its focus, so the bullet no longer stays highlighted
- Remove the vertical indentation guide lines
- Who has the note open: up to 3 overlapping avatars, "+n", full list on hover
- Shared AvatarStack component; UserAvatar gets xxs size and optional title

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 20:26:55 +01:00
sandrodach 3540b4b2ae New icons for all shit
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m22s
2026-10-28 19:01:08 +01:00
sandrodachandClaude Opus 5.5 f82ab2fd32 fix: mobile layout, task clicks, list tab corners, hashtags in URLs
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m25s
Mobile
- Plus button in triage did nothing: the stored action returned the
  capture function instead of calling it
- Workspace: tabs share the full width; save status sits as an icon next
  to the note title instead of wrapping into its own row; "Neue Notiz" /
  "Neuer Ordner" only in the top menu (and +), not repeated in the list
- Outliner fields measured while hidden stayed one line high (cut-off
  callout); they are measured again when their width changes
- Task dialog: scrolls in a div instead of a fieldset, height in dvh,
  notes editor grows with its text, so long notes are fully reachable

Desktop
- Delete button of the selected task/shopping list sits inside the tab as
  its own rounded button (matches rounded themes like Soft)

Both
- Tasks sometimes did not open: every reload after an action replaced the
  list with a loading placeholder, swallowing clicks; reloads are now
  silent after the first load of a list, stale responses are dropped
- Hashtags need whitespace or "(" before "#", so URL anchors are no
  longer tags (server, browser); one-time cleanup of stored anchor tags

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 16:50:51 +01:00
sandrodachandClaude Sonnet 5.5 be85ea3093 feat(notes): jump to the task after converting; "Erweitert" badge opens it
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m20s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 15:51:37 +01:00
sandrodachandClaude Opus 5.5 4e39b367bd release: v0.2 – collaboration docs, richer demo data, new screenshots
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m30s
- Turn the collaboration plan into module docs (Doku/modules/collaboration.md)
  describing the implemented state; remove Doku/plans
- Header version comes from the build: git tag via APP_VERSION (CI passes
  it for tag builds), otherwise "<package version>-dev"; package 0.2.0
- Sample data (setup option and demo mode): six inbox thoughts, two task
  lists with Kanban states, subtasks and due dates, shopping and packing
  lists, three notes in folders incl. a long nested outline; demo mode
  shares the note and two lists with user/user
- e2e/screenshots.sh renews the README screenshots from demo data
- README: live collaboration, editor sharing, image tags, version badge

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:32:31 +01:00
sandrodachandClaude Opus 5.5 f26f286fb8 feat(notes): compact the operation log and purge old tombstones
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m17s
- Background job at start and every 6 h: log entries older than 30 days
  (private notes: 7) are removed, documents.log_floor marks the boundary;
  clients behind it get resync and keep their queued changes
- Deleted blocks are purged 30 days after deleted_at via a "purge" log
  effect, so open editors drop them without reloading; a tombstone stays
  while a deleted child still points to it
- Text for a purged block becomes a new block at the end; inserts under a
  purged parent go to the top level (server and browser model)
- doc_op_results kept for 90 days; expired lease/session maps are swept
- Tests: storage, API, engine resync, simulation with compactions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:08:13 +01:00
sandrodachandClaude Opus 5.5 aea4324c20 refactor(notes): remove legacy whole-document saves; all block changes go through sync
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m14s
Phase 5 of the collaboration plan:
- Remove PATCH /documents/{id}/blocks, PatchDocumentBlocks, the
  DOC_BLOCKS_PATCHED event and its types, FlushDocumentState and
  LoadDocumentState. PUT /documents/{id} rejects blocks (400) and only
  changes title, icon, folder and pin; editors may now change title/icon.
- The to-do overview ticks via a single operation on /docs/{id}/sync
  (new skipLog flag). Task links set the block tick with a targeted
  operation and notify open editors; creating a linked task needs edit
  rights.
- Keep the three share tables: DocRole already decides centrally, and
  rewriting the visibility queries would only add risk (documented in plan).
- Tests adapted to the new paths; share e2e test now also ticks a to-do in
  the overview.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:35:59 +01:00
sandrodachandClaude Opus 5.5 8b7a53daab feat(notes): push, long polling and fallback detection for note sync
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m16s
Phase 4 of the collaboration plan:
- The sync engine listens for DOC_SEQ in the note's realtime room and syncs
  right away. Without WebSocket/SSE it long-polls /docs/{id}/changes (25 s);
  after three failures it falls back to polling every 3 s and retries long
  polling when the browser comes back online.
- With push or long polling the engine only syncs every 7 s while holding
  leases (renewal), otherwise every 30 s as a safety net. Focusing a block
  announces its lease immediately (otherwise it could take up to 30 s).
- Realtime connection: SSE counts as connected only after its first event;
  a stream that stays silent for 5 s (buffering proxy) switches SSE off for
  the tab. App-level PING/PONG detects WebSockets that are accepted but
  forward nothing and switches to SSE after 35 s.
- The editor shows the active channel for shared notes.
- Tests: engine channel tests (push, heartbeat, lease on focus, long
  polling, interval fallback, switching), realtime fallback tests with fake
  WebSocket/EventSource, Go tests for PONG and DOC_SEQ delivery, and
  e2e/channels.e2e.mjs measuring latency behind six simulated proxy setups
  (0.2-0.3 s on all live channels, ~3 s with plain polling).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:10:29 +01:00
sandrodachandClaude Opus 5.5 aa397c18cd feat(notes): show block locks and presence, conflict copies with accept/discard, undo/redo
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m21s
Phase 3 of the collaboration plan:
- Blocks held by someone else show a lock with the name and are read-only;
  Enter in such a block adds a new block below. Delete, merge, indent and
  drag are not started when a involved block (or one in its branch) is
  locked; a short notice explains why (fixes FLAW-25).
- Presence: the editor header lists who else has the note open.
- Conflict copies are highlighted ("Konflikt – Version von …") with
  Übernehmen (replaces the original or the title) and Verwerfen. Both check
  the locks of the original and of the copy first.
- Undo/redo of own changes (Ctrl/Cmd+Z, Ctrl+Shift+Z, Ctrl+Y, beforeinput
  history events): typing is grouped per block until a 1 s pause, up to 200
  steps per tab; a step is skipped with a notice if someone else changed or
  holds the block meanwhile. New clearConflict props patch on the server.
- New blocks get focus synchronously on mount (fixes FLAW-26).
- Fix: after reopening a note from local storage the engine polled every
  30 s instead of 3 s until the next change, because the delay was decided
  before the first response told it the note is shared.
- Tests: undo/conflict engine tests, lock/undo/conflict UI tests and
  e2e/lock.e2e.mjs (two browsers); all three browser tests pass against a
  freshly built image.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 13:44:27 +01:00
sandrodachandClaude Opus 5.5 08d9b2dc77 feat(workspace): allow sharing notes and shared folders as editor
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m13s
The share dialog for notes and shared folders now offers "Bearbeiten" and
"Nur Lesen" and stores write/read accordingly. Editors already edit through
the sync engine since phase 2.

Adds e2e/share.e2e.mjs: shares a note as editor through the dialog and checks
that the recipient can edit it; e2e/run.sh runs both browser tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:40:22 +01:00