Skip to content

feat: mail dedupe addon + list filter/sort (passes 8–12)#98

Open
jasincanada wants to merge 19 commits into
root-fr:mainfrom
jasincanada:main
Open

feat: mail dedupe addon + list filter/sort (passes 8–12)#98
jasincanada wants to merge 19 commits into
root-fr:mainfrom
jasincanada:main

Conversation

@jasincanada

Copy link
Copy Markdown

Summary

  • Mail dedupe addon: settings, sidebar actions, /dedupe operations page, list highlights, dupes/ folder handling
  • List filter/sort restore (pass 12): read filter, search merge, scroll pagination, dedicated control row
  • docs/TESTER_TASKS.md manual QA checklist
  • Unit tests for list-query-utils

Review tracking

Follow-up from B+ code review is tracked in epic #97 (#77#96).

Test plan

  • Run docs/TESTER_TASKS.md quick smoke (S-1–S-5)
  • List filter/sort section (L-1–L-16)
  • Unread safety (U-1–U-6)

Add browser-side duplicate detection and removal: settings UI, sidebar
folder actions, /dedupe operations page, list highlights, and dupes/
folder handling. Restore list filter/sort controls (read filter, search
merge, scroll pagination) with list-query-utils and tests.

Includes docs/TESTER_TASKS.md for manual QA. Review follow-ups tracked
in GitHub epic root-fr#97.
Rename product branding (UI title, locales, metadata, Docker labels).
Point package.json and image metadata at jasincanada/JasMail while
keeping upstream fetch from root-fr/jmap-webmail.
Add docs/JASMAIL_CHANGELOG.md, bump VERSION to 1.6.0, update README
with fork links, and point TESTER_TASKS at jasincanada/JasMail issues.
- Batch folder scans in 500-message pages with slimmed email refs
- Require confirmation before folder/account remove on /dedupe
- Use preview-only body matching; block body criterion above 2k msgs

Closes #4, #5, #6
- Unify search/refresh with resolveMailboxListQuery (#7, #8, N2)
- Server-side subject/sender sort + partial-sort hint (#9)
- Namespace shared mailboxIds in getEmailsForDedupe (#10)
- Stop creating dupes/ on scan-only (#11)
- Cancel long dedupe operations between batches (#12)
- Re-check large-folder confirmation on Run again (N1)
- Fail scan on empty pagination page instead of silent under-scan

Closes #7, #8, #9, #10, #11, #12
Reset operations store and startedRef on cancel, navigate-away, and
DedupeAbortedError. Guard success paths so aborted runs do not toast
or mark complete after the user leaves /dedupe.
…3, N4–N6)

- Clear per-mailbox highlights after folder remove; copy match keys in GroupCard
- Reset startedRef on unmount; dedupe mergeJMAPFilters; parallel account scan (×3)
- Abort signal through list fetch and dedupe JMAP calls; date-only server sort
- Account scan confirmation; settings remove confirm; i18n for list controls
- Scanned stat uses actual position; body preview false-positive warning
- Dedupe auto-start/confirm races, AbortError handling, run-again guard
- JMAP moves remove source mailbox; validate Email/set responses; batch thread moves
- loadMoreEmails stale guard; getThreadEmails chunked with strict validation
- Account-scoped archive; shared-folder accountId on conversation load
- Remove dedupeBusy dead code; account dedupe progress banner
- Scan/apply split with action picker and tiered confirmation
- Server-side SQLite audit API and Docker volume support
- Built-in dedupe actions including delete_with_retention (90-day)
- Remove auto-remove entry points; redirect action=remove to scan
- JasMail dev OS skills under .grok/skills/jasmail-*
- Plan: docs/plans/DEDUPE_V1.7.md

748 tests pass.
- Orchestrator: implement → test-write → micro-review → 7 specialist
  reviewers → bugfix loop → build gates → docs → tag (SHIP CLEAR required)
- New bots: implementer, test-writer, plan/security/test/a11y/i18n/stack reviewers
- Persisted review artifacts in docs/reviews/; RELEASE_CHECKLIST template
- Living memory: review-patterns.md, ACTIVE_MILESTONE.md
- Ship gates: eslint --max-warnings 0, check:locales, check:ship scripts
- CONTRIBUTING.md documents JasMail development OS workflow
- Scripts: ship-gate, validate-review-artifact, diff-scope, sync-locales,
  record-review-metrics (+ shared dev-os-utils)
- Hooks: pre-commit check:ship; pre-push blocks tags without SHIP CLEAR artifact
- CI: .github/workflows/ci.yml (quick + full ship gate on main)
- Docs: DEV_OS.md hub, DEV_OS_MAINTENANCE.md, scripts/README.md, skill index
- Learning: metrics.jsonl, RETROSPECTIVE_TEMPLATE, METRICS schema, DEV_OS_CHANGELOG
- Fix npm run lint; unify check:ship via ship-gate.mjs
Lock in solo-dev maximum quality: binding DEV_OS_POLICY, upstream merge
workflow, CVE strict checks, all specialists on every release, and
check:ship:maximum (dedupe suite + E2E on port 3456 + upstream fetch).
- Add gate-logic tests, dedupe URL redirect regression, docker in maximum gate
- Review artifact docs/reviews/2026-06-20-v1.7.1-review.md
- Dev OS 2.2.0 maximum quality policy shipped and validated
Stalwart/JMAP can return messageId or subject as arrays or other types.
coerceJmapString prevents buildDedupeKey from calling .trim on non-strings.
- Dedupe page in mail shell; Stalwart-aware limits; CLI/limits/recent-runs panels
- fix: coerce non-string JMAP fields in dedupe scan (e.trim)
- Dev OS 2.3: jasmail-vulnerability-reviewer, check:vulnerabilities gate
- jasmail-github-sync subagent for fork pushes between releases
- docs/plans/DEDUPE_SERVER_JOBS.md server-side dedupe architecture

Refs #24 #25. Not tagged — manual QA deferred.
- Harden vulnerability-scan: fail on npm audit parse errors, Node
  fallback when rg is absent, exclude docs/.env.example from secrets
- Coerce threadId in dedupe keys; document object JMAP coercion
- Dedupe page mobile title, recent-runs a11y and enum i18n fallbacks
- Translate dedupe.cli/limits/runs in all 9 non-en locales
- Add folder_too_large and getDedupeLimits regression tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant