feat(server): ServerModule skeleton with shared ServerContext, worker runs engine + outbox relay (B6)

modules/{auth-settings,sources-identity,acquisition-organize,agent} placeholders listed in
SERVER_MODULES; ServerModule registers routes (under /api/v1, authenticated), tasks,
outbox routes, capabilities and background loops. bootstrap() builds ServerContext (db,
config, logger, events, engine, outbox writer, secrets placeholder, settings reader,
capability registry), fills unregistered tasks with stubs and rejects duplicate task or
outbox ownership. worker starts the OpenWorkflow worker, OutboxRelay and module start().
--role migrate also migrates the engine schema; api/worker connect without migrating.
tasks: TaskRegistry.has, migrateEngineSchema.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-27 19:30:55 +08:00
1 parent ef3998767c
commit 9858b8494d
23 files changed
+829 -22

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
import type { DownloaderClient, SiteRelease } from "@umt/adapters";
import type { DomainDownloadStatus, SiteReleaseLike } from "@umt/mapping";
import { toDomainDownloadStatus } from "@umt/mapping";
import { describe, expect, it } from "vitest";
// @umt/mapping 不依赖 adapters;server 同时依赖两者,在这里做类型层兼容校验。
type Assert<T extends true> = T;
export type _SiteReleaseCompatible = Assert<SiteRelease extends SiteReleaseLike ? true : false>;
// 删数据接口必须带安全检查输入(B7)
export type _DeleteRequiresSafety = Assert<
{ deleteFiles: true } extends Parameters<DownloaderClient["delete"]>[1] ? false : true
>;
describe("mapping ↔ adapters 兼容", () => {
it("adapters 的 SiteRelease 可直接交给 mapping", () => {
const status: DomainDownloadStatus = toDomainDownloadStatus("paused", "threshold");
expect(status).toBe("paused_by_threshold");
});
});