improve gmail sync: email input, permanent errors, auto-dock

- add isync to setup.sh
- ask for gmail address alongside app password in integrations
- add PermanentError to job queue (skips retries for non-recoverable failures)
- use PermanentError for missing credentials, missing executable, auth failures
- auto-add /email to dock after successful gmail sync
- invalidate dock cache on sync completion for seamless UI update

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-04 23:13:55 +00:00
co-authored by Claude Opus 4.6
parent 8737681464
commit aa0207436c
7 changed files with 146 additions and 43 deletions
+6 -3
View File
@@ -110,7 +110,7 @@ integrationsRouter.get('/google/verify', async (ctx) => {
const body = await res.json();
const valid = body.error === 'invalid_grant' || body.error === 'redirect_uri_mismatch';
return ctx.json({ valid, error: valid ? null : body.error_description ?? body.error });
return ctx.json({ valid, error: valid ? null : (body.error_description ?? body.error) });
});
// --- Personal: Google account connection status ---
@@ -132,17 +132,20 @@ integrationsRouter.get('/google/status', async (ctx) => {
integrationsRouter.put('/google/app-password', async (ctx) => {
const user = ctx.get('user');
const body = ctx.get('body') as { appPassword?: string };
const body = ctx.get('body') as { appPassword?: string; email?: string };
if (!body.appPassword) throw BAD_REQUEST('Missing appPassword');
const connection = await getUserIntegration(user.id, 'google');
const connConfig = (connection?.config as Record<string, unknown>) ?? {};
const updated: Record<string, unknown> = { ...connConfig, imapAppPassword: body.appPassword };
if (body.email) updated.email = body.email;
await upsertUserIntegration({
userId: user.id,
provider: 'google',
serverIntegrationId: connection?.serverIntegrationId ?? undefined,
config: { ...connConfig, imapAppPassword: body.appPassword },
config: updated,
});
return ctx.json({ ok: true });