mirv
d34100e2ed
feat: node search picker, ByNode grouping fix, PDF export
...
- node picker: Search/Path on Repository, SearchNodes binding,
debounced search dropdown showing title + full path
- ByNode summary groups by nodeID with NodePath as label (not NodeTitle)
- PDF export for worklog reports with embedded DejaVuSans fonts
- ExportWorklogPDF binding + button on Journal screen
- Removed unused Section field from ReportFilter
- ListReport now calls BuildReportPaths so nodePath is available
- go.sum: +github.com/signintech/gopdf dependency
2026-06-03 10:56:13 +08:00
mirv
5732264fc5
fix(step16.1): review fixes — acceptance, filters, sorting, export
...
- Remove dead acceptSuggestion, unify into refreshAfterSuggestion()
- Journal: nodeID picker, includeChildren only with selected node
- Journal: billable/approximate filters (all/yes/no selects)
- Summary: ByDay sorted by date desc, ByNode by minutes desc
- CSV: proper encoding/csv writer (was manual fmt.Sprintf)
- Markdown: escape pipes and newlines via escMD()
- After suggestion: refresh suggestions + count + worklog + journal
- Add GetNodeTitle binding
- i18n: common.all/no/date/search
2026-06-03 10:30:48 +08:00
mirv
c25e75f839
Step 16.1: global worklog dashboard + conservative suggestions
...
- Fix date timezone: worklog.Add uses local date (was UTC)
- Conservative suggestion estimator:
- burst detection (10min window), time spread analysis
- 5-30 min range, 60+ only with strong evidence
- confidence levels: low/medium/high with reason
- worklog/report.go: ReportFilter, ListReport, Summary, ExportCSV, ExportMarkdown
- Expanded WorklogDTO: date, details, approximate, billable, nodeTitle
- New bindings: CreateWorklogFull, ListWorklogReport, WorklogSummary, Export*
- New system section 'Журнал' in sidebar with badge (suggestion count)
- Global journal screen: filters (date range, includeChildren), table, summary
- Suggestions shown on Today dashboard + Journal screen + per-node worklog tab
- Suggestion cards: editable minutes, confidence display, apply/open buttons
- i18n: all new keys in ru + en
2026-06-03 09:56:17 +08:00
mirv
57d13c9506
feat: activity-based worklog suggestions (Step 16)
...
- Suggestion struct with nodeId, nodeTitle, summary, suggestedMin
- GetSuggestions binding: analyzes today's activity events, groups by
node, skips nodes with existing today's worklog, generates summary
- AcceptSuggestion binding: creates worklog entry from suggestion
- HasTodayEntries helper on worklog.Service
- Suggestions panel in Worklog tab with Apply button
- i18n: worklog.suggestions / worklog.apply (ru + en)
2026-06-03 09:31:40 +08:00
mirv
ca280a59c0
test: comprehensive sync package unit tests (37 new tests)
...
- safe_path_test.go: path traversal protection (11 table-driven cases)
- blob_test.go: SHA-256 hashing, store/deduplicate/read blobs
- sync_test.go: Service CRUD ops, state, push/mark lifecycle
- client_test.go: Push/Pull/Blobs/Auth via httptest.Server
- sync_e2e_test.go: auto-build server binary on demand
2026-06-03 09:16:38 +08:00
mirv
7d81250ebd
fix: rename node not found, A11y warnings cleanup
...
- fix renameId cleared before RenameNode API call (submitRename)
- add role, tabindex, keydown handlers to all interactive divs
- associate labels with inputs (wrap in label + .label-text)
- remove autofocus, unused CSS selectors, old root build.sh
- update frontend-dist assets
2026-06-03 08:55:38 +08:00
mirv
20a05569ac
fix: второй стабилизационный pass vault layout — sync payload, bindings, vaultPath, tests
...
sync_apply.go:
- applyRemoteNodeCreate: полный payload (template_id/fs_path/sort_order/archived),
INSERT сохраняет все поля, для folder-like создаётся физическая папка.
- applyRemoteNodeUpdate: принимает fs_path/template_id/archived,
физическое переименование папки при изменении title/fs_path.
- applyRemoteNodeMove: принимает fs_path, обновляет parent_id+fs_path,
физически перемещает папку (folder-like) или file record (note/file).
bindings_nodes.go:
- MoveNode: node.FsPath = newFsPath после UpdateFsPath;
sync.RecordOp отправляет новый fs_path; note/file move to root — файл в vault root.
- RenameNode: EntityFile для file, EntityNote для note;
коллизия → генерация уникального имени; файл переименовывается только после os.Rename.
- DeleteNode: единый вызов a.files.DeleteNodeAndChildren(), дублирование удалено.
- Исправлен deadlock с SetMaxOpenConns(1) — Query/Exec больше не конфликтуют.
files.Service.vaultPath: filepath.Rel-based проверка,
sibling-prefix escape (/tmp/vault vs /tmp/vault_evil) отклоняется.
VaultCheck: SQL JOIN с n.deleted_at IS NULL, чтобы удалённые узлы
не показывались как missing files.
Добавлены тесты: RenameFileNodeUsesEntityFile, MoveNoteToRoot,
DeleteFolderLeavesVaultCheckHealthy, SyncNodeCreatePreservesFields,
VaultPathSiblingPrefixEscape.
2026-06-02 17:03:05 +08:00
mirv
66c5c81f39
fix: стабилизация vault layout — rename/move/delete note/file vs folder разведены, sync apply без spaces/, VaultCheck усилен
...
- RenameNode/DeleteNode/MoveNode: note/file и folder-like nodes
обрабатываются по-разному (file record vs физическая папка)
- DeleteNode: рекурсивный soft-delete всех descendants
- SafeVaultPath возвращает clean relative, filepath.Join в sync_apply.go
- Fallback spaces/ → .verstak/remote-inbox в applyRemoteNoteCreate
- VaultCheck: проверка parent_id != nil, orphan descendants,
fs_path folder на диске
2026-06-02 16:36:43 +08:00
mirv
4f01f2de2e
fix: complete vault layout transition — fs_path everywhere, no more spaces/
...
- notes.Create(): .md files stored in parent node's fs_path folder
- files.CopyIntoVault/CreateEmptyFile/Duplicate: use parent fs_path
- files.AddPathCopy/AddPathLink: use parent fs_path, set folder fs_path
- files.DeleteNodeAndChildren: move physical folder to .verstak/trash
- UpdateFsPathRecursive: use SafeDisplayNameToPathSegment(child.Title)
- sync_apply.go note ops: use fs_path instead of spaces/
- internal/gui/server.go file upload: use n.FsPath instead of nodeSlug
- VaultCheck diagnostic: walk nodes/files, verify paths on disk
- Tests: create/rename/move/delete/name-conflict/vault-check all pass
2026-06-02 15:43:40 +08:00
mirv
0b26f7e5b3
refactor: implement template-driven node tree and human-readable vault layout
...
Unified Node model: added template_id, fs_path, archived, sort_order fields.
Template registry: system templates embedded as JSON (folder/project/client/
document/recipe), with Registry for enabled/disabled/filtered access.
SafeDisplayNameToPathSegment: human-readable path segments with Cyrillic
support, illegal char replacement, uniqueness via numeric suffixes.
Sidebar refactored: system views (Today/Inbox/Activity) separate from
workspace tree. Creation menu built dynamically from enabled templates.
Create/Rename/Move: physical folder operations with fs_path update,
recursive descendant path updates.
DB migration 012: adds template_id, fs_path, archived columns.
Vault migration command: rebuilds fs_path for existing nodes.
Tests: safename, registry, node model, repository integration.
Docs: VAULT_LAYOUT.md, TEMPLATES.md, PLAN.md updated.
i18n: nav.system, nav.workspace, template.*, common.rename/archive,
migrate.* keys added to ru.json and en.json.
2026-06-02 12:47:06 +08:00
mirv
12f2916a24
followup: SafeVaultPath in note update, email i18n, strict check-i18n.sh
...
- applyRemoteNoteUpdate: use SafeVaultPath for vault mode, skip non-vault with log
- Email subjects/bodies moved to Go i18n (confirm + reset) in ru.json and en.json
- check-i18n.sh: ru/en key mismatch now FAIL (not WARNING)
- All builds, tests, frontend pass
2026-06-02 11:40:27 +08:00
mirv
7091397649
server i18n: move inline HTML to templates.go, localize all handler strings
...
- Admin & user dashboard HTML moved from handlers to templates.go with i18n.T()
- SafeVaultPath applied in sync_apply.go (note/file create/update, blob restore)
- DeleteNode/RenameNode/MoveNode fixed: correct activity type / entity variant
- Added TypeNoteDeleted, TypeNodeDeleted, TypeFolderMoved activity constants
- Added locale() helper on Server struct, removed hardcoded 'ru' in handlers
- Password policy loosened: 8-256 chars, any characters, machine-readable error codes
- check-i18n.sh: Go Cyrillic = FAIL with explicit exception list, Go locale key consistency check
2026-06-02 11:26:54 +08:00
mirv
2fa583d157
stabilization: server.go split + i18n templates + frontend localization
...
cmd/verstak-server/server.go (2838→127 строк): разделён на 12 файлов
- config.go, tokens.go, schema.go
- server.go (только struct + NewServer + ListenAndServe)
- routes.go, middleware.go, smtp.go
- handlers_api.go, handlers_user.go, handlers_web_user.go, handlers_admin.go
- templates.go (конвертирован в функции с i18n.T())
frontend: все русские строки заменены на t() вызовы
- App.svelte, FileTreeRow.svelte, ConfirmModal.svelte
- FilePreviewModal.svelte, fileUtils.js
core: gofmt по всему проекту
Все сборки (CLI, server, gui, frontend), go vet, go test проходят.
check-i18n.sh: frontend чист, Go-файлы с кириллицей — только тесты/легаси.
2026-06-02 11:08:29 +08:00
mirv
3089d777a8
refactor(gui): разделить app.go на binding-файлы по доменам, вынести sync apply
...
- app.go (1810→280 строк): только App struct, startup, DTOs, helpers
- bindings_{nodes,files,notes,actions,worklog,activity,sync,settings}.go
- sync_apply.go: все applyRemote* методы
- i18n: internal/i18n (Go, embed JSON) + frontend/src/lib/i18n (JS)
- core/sync/safe_path.go: SafeVaultPath
- scripts/check-i18n.sh: проверка хардкода кириллицы и bidi-символов
- build.sh: NVM loading, set -e
Все сборки (CLI, server, gui, frontend), go vet, go test проходят.
2026-06-02 10:47:38 +08:00
mirv
390d451977
frontend: удалён мёртвый код (verstak.js, FileActions.svelte, style.css)
2026-06-02 09:48:58 +08:00