email: store emails.db per account under email_accounts/<account>/

Reorganizes email storage: the DB moves from DATA_PATH/<user>/emails.db to
DATA_PATH/<user>/email_accounts/<accountEmail>/emails.db, with a shared
email_accounts/attachment_cache/ (was Gmail/emails/attachments). openEmailDb now
takes (owner, account); a new openUserEmailDb(owner, userId) resolves the user's
configured account (first enabled) for read paths. Threads the account through
email.ts, accounts, resync, queue sync, channel handlers, and the email_db MCP
tool path. Drops the dead getUserEmailDir helper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-24 13:34:29 +00:00
co-authored by Claude Opus 4.8
parent 9271e63eef
commit 33a0bb4578
13 changed files with 118 additions and 71 deletions
+4 -4
View File
@@ -40,7 +40,7 @@ async function refreshCredentials(creds: GmailCredentials): Promise<GmailCredent
return { ...creds, accessToken: refreshed.accessToken, expiresAt: refreshed.expiresAt };
}
async function gmailResync(userEmail: string): Promise<ResyncResult> {
async function gmailResync(userEmail: string, accountEmail: string): Promise<ResyncResult> {
let creds = await loadGmailCredentials(userEmail);
if (!creds.accessToken) {
throw new Error('OAuth not configured — connect Google in Settings → Integrations for resyncs');
@@ -48,7 +48,7 @@ async function gmailResync(userEmail: string): Promise<ResyncResult> {
creds = await refreshCredentials(creds);
const db = openEmailDb(userEmail);
const db = openEmailDb(userEmail, accountEmail);
try {
const result = await gmailApiSync({ creds, db });
@@ -154,7 +154,7 @@ async function imapResync(account: ImapAccountInfo, userEmail: string): Promise<
if (!freshAccount) throw new Error(`Email account ${account.id} not found`);
const syncMeta = (freshAccount.syncMeta ?? {}) as Record<string, unknown>;
const db = openEmailDb(userEmail);
const db = openEmailDb(userEmail, account.email);
const existingIds = new Set<string>();
const rows = db.query('SELECT id FROM emails').all() as Array<{ id: string }>;
for (const row of rows) existingIds.add(row.id);
@@ -289,7 +289,7 @@ async function doResync({ accountId, userEmail, userId }: ResyncParams): Promise
// Gmail API resync needs OAuth; a gmail account authed with an app password resyncs over IMAP.
if (account.provider === 'gmail' && account.authType === 'oauth') {
return gmailResync(userEmail);
return gmailResync(userEmail, account.email);
}
return imapResync(