Root cause: CallFunctionJSON used .String() on Lua return values, which
for tables produces 'table: 0x...' — not valid JSON. Frontend does
JSON.parse() on the result and silently caught the parse error.
Fix:
- runtime.go: convert Lua return value to JSON via luaValueToGo +
json.Marshal so tables become proper JSON arrays/objects
- main.lua: add backward compat in get_events() and update_event()
to accept both positional args (start, end) and table params
- CalendarPluginPage.svelte: show errors in UI instead of silent catch;
restructure template to always show iframe + error overlay
PluginPage.svelte использовал несуществующий Wails binding CallPluginAction.
Заменён на CallPluginFunction с правильным dotted path (calendar.get_events и т.д.),
что соответствует сигнатуре bindings_plugins.go.
Frontend пересобран, go build + go test ./... — всё зелёное.
- Новый экран 'Сегодня' разбит на 4 вкладки: Лента, Предложения,
В работе, Захвачено
- Лента отображает события за сегодня с кликабельными сущностями
- Предложения вынесены в отдельную вкладку (только предложения)
- В работе: изменённые файлы/заметки/действия за сегодня с сортировками
- Захвачено: захваченные элементы за сегодня с сортировками
- Неразобранное: сортировка по дате/имени/типу с направлением
- Неразобранное: переключатель 'Группировать по месту захвата'
- TodayScreen.svelte: новый компонент с 4 вкладками
- Новые i18n ключи для вкладок и сортировок
- Backend: ListTodayInProgress, ListTodayCaptures bindings
- Все переходы из вкладок ведут в соответствующее место программы
- resolveActivityTarget uses 'targetId'/'targetPath' for all types
(note, file, folder) instead of type-specific property names
- openActivityTarget for files: resolves the file node via
GetNodeDetail, navigates to its parent folder in the Files tab,
then auto-previews the file if it's a previewable type
- For root-level files (no parent_id): loads root items
- Removed spurious OpenFolder(targetPath) call that silently failed
because OpenFolder expects a node ID, not a filesystem path
selectNode() resets fileItems=[] and activeTab='overview'. Setting
activeTab='files' programmatically does not trigger the tab click
handler that calls loadFolder(), so the file tree stays empty.
Fix: explicitly call await loadFolder(selectedNode.id) in the files
branch of openActivityTarget.
Also: unified resolveActivityTarget return shape to always use
targetId/targetPath regardless of targetType.
- New cmd/verstak-gui/bindings_debug.go: WriteDebugLog(msg) appends a
timestamped line to the vault's .verstak/debug.log
- Frontend: console.log replaced with writeDebugLog() which calls
wailsCall('WriteDebugLog', ...) — works in production Wails builds
- Both acceptTodaySuggestion and acceptJournalSuggestion log eventIds,
events, and errors to the file
Tests added to suggest_test.go:
- TestJournalFullRegression: GetSuggestions -> verify eventIds match
events -> AcceptSuggestionWith -> verify all 3 linked via
worklog_entry_events + JOIN + GetWorklogEntryEvents
- TestSuggestionOnRepeatedActivity: first event accepted, new event
created -> GetSuggestions still returns suggestion for the new event
- TestManualWorklogEntry: CreateWorklogFull -> source=manual,
billable/approximate/details preserved, GetWorklogEntryEvents empty
Frontend:
- resolveActivityTarget(ev) pure function returning { nodeId, tab,
noteId/fileId/targetPath } based on targetType
- openActivityTarget(ev) uses resolveActivityTarget for navigation
Root cause: Wails v2.12.0 cannot reliably marshal []string arguments
from JavaScript to Go when called through positional binding.
The event IDs array arrived empty on the Go side, causing no
worklog_entry_events INSERTs.
Fix:
- AcceptSuggestionWith now accepts eventIDsJSON (string) instead of
eventIDs ([]string). Frontend passes JSON.stringify(eventIds).
- Backend json.Unmarshal into []string before validation.
- Pre-insert validation: each eventID checked in activity_events.
- Atomic tx: entry create + linking in single Begin/Commit.
- INSERT (not INSERT OR IGNORE) — failure is a hard error.
- Post-commit verification: JOIN COUNT(*) must match len(eventIDs).
- End-to-end test: TestAcceptSuggestionWithEndToEnd creates a node,
3 activity events, accepts suggestion, verifies all 3 linked.
Other changes:
- GetWorklogEntryEvents: fixed column name (details_json -> metadata).
- openActivityTarget(ev): new function for 'Посмотреть' button that
navigates to specific note/file/folder instead of just opening node.
- All 'openNodeById(ev.nodeId)' in event contexts replaced with
'openActivityTarget(ev)'.
Root cause: s.eventIds may be undefined in JavaScript even when s.events
has data (Wails v2 marshalling of []string in nested struct response).
On calling AcceptSuggestionWith(eventIDs []string), empty array reached Go,
no INSERTs executed, events silently lost.
Changes:
- Frontend: extractEventIds() fallback — s.eventIds || s.events[].id || []
- Frontend: console.log debug for eventIds/events in accept handler
- Backend: AcceptSuggestionWith wrapped in tx (Begin/Commit/Rollback) so
entry creation + event linking is atomic
- Backend: AddWithSourceTx method for transaction-aware insert
- Backend: buildEntry helper extracted
- Backend: fmt.Printf debug logging for received eventIDs + link count
- Backend: verification query after commit
- Cleanup: removed stale frontend-dist assets, .gitignore build.log
- Add source column to worklog_entries (migration 014): manual/suggestion/unknown
- GetSuggestions now excludes only events linked in worklog_entry_events,
not entire nodes — repeated activity same day now produces suggestions
- Manual entry form replaced with '+' button + modal dialog
- Source display shows correct origin (manual/suggestion/unknown/no-events)
- Include-children checkbox hidden when no node selected
- Activity events navigate to specific notes/files instead of just case
- Expandable row reactivity fixed (journalRows/worklog reassignment)