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:
chick
2026-09-05 18:53:04 +08:00
parent f11877f13e
commit f9186bd851
97 changed files with 18646 additions and 104 deletions
@@ -122,4 +122,51 @@ describe('ScheduledOperationDispatcher', () => {
expect(sleep).toHaveBeenCalledWith(30_000);
db.close();
});
it('dispatches a baseband task against the baseband restart operation', async () => {
const db = new Database(':memory:');
migrateDatabase(db);
const prepare = vi.fn(async (input: { operationId: string; parameters: unknown }) => ({
id: 'prep-a',
confirmationToken: 'token',
...input,
}));
const dispatcher = new ScheduledOperationDispatcher({
db,
operations: {
prepare,
execute: vi.fn().mockResolvedValue({ id: 'job-a', status: 'succeeded' }),
},
messages: { send: vi.fn() },
store: { set: vi.fn(), get: vi.fn(), delete: vi.fn() },
repository: new ScheduledTaskRepository(db),
});
const result = await dispatcher.dispatch(
{
id: 'task-baseband',
name: 'Baseband',
operationType: 'restart-baseband',
cronExpression: '0 4 * * *',
timezone: 'Asia/Shanghai',
targetSelector: { mode: 'fixed', instanceIds: ['a'] },
misfirePolicy: 'skip',
overlapPolicy: 'skip',
retryPolicy: { maxRetries: 0, intervalSeconds: 60 },
enabled: true,
version: 1,
createdBy: 'operator',
updatedBy: 'operator',
createdAt: '2026-07-30T00:00:00.000Z',
updatedAt: '2026-07-30T00:00:00.000Z',
},
[{ id: 'a', revision: 1 }],
{ actor: 'operator', requestId: 'request-1' },
);
expect(result.outcome).toBe('succeeded');
expect(prepare.mock.calls[0]?.[0]).toMatchObject({
operationId: 'postBasebandRestart',
parameters: { parameterSchemaId: 'simadmin.58e2204.postBasebandRestart.parameters.v1' },
});
db.close();
});
});