← back to Norma

app/api/gmail/sync-status/route.ts

96 lines

import { NextRequest, NextResponse } from 'next/server';
import { requireRole } from '@/lib/require-role';
import { query } from '@/lib/db';

/**
 * GET /api/gmail/sync-status
 *
 * Returns sync status information for the dashboard widget:
 * - Last sync time
 * - Messages synced since last sync
 * - Sync health indicator (green/yellow/red)
 * - Recent sync log entries
 * - needs_reauth flag
 */
export async function GET(request: NextRequest) {
  const auth = requireRole(request, 'admin', 'staff');
  if (auth instanceof NextResponse) return auth;

  try {
    // Get primary mailbox status
    const mbRes = await query(
      `SELECT m.id, m.email, m.last_synced_at, m.needs_reauth, m.is_active,
              (SELECT count(*) FROM gmail_messages WHERE mailbox_id = m.id) AS total_messages,
              (SELECT count(*) FROM gmail_messages WHERE mailbox_id = m.id AND created_at > COALESCE(m.last_synced_at - INTERVAL '30 minutes', m.last_synced_at)) AS recent_messages
       FROM mailboxes m
       WHERE m.email = 'natalia@studentdebtcrisis.org'`,
    );

    if (mbRes.rows.length === 0) {
      return NextResponse.json({
        connected: false,
        lastSyncedAt: null,
        health: 'red',
        totalMessages: 0,
        recentMessages: 0,
        needsReauth: false,
        recentLogs: [],
      });
    }

    const mailbox = mbRes.rows[0];
    const lastSynced = mailbox.last_synced_at;

    // Compute health indicator
    let health: 'green' | 'yellow' | 'red' = 'red';
    if (lastSynced) {
      const minutesAgo = (Date.now() - new Date(lastSynced).getTime()) / 60000;
      if (minutesAgo <= 30) {
        health = 'green';
      } else if (minutesAgo <= 60) {
        health = 'yellow';
      } else {
        health = 'red';
      }
    }

    // Get recent sync logs
    const logsRes = await query(
      `SELECT id, started_at, completed_at, messages_synced, error, status
       FROM gmail_sync_log
       WHERE mailbox_id = $1
       ORDER BY started_at DESC
       LIMIT 5`,
      [mailbox.id],
    );

    // Messages since last sync
    let messagesSinceLastSync = 0;
    if (lastSynced) {
      const sinceRes = await query(
        `SELECT count(*) AS cnt FROM gmail_messages
         WHERE mailbox_id = $1 AND created_at >= $2`,
        [mailbox.id, lastSynced],
      );
      messagesSinceLastSync = parseInt(sinceRes.rows[0]?.cnt || '0', 10);
    }

    return NextResponse.json({
      connected: true,
      lastSyncedAt: lastSynced,
      health,
      totalMessages: parseInt(mailbox.total_messages, 10) || 0,
      messagesSinceLastSync,
      needsReauth: mailbox.needs_reauth || false,
      isActive: mailbox.is_active,
      recentLogs: logsRes.rows,
    });
  } catch (err) {
    console.error('[gmail/sync-status] Error:', (err as Error).message);
    return NextResponse.json(
      { error: 'Failed to get sync status' },
      { status: 500 },
    );
  }
}