# MAIL-001 consolidated job-email hub

Updated: 2026-08-09

Status: `IN PROGRESS`. Canonical hub routing and provider-neutral read capability discovery are implemented and locally verified; provider actions and draft/send work remain.

## Revalidated current boundaries

- `/correspondence` listed persisted, job-linked `Correspondence` rows with search/direction/link filters.
- `/correspondence/review` separately rendered Gmail review candidates/suggested jobs and linked back to the inbox.
- The job workspace already embeds the shared `Correspondence` component and therefore reads/writes the same underlying rows rather than a copy.
- Gmail review decisions, import/link/unlink/relink and job creation use existing Gmail APIs. Outlook/Graph and IMAP connection models exist, but this review surface is Gmail-specific.
- The per-job composer currently logs a message to `Correspondence`; it is not a provider-send draft flow. Separate follow-up sending exists elsewhere and must not be mislabeled or silently reused.

## Implemented first increment

- `/correspondence` is the canonical **Job email** hub with linked-message and recruitment-suggestion views represented by `?view=review`.
- The review component embeds under the hub with correct heading hierarchy and without duplicate back navigation.
- `/correspondence/review` remains a compatibility route and redirects to the canonical filtered hub.
- Switching to review does not issue the linked-correspondence query; switching views reuses the existing tested review component and APIs.
- No provider connection, sync, import, link or send behavior changed.

## Implemented provider-neutral read increment

- Added one authenticated `/api/email` controller over the existing `IEmailProviderRegistry` for provider status, search, thread summaries and plain-text message detail.
- Every operation passes the authenticated owner ID into the registered Gmail, Outlook or IMAP adapter and rejects unknown or disconnected providers before mailbox access.
- Message detail intentionally omits provider HTML. Untrusted provider markup is not exposed through this shared endpoint.
- The hub now identifies connected and disconnected providers and advertises their actual capability. Gmail, Outlook and IMAP are currently shown as read-only because their installed scopes/contracts do not implement provider send.
- The controller does not change OAuth scopes, connect accounts, invoke providers in tests or claim that the legacy SMTP follow-up sender is provider-native.

## Verification

- Focused provider controller: 3/3 tests; focused hub/review: 2 suites, 5/5 tests.
- Full backend: 604/604; full frontend: 49/49 suites, 186/186 tests.
- Production build/TypeScript and `git diff --check`: pass.
- Implementation commits: `6008b4a`, `536d403`.

## Remaining MAIL-001 work

- Use the provider-neutral thread/list/detail API in a shared hub/application message view while preserving provider capability differences.
- Surface provider identity, reauthorization, read/unread, pin/read-later/archive/spam/trash only where the provider supports it.
- Share thread detail and link/unlink actions between hub and job workspace.
- Design editable provider drafts with recipient/subject/thread/provider review and explicit confirmed, idempotent send; uncertain failures must not be retried blindly.
- Preserve minimal audit metadata without sensitive body logging; verify Free non-AI access and Pro-only AI assistance.
- Complete link/unlink/dismiss/draft/send/failure/two-user/application-embed tests plus browser/production provider gates. No real email may be sent during repository verification.

## Validation limitation

The first focused Jest invocation exhibited the repository's open-handle delay. The passing focused and full runs used `--forceExit`; the full run took 228.709 seconds. A Next build process also failed to exit after compilation; only the exact PIDs started by those build attempts were stopped, then a clean build completed. This is recorded as tooling/runtime behavior, not hidden.

## Rollback

Revert `536d403` to remove the provider-neutral API/status chips, then `6008b4a` to restore the separate route presentation. Persisted email/correspondence data and provider scopes remain unchanged.
