feat(mail): Phase 4 archive jobs#159
Conversation
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
- Add create_archive_job, list_archive_jobs, get_archive_job, cancel_archive_job, delete_archive_job, and process_archive_job to MailService. - Add update_mail_import_job_status to MetadataStore for atomic status transitions. - Add FromStr impl for MailImportJobStatus to support status parsing. - Update SQLx offline query cache. Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
- Advance the UID watermark across IMAP gaps while stopping at the first failure, so deleted-message gaps do not stall progress. - Propagate retention cleanup failures instead of swallowing them. - Log event-store append failures for MailImported, MailArchiveJobCompleted, MailArchiveJobFailed, and MailArchiveJobStarted events. - Cap max_retries validation at 100 in the archive-job handler. - Add integration test for non-contiguous UID watermark advancement. Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
The test created two independent mock sessions, so the fetch counter on the first session only counted one fetch. Capture the second session's counter and assert the total fetch count across both sessions. Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
692fd0a to
97881c6
Compare
Signed-off-by: Senol Colak <senol@kubedo.com>
97881c6 to
43c3315
Compare
Signed-off-by: Senol Colak <senol@kubedo.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9a18cf5d2e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: Senol Colak <senol@kubedo.com>
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7545d7558a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: Senol Colak <senol@kubedo.com>
|
@codex review |
|
To use Codex here, create a Codex account and connect to github. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 74f1a7a4f8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…jobs - Skip archive retention when the job is no longer running, so cancelling a scan does not delete aged messages. - Reassign archived messages from a deleted archive job to a new archive job so the new job's retention policy applies; active overlapping jobs keep their ownership to avoid a ping-pong race. - Owner-scope the new update_mail_message_archive_job_id query. - Cancel a running archive job before soft-deleting it so a worker does not get stuck in a running state against a deleted row. - Hard-delete mail_message_parts and mail_attachments rows when applying archive retention, so internal metadata is also purged. - Add integration tests for retention-on-cancel, ownership reassignment, and deleting a running archive job; extend retention test to assert parts and attachments are removed. Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
|
@codex review |
Follow-up to the deep-review pass: - soft_delete_mail_archive_job now atomically sets status = 'cancelled' so deleting a running job cannot leave it stuck in 'running' against a deleted row. delete_archive_job drops the separate cancel call. - apply_archive_retention verifies the owning archive job is still 'running' inside its transaction, closing the gap between the service-layer guard and the retention UPDATE. - maybe_reassign_archive_message_ownership now also takes over messages from cancelled or failed archive jobs, not only deleted ones, so those messages remain under an active retention policy. - Add integration test for ownership reassignment from a cancelled job. Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
|
All Codex review comments have been addressed and resolved. Summary of fixes pushed:
Verification run:
All pass. Per project safety boundaries this still needs human review before merge (external IMAP imports, retention/soft-delete, storage queries). |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dc0f354d29
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
IMAP SINCE/BEFORE search criteria are date-only, so the previous DateTime<Utc> API silently dropped the time component and produced unexpected inclusions/exclusions. Change the API, domain type, migration, and IMAP client to use NaiveDate so callers get exactly the behavior the IMAP query implements. Also fixes two new Codex findings: - update_mail_message_archive_job_id is now a compare-and-swap that matches the previous archive_job_id, preventing concurrent replacement jobs from stealing ownership from each other. - apply_archive_retention verifies the owning job is still running inside the transaction, and ownership is reassigned from cancelled/failed jobs as well as deleted ones. Refs #147 Signed-off-by: Senol Colak <senol@kubedo.com>
|
Follow-up fixes pushed (6a3c092):
All verification commands still pass. |
…ation test The retention pass now verifies the owning archive job is still running inside the transaction. Update the integration test to mark the job running before the second pass so the aged message is soft-deleted as expected. Also remove the now-unused NaiveDate import. Signed-off-by: Senol Colak <senol@kubedo.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Another round soon, please! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Implements RustShare Mail Phase 4: folder/date-range IMAP archive jobs with incremental sync, retention, retry/backoff, and failure handling.
Scope:
mail_import_jobswithsource_mode = 'imap_archive'.archive_job_idscoping tomail_messagesfor retention.Refs #147
Design doc:
docs/plans/2026-07-09-mail-phase4-archive-jobs-plan.mdNote: this touches migrations, external IMAP imports, retention/soft-delete, and tenant/owner scoping; per project safety boundaries it should have human review before merge.