feat(service-integrations): phase 1 — integration architecture foundation
- Add Integration interfaces, registry, cache, encryption, and base helpers - Add integrationType, integrationConfig, integrationEnabled to App model - Add integration widget type to constants and validators - Add integration fields to AppRecord, CreateAppInput, UpdateAppInput - Update appService with encryption/decryption for integration config - Add API routes: list integrations, test connection, fetch endpoint data
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import { json } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { requireAuth } from '$lib/server/middleware/authenticate.js';
|
||||
import { listInfo } from '$lib/server/integrations/registry.js';
|
||||
import { success } from '$lib/server/utils/response.js';
|
||||
|
||||
/**
|
||||
* GET /api/integrations — List available integration types.
|
||||
*/
|
||||
export const GET: RequestHandler = async (event) => {
|
||||
requireAuth(event);
|
||||
|
||||
const integrations = listInfo();
|
||||
return json(success(integrations));
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
import { json } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { z } from 'zod';
|
||||
import { requireAuth } from '$lib/server/middleware/authenticate.js';
|
||||
import * as registry from '$lib/server/integrations/registry.js';
|
||||
import { success, error } from '$lib/server/utils/response.js';
|
||||
|
||||
const testConnectionSchema = z.object({
|
||||
integrationType: z.string().min(1, 'Integration type is required'),
|
||||
appUrl: z.string().url('Invalid app URL'),
|
||||
config: z.record(z.unknown())
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /api/integrations/test — Test an integration connection.
|
||||
*/
|
||||
export const POST: RequestHandler = async (event) => {
|
||||
requireAuth(event);
|
||||
|
||||
let body: unknown;
|
||||
try {
|
||||
body = await event.request.json();
|
||||
} catch {
|
||||
return json(error('Invalid JSON body'), { status: 400 });
|
||||
}
|
||||
|
||||
const parsed = testConnectionSchema.safeParse(body);
|
||||
if (!parsed.success) {
|
||||
return json(error(parsed.error.errors[0]?.message ?? 'Invalid input'), { status: 400 });
|
||||
}
|
||||
|
||||
const { integrationType, appUrl, config } = parsed.data;
|
||||
|
||||
const integration = registry.get(integrationType);
|
||||
if (!integration) {
|
||||
return json(error(`Unknown integration type: ${integrationType}`), { status: 404 });
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await integration.testConnection(appUrl, config);
|
||||
return json(success(result));
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : 'Connection test failed';
|
||||
return json(error(message), { status: 500 });
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user