GET /api/openclaw/datto-rmm/sites GET /api/openclaw/datto-rmm/devices (filters: siteUid, online, deleted, page, limit) GET /api/openclaw/datto-rmm/devices/[uid] GET /api/openclaw/datto-rmm/devices/[uid]/audit (always live) GET /api/openclaw/datto-rmm/alerts (filters: resolved, siteUid, deviceUid, limit) GET /api/openclaw/datto-rmm/alerts/open - All protected by x-openclaw-key header - Default: queries Pulse DB (datto_rmm_devices/alerts/sites tables) - ?live=true: proxies to Datto RMM API via DattoRMMClient - Responses include source:'db'|'live' for data freshness awareness
51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { validateOpenClawKey } from '@/lib/utils/openclaw-auth';
|
|
import { Pool } from 'pg';
|
|
import { getDattoRMMClient } from '@/lib/services/datto-rmm-factory';
|
|
|
|
const pool = new Pool({
|
|
host: process.env.POSTGRES_HOST,
|
|
port: parseInt(process.env.POSTGRES_PORT || '5432'),
|
|
database: process.env.POSTGRES_DB,
|
|
user: process.env.POSTGRES_USER,
|
|
password: process.env.POSTGRES_PASSWORD,
|
|
});
|
|
|
|
export async function GET(request: NextRequest) {
|
|
const authError = validateOpenClawKey(request);
|
|
if (authError) return authError;
|
|
|
|
const live = request.nextUrl.searchParams.get('live') === 'true';
|
|
|
|
try {
|
|
if (live) {
|
|
const client = getDattoRMMClient();
|
|
const sites = await client.getAllSites();
|
|
return NextResponse.json({
|
|
data: sites,
|
|
total: sites.length,
|
|
source: 'live',
|
|
});
|
|
}
|
|
|
|
const result = await pool.query(`
|
|
SELECT
|
|
id, uid, name, description, notes, on_demand,
|
|
autotask_company_id, autotask_company_name,
|
|
number_of_devices, number_of_online_devices, number_of_offline_devices,
|
|
portal_url, synced_at, updated_at
|
|
FROM datto_rmm_sites
|
|
ORDER BY name
|
|
`);
|
|
|
|
return NextResponse.json({
|
|
data: result.rows,
|
|
total: result.rowCount,
|
|
source: 'db',
|
|
synced_at: result.rows[0]?.synced_at ?? null,
|
|
});
|
|
} catch (error) {
|
|
const msg = error instanceof Error ? error.message : String(error);
|
|
return NextResponse.json({ error: msg }, { status: 500 });
|
|
}
|
|
}
|