feat(api): absorb the Hub control plane into the local instance model
Add central notification channels, rules, queue and delivery logs, fleet organization groups and tags, device discovery, the device action catalog, instance module reads, the log centre, connection settings and system maintenance as native /api/v1 routes backed by the existing secret store, audit trail and pinned upstream transport.
This commit is contained in:
@@ -2,9 +2,14 @@ import { JOB_STATUSES, type JobPageQuery, type JobStatus } from '@multi-simadmin
|
||||
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
|
||||
|
||||
import { JobQueryError, JobQueryService } from '../../application/jobs/job-query-service.js';
|
||||
import {
|
||||
JobCancelError,
|
||||
JobReconcileService,
|
||||
} from '../../application/jobs/job-reconcile-service.js';
|
||||
|
||||
export interface JobRoutesOptions {
|
||||
readonly jobs: JobQueryService;
|
||||
readonly reconcile?: JobReconcileService;
|
||||
}
|
||||
|
||||
const QUERY_KEYS = new Set([
|
||||
@@ -130,4 +135,40 @@ export function registerJobRoutes(app: FastifyInstance, options: JobRoutesOption
|
||||
'/api/v1/jobs/:jobId',
|
||||
handler((request) => options.jobs.get((request.params as { jobId: string }).jobId)),
|
||||
);
|
||||
|
||||
const reconcile = options.reconcile;
|
||||
if (reconcile) {
|
||||
app.get('/api/v1/jobs/reconcile', async () => reconcile.summary());
|
||||
app.post('/api/v1/jobs/reconcile', () => reconcile.reconcile());
|
||||
|
||||
app.post('/api/v1/jobs/:jobId/cancel', async (request, reply) => {
|
||||
const jobId = (request.params as { jobId: string }).jobId;
|
||||
try {
|
||||
reconcile.cancel(jobId);
|
||||
} catch (error) {
|
||||
if (!(error instanceof JobCancelError)) throw error;
|
||||
const mapped =
|
||||
error.code === 'NOT_FOUND'
|
||||
? {
|
||||
status: 404,
|
||||
title: 'Not Found',
|
||||
detail: 'The requested job does not exist.',
|
||||
}
|
||||
: {
|
||||
status: 409,
|
||||
title: 'Conflict',
|
||||
detail: 'The job already reached a terminal state.',
|
||||
};
|
||||
return reply.code(mapped.status).type('application/problem+json').send({
|
||||
type: 'about:blank',
|
||||
title: mapped.title,
|
||||
status: mapped.status,
|
||||
code: error.code,
|
||||
detail: mapped.detail,
|
||||
requestId: request.id,
|
||||
});
|
||||
}
|
||||
return reply.code(202).send(options.jobs.get(jobId));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user