Commit Graph

73 Commits (7091397649a095c9508fe68a8e4a77e1a1d82f41)

Author SHA1 Message Date
mirivlad 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
mirivlad 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
mirivlad 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
mirivlad 390d451977 frontend: удалён мёртвый код (verstak.js, FileActions.svelte, style.css) 2026-06-02 09:48:58 +08:00
mirivlad 50e7e95844 test(sync): add end-to-end two-client sync smoke test
TestE2ESync starts a real server process, registers user, pairs two devices,
pushes a node op from client A, pulls on client B, verifies payload content,
and confirms /api/auth/test does not create devices.
2026-06-02 08:02:19 +08:00
mirivlad 4a96aa3468 fix(sync): expand payloads, implement ApplyRemoteOp, fix SyncTestConnection and auto sync
- Expand all RecordOp payloads with full entity data needed for reconstruction
- Add applyRemoteOp with handlers for node/note/file/action/worklog CRUD
- SyncNow() now applies pulled ops to real DB tables + sets LastSeenServerSeq
- SyncTestConnection uses /api/auth/test instead of PairDevice
- autoSyncLoop respects configured interval with lastSync timing
- Add helper functions: nodePayload, notePayload, filePayload, actionPayload, worklogPayload
2026-06-02 08:02:15 +08:00
mirivlad f8f9510e2a fix(sync): add /api/auth/test endpoint, fix CSS %& vet warnings
- Add handleAuthTest endpoint that validates credentials without creating a device
- Fix resetPasswordHTML to use {TOKEN} placeholder instead of %s
- Remove fmt.Sprintf from admin dashboard (no format args needed)
2026-06-02 08:02:11 +08:00
mirivlad 852d6d373c fix(sync): send LastSeenServerSeq from CLI push, report conflicts 2026-06-02 08:02:07 +08:00
mirivlad 3c7e9d1d56 fix(sync): add ClientSequence and LastSeenServerSeq to Op struct and Push
- Add ClientSequence and LastSeenServerSeq fields to sync.Op struct
- Fix Client.Push() to copy these fields to PushOp
- Add GetDeviceID() method to sync.Service
2026-06-02 08:02:03 +08:00
mirivlad 87c8dfcbea sync: overhaul sync system — device pairing, server_sequence, auto-sync, dashboards
BREAKING: replace legacy API keys with device tokens via pairing flow.
- Server: /api/client/pair, revoke, me endpoints; server_sequence + tombstones + idempotency
- Desktop client: PairDevice, GetMe, RevokeCurrent; auto-sync loop every 60s
- Config: device_token stored in separate file (0600), not config.yml
- Client DB: last_pull_seq migration for incremental pull
- Frontend (Svelte): settings modal with connect/disconnect/interval
- User dashboard (/dashboard): device list with status, revoke with password
- Admin dashboard (/admin/dashboard): devices table from /admin/api/devices
- CLI (cmd/verstak): updated for ServerSequence/GetState changes
- Fix: autoSyncLoop falls back to SQLite sync_state for server URL
- Fix: SyncSetInterval preserves server_url/device_id from SQLite
2026-06-02 02:26:05 +08:00
mirivlad 7fe02fc8df feat: forgot/reset password pages, login link, consistent error page helper, fix reset URL bug 2026-06-02 00:43:28 +08:00
mirivlad b0d992b0d6 fix: rebuild GUI with login/password sync fields, make sync buttons more visible 2026-06-02 00:37:31 +08:00
mirivlad e5860ca076 feat: styled registration/confirm pages with login link, consistent theme 2026-06-02 00:31:53 +08:00
mirivlad daed8e0aba feat: SMTP security selector (none/STARTTLS/TLS) instead of port-based detection 2026-06-02 00:18:04 +08:00
mirivlad fa6f988368 fix: SMTP test send JSON instead of multipart FormData (ParseForm can't read multipart) 2026-06-02 00:14:52 +08:00
mirivlad c8cdb089a6 feat: SMTP test button in admin modal — sends real test email, shows result 2026-06-02 00:12:41 +08:00
mirivlad 4afcc0e135 feat: add SMTP/logging — log.Printf for smtpSend errors, fix confirm URL logic 2026-06-02 00:10:04 +08:00
mirivlad 61928cf28e fix: restore side-by-side layout for stat counters 2026-06-02 00:04:56 +08:00
mirivlad 04af88940b refactor: SMTP form and health check into modals with toolbar buttons 2026-06-02 00:03:35 +08:00
mirivlad 015c8fdec7 docs: update sync server guide with user registration flow and full API 2026-06-02 00:00:53 +08:00
mirivlad 0f5c584c50 fix: admin dashboard format errors — use JS for stats, string concat for SMTP values, fix layout overlap 2026-06-01 23:59:15 +08:00
mirivlad 99e47fcb17 feat: add user registration web form at /register 2026-06-01 23:46:25 +08:00
mirivlad 0ef54c31f8 feat: user web GUI — login, dashboard with devices/keys, logout 2026-06-01 23:40:48 +08:00
mirivlad b3662d4876 test: update smoke test for user auth flow 2026-06-01 23:36:38 +08:00
mirivlad f8dc436709 feat: client auth — login/password flow, auto device reg, sync interval + improved sync UI 2026-06-01 23:36:19 +08:00
mirivlad 241a9d8c06 feat: user registration, email confirmation, login, device management + SMTP config UI in admin panel 2026-06-01 23:33:58 +08:00
mirivlad 5db3da3618 fix: protect device register with admin auth; improve admin UI (full API key, copy button, styling) 2026-06-01 23:22:19 +08:00
mirivlad e828ebd44e docs: add sync server installation and usage guide 2026-06-01 23:13:59 +08:00
mirivlad 84c0bcbcab test: add E2E smoke test for sync 2026-06-01 23:07:24 +08:00
mirivlad a1a50863c5 gui: add sync settings panel in Svelte 2026-06-01 22:58:12 +08:00
mirivlad 1abe8c4fa0 cli: add sync push/pull/status commands 2026-06-01 22:56:05 +08:00
mirivlad 5b2cec5bcc sync: fix SyncStatus binding — remove invalid type assertion, use config for device ID 2026-06-01 22:55:50 +08:00
mirivlad 1a20edac44 feat: sync — client ops recording in core services
- internal/core/sync/: Service, Client, Blob packages

- RecordOp creates sync_ops entries for all mutations

- Client for push/pull/blob HTTP to server

- Blob SHA-256 hashing and local storage

- Wired into app.go alongside activity recording

- Device ID from config or fallback
2026-06-01 22:54:23 +08:00
mirivlad ad684eb118 feat: sync — push/pull API endpoints
- POST /api/v1/sync/push — accepts ops, assigns revisions, returns accepted list

- POST /api/v1/sync/pull — returns ops since given revision with server_revision
2026-06-01 22:51:30 +08:00
mirivlad 10c6d06e38 feat: sync — blob upload/download with SHA-256 storage
- POST /api/v1/blobs/ — multipart upload, stored as blobs/ab/cd/sha256

- GET /api/v1/blobs/{sha256} — download by hash

- server_blobs table for tracking stored blobs
2026-06-01 22:50:38 +08:00
mirivlad ec928e3be6 feat: sync — systemd unit and install.sh for server deployment
- verstak-server.service — systemd unit with sandboxing, configurable port via env

- install.sh — creates user, installs binary, sets up admin, enables service

  Usage: sudo ./install.sh --admin-user admin --admin-pass secret [--port 47732]
2026-06-01 22:49:40 +08:00
mirivlad c5e0060fee chore: add verstak-server to gitignore 2026-06-01 22:49:10 +08:00
mirivlad 834b5ef0d4 feat: sync — server skeleton with health, admin login/dashboard, device registration
- cmd/verstak-server/main.go — flags: --port, --data, --admin-user, --admin-pass

- Server DB schema: server_devices, server_revisions, server_ops

- Health endpoint GET /api/v1/health

- Admin login page + session cookie auth

- Admin dashboard with device stats and API key management

- Device registration POST /api/v1/device/register

- Stub push/pull/blob endpoints
2026-06-01 22:49:02 +08:00
mirivlad 4145b4d74a feat: sync — migration 010 for sync_ops and sync_state tables 2026-06-01 22:45:12 +08:00
mirivlad edc708a106 chore: add spaces/ to gitignore (vault data) 2026-06-01 22:17:39 +08:00
mirivlad ee708d30bb docs: sync documentation with current codebase state
- Architecture: Wails v3→v2, removed TUI/sync/security from diagram

- UI/UX: layout updated to sidebar+header, sync marked future

- Roadmap: Wails v3→v2 migration note, milestones 10+ PAUSED

- MVP Checklist: mark implemented features as done

- PLAN.md: bindings list synced, repo structure fixed, progress updated

- Medium-term steps documented (sync, scanner, TUI, Lua, etc.)
2026-06-01 22:17:29 +08:00
mirivlad 305158ecc6 test: MVP smoke test for core workflow
Covers: vault init, node tree, notes CRUD, file import, actions CRUD, worklog, search (FTS5 optional), reopen persistence, soft delete, worklog report
2026-06-01 22:17:25 +08:00
mirivlad 996322f3a9 gui: actions CRUD + FromTemplate bindings + UI
- CreateAction / DeleteAction Wails bindings

- FromTemplate / ListTemplates bindings with recursive tree creation

- Plugin manager stored in App struct for template access

- Action creation modal (title, kind, data) in Overview and Actions tabs

- Delete action button on action cards

- Template selector in new-node dialog
2026-06-01 22:17:18 +08:00
mirivlad a098cf721c add missing Wails bindings for ListActivityFeed, ListActivityByNode, CountActivityByNode 2026-06-01 22:00:58 +08:00
mirivlad 3672e3133b activity: global feed, per-case log, sidebar section, today UX
- migration 009: target_type, target_id, target_path columns
- new Event fields: TargetType, TargetID, TargetPath
- ListActivityFeed (paginated global), ListActivityByNode (per-case)
- all Record() callsites pass target info
- frontend: Активность sidebar section with chronological feed
- per-case Активность tab with real data (was placeholder)
- today events: clickable, target-type badges, event counts
2026-06-01 02:53:56 +08:00
mirivlad 5a1c4c6d7f simplify ListTodayView: remove fallback table queries, pure activity_events + ListTodayNodes
TodayView now uses only activity_events (source of truth) + ListTodayNodes (ensure changed cases appear). Removed direct queries to nodes (notes) and files tables — those will come from activity_events going forward.
2026-06-01 02:45:55 +08:00
mirivlad 08c9d5dbea gitignore: fix verstak-gui pattern to root-only, add .verstak/ 2026-06-01 02:16:25 +08:00
mirivlad c74fa3ad43 today dashboard: activity_events, ListTodayView with events timeline, frontend TodayDashboard separated from sidebar 2026-06-01 02:16:13 +08:00
mirivlad 69891e395c Today view and Inbox section: dynamic query, not stored sections
- ListTodayView() on backend: queries nodes created or updated today
  using local timezone day boundaries
- todayBoundaries() helper returns start/end of current day in RFC3339
- Section validation: Create() rejects today and inbox as node sections
- validSections moved from repository.go to types.go with IsValidSection
  and IsServiceSection helpers
- Frontend selectSection('today') calls ListTodayView instead of
  ListNodesBySection('today')
- FAB (create node) hidden in today and inbox sections
- CreateNode in app.go guarded against today/inbox sections
- types.go: today/inbox defined as service sections (sidebar only)
2026-06-01 01:39:02 +08:00
mirivlad a4ae22c445 File manager: selection, keyboard shortcuts, rename modal, security, localization
- Selection model: click=select, dblclick=open, Ctrl+click toggle,
  Shift+click range select, Ctrl+A, Esc to clear
- Keyboard shortcuts: Enter, Ctrl+Enter, F2, Backspace (navigate up),
  Delete/Backspace (delete with confirm)
- Rename modal replaces prompt() with validation via backend ValidateName
- Context menu: Open, Open External, Show in Folder, Rename, Duplicate,
  Copy, Cut, Delete — all with SVG icons and Russian labels
- Backend security: vaultPath/absPathSafe helpers prevent path traversal,
  validateName rejects .. / \ null bytes empty overlong names
- MoveNode auto-renames on name conflict (copy style)
- Duplicate uses (copy) (copy 2) suffix pattern
- Russian localization: all file type labels, preview messages, tooltips
- FilePreviewModal: fixed broken {/if} tag
2026-06-01 01:35:45 +08:00