Commit Graph
107 Commits
Author SHA1 Message Date
vasyanskandClaude Opus 5 76ada57dd7 Add a defaults button to the folder mapping dialog
Mapping the Exchange/Kerio special folders onto mailcow's by hand is
repetitive work that scales with the number of accounts. "By default"
maps Deleted Items to Trash, Junk E-mail to Junk, Sent Items to Sent and
unchecks Public Folders, which mailcow has no counterpart for.

The destination select only offered the source folder as a name to
create, so a target missing on the destination could not be selected at
all. It now also offers the current selection, and marks any name absent
from the destination as "(create)".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 11:50:55 +07:00
vasyanskandClaude Opus 5 bb3635e517 Add a Kerio sample file to the bulk import
Only the plain four-column format had a downloadable example, leaving
the Kerio route undocumented in the UI. Each import button now carries
its own sample link underneath: the plain comma-separated layout and a
Kerio export with the Name;FullName;Description;Enable header, a
disabled row included to show what the import skips.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 11:50:45 +07:00
vasyanskandClaude Opus 5 8bc7ff026d Add endpoint deletion
The endpoints screen could only create and edit servers, so a mistyped
or retired endpoint stayed in the list forever.

Tasks reference endpoints without ON DELETE CASCADE, so a referenced
endpoint is refused with 409 and a count of the tasks using it rather
than cascading away migration history. The foreign-key violation is
mapped to the same status to cover a task created between check and
delete.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 11:50:12 +07:00
vasyanskandClaude Opus 5 94fb410c59 Fix postgres healthcheck probing a nonexistent database
pg_isready without -d connects to a database named after the user, but
the database is imapcopier, so every probe logged a FATAL and the
healthcheck only passed because pg_isready treats "server rejects the
connection" as reachable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 11:50:02 +07:00
vasyansk 6bf3a6c4ca Add body read timeout recovery to IMAP client
Introduce Client wrapper with socket deadline support
Add reconnection logic for body read timeouts
Implement test cases for underflow scenarios
Update orchestrator to handle reconnections
2026-07-21 05:29:35 +07:00
vasyansk c741cd19a0 Update docker-compose.yml 2026-07-21 04:41:25 +07:00
vasyansk b6e68bdd90 Add activity tracking to prevent stall timeouts during message transfers
Add OnActivity callback to CopyDeps to prevent stall timeouts during large message transfers
Implement touchReader and touchWriter wrappers to call OnActivity during FETCH and APPEND operations
Add slow message logging to identify performance bottlenecks
Add test case to verify activity reporting during message transfers
Clean up orchestrator account reset code formatting
2026-07-21 04:38:32 +07:00
vasyansk d125320667 fix dtt 2026-07-18 12:21:58 +07:00
vasyansk b352cda166 add kerio format support 2026-07-17 11:42:34 +07:00
vasyansk 5d296c39b1 Merge feat/selective-account-run: selective account run via checkboxes 2026-07-08 13:56:28 +07:00
vasyanskandClaude Opus 4.8 fc335dee3f Add selective account run implementation plan
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 13:55:02 +07:00
vasyansk b439eee164 Add account selection checkboxes and selective run button 2026-07-08 13:48:48 +07:00
vasyansk 2e5036aad5 runTask accepts optional accountIds 2026-07-08 13:44:53 +07:00
vasyansk 599c66189c Parse optional account_ids in run handler 2026-07-08 13:41:14 +07:00
vasyansk 315e56046b Add selectAccounts filter and accountIDs param to orchestrator.Run 2026-07-08 13:37:24 +07:00
vasyansk 692a83a468 fix domain 2026-07-08 13:34:53 +07:00
vasyansk 6d8471efdd add dick pics 2026-07-08 13:33:14 +07:00
vasyanskandClaude Opus 4.8 3eac1cea7d Add selective account run design spec
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 13:30:11 +07:00
vasyansk b076ac92d6 Add folder mapping status indicator to task list
Add account label to folder mapping modal

Update folder mapping logic to include destination login
2026-07-06 19:15:30 +07:00
vasyansk e84366eb0c Remove idle connection timeout handling
Remove error handling for closed connections

Add progress watchdog to detect stalled accounts

Improve error modal styling and pagination
2026-07-05 14:50:25 +07:00
vasyansk 95ddbf5619 Update copy.go 2026-07-05 13:59:56 +07:00
vasyansk 2bdb4904d6 Add stacked account display and fixed live progress row sizing
Improve account display by showing source/destination in a stacked format
when they differ, and add fixed sizing for live progress rows to prevent
resizing during scans. Also update the table header to use a single
"Account" column.
2026-07-05 12:20:33 +07:00
vasyansk 7ad326fa36 Update docker-compose-traefik.yml 2026-07-05 12:16:44 +07:00
vasyanskandClaude Opus 4.8 45b0ff2358 feat(errors): per-account error modal with persisted error list
Accounts finishing done_with_errors showed only a count and a single
last_error. This adds a modal listing every concrete error of the
account's most recent run.

- migration 0005: account_errors table (kind folder|message|account,
  folder, message_ref, error, created_at; ON DELETE CASCADE; indexed)
- store: AddAccountError / ClearAccountErrors / ListAccountErrors
- copy: OnError callback captures per-message error text (previously
  only counted), with a "UID N: subject" reference
- orchestrator: clear errors at run start; persist folder/message/
  account errors; cap 500 rows/account/run with a suppressed-note row
- api: GET /api/tasks/{id}/accounts/{accountId}/errors
- web: AccountErrorsModal, clickable ERRORS count, api + styles

Verified: migration applies on Postgres 18; store add/list/clear and
cascade tests pass against real pg; backend build/vet/test green; web
tsc+vite build and oxlint clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U9Eq4JtWjyNTv5qat3B3mM
2026-07-05 12:16:12 +07:00
vasyansk 2623bc8815 Reduce worker concurrency from 4 to 2
Reduce idle read timeout from 120s to 60s

Add batching for IMAP metadata fetches
2026-07-05 11:40:04 +07:00
vasyansk b9cc7749c8 Update docker-compose-traefik.yml 2026-07-05 11:24:44 +07:00
vasyansk d5192e1cf7 Add optional pprof endpoint for debugging 2026-07-04 21:31:53 +07:00
vasyansk dca1363ec9 Add IMAP connection timeout handling
Introduce idleConn wrapper to prevent wedged connections
Add test for silent server timeout behavior
Implement proper TLS handshake and greeting handling
Set explicit dial and read timeouts
2026-07-04 19:37:36 +07:00
vasyansk 8656f46674 Create 2026-07-03-scheduled-task-runs.md 2026-07-03 13:59:12 +07:00
vasyanskandClaude Opus 4.8 e104a77de1 Merge feat/scheduled-task-runs: recurring task execution
A 30s in-process scheduler auto-runs tasks on a recurring interval
(1/3/6/12/24h). Interval is measured from the last run's completion; a task
already running is never re-triggered. Enabling a schedule requires all
accounts tested OK. A breaker disables the schedule and flags the task broken
(red badge in list + detail) when a scheduled run errors or panics. Next-run
time (browser-local) and a run-log modal (per-run status/totals) are shown.
Migration 0004 adds tasks.schedule_interval_seconds/schedule_anchor/broken and
runs.trigger; task delete cascades runs as before.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 13:40:39 +07:00
vasyansk 64bcb1d60b fix: anchor floor on re-enable; breaker on scheduled panic; propagate next-run err; reject negative interval; close phantom runs on startup 2026-07-03 13:31:58 +07:00
vasyansk e8acab6920 feat(web): schedule control, next-run, broken badge, run-log modal 2026-07-03 13:19:14 +07:00
vasyanskandClaude Opus 4.8 d2c69c6a5e feat(api): schedule + runs endpoints; next_run_at on task detail
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 13:13:10 +07:00
vasyansk be777dc908 feat(orchestrator): thread run trigger; breaker on scheduled runs with errors 2026-07-03 13:08:21 +07:00
vasyansk b9421d388c feat(scheduler): 30s polling scheduler with pure NextRun/dueTaskIDs 2026-07-03 13:07:05 +07:00
vasyansk 8f93dcd97b feat(store): task schedule columns, run trigger, scheduling queries 2026-07-03 13:01:20 +07:00
vasyanskandClaude Opus 4.8 e8f29064fb docs: spec for scheduled (recurring) task runs
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 12:40:26 +07:00
vasyanskandClaude Opus 4.8 1810497c2a Merge feat/per-account-folder-mapping: per-account folder mapping + exclusion
Move folder config from task-level to per-account (accounts.folder_mapping +
excluded_folders, migrating existing task mapping). Add per-account folders
button that re-probes an account and opens the mapping modal with sync
checkboxes to exclude folders. Orchestrator builds each account's plan via
planFolders honoring per-account mapping/exclusions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 12:10:57 +07:00
vasyansk b59ce67497 fix: validate account on mapping PUT; gate folders btn during run; prune stale mapping keys; drop dead export 2026-07-03 12:08:22 +07:00
vasyansk 964e4cfc33 feat(web): per-account folders button + edit-mapping modal 2026-07-03 11:56:47 +07:00
vasyansk 1ba7b54e05 feat(web): folder-sync checkboxes + per-account mapping API client 2026-07-03 11:55:40 +07:00
vasyansk bdb3b72f38 feat(api): probe existing account + persist per-account folder mapping 2026-07-03 11:50:32 +07:00
vasyansk bc72f8172f feat(orchestrator): build copy plan from per-account mapping + exclusions 2026-07-03 11:46:31 +07:00
vasyansk d6d17ee544 feat(store): per-account folder_mapping + excluded_folders columns 2026-07-03 11:39:21 +07:00
vasyanskandClaude Opus 4.8 e7870c6aa4 docs: spec + plan for per-account folder mapping & exclusion
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 11:35:17 +07:00
vasyansk 79fd200e57 many fixes 2026-07-03 11:18:40 +07:00
vasyansk d909618ced Create docker-compose-traefik.yml 2026-07-02 15:31:27 +07:00
vasyanskandClaude Opus 4.8 4b9c806719 Merge fix/error-reporting-and-modal-reset
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMHQTtnQtQqL8muAXHr9kd
2026-07-02 15:14:11 +07:00
vasyanskandClaude Opus 4.8 477077d9e3 fix: consistent error reporting + reset mapping modal per account
Error consistency: folder-level failures were counted only toward the task's
done_with_errors status, not the account's error_count, so a task showed
DONE_WITH_ERRORS while its only account showed 0 errors / DONE. Now folder
errors increment the account counter and the account status becomes
done_with_errors when errs>0.

Visibility: persist accounts.last_error (migration 0002) so the failing folder
/ login error survives a page reload (shown red under the source login);
cleared at the start of each run.

Modal reset: the folder-mapping modal kept its selections across opens, so
adding a second account showed the first account's mapping. It now mounts
fresh per add (conditional render + key), reflecting the newly-probed folders.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMHQTtnQtQqL8muAXHr9kd
2026-07-02 15:14:11 +07:00
vasyanskandClaude Opus 4.8 cdb93926bf Merge feat/folder-mapping-ui: probe + folder mapping modal on add
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMHQTtnQtQqL8muAXHr9kd
2026-07-02 14:39:32 +07:00