v2: fix action routes (proper method paths), complete REST Action API
- GET /api/v1/actions (discovery, 47 actions), GET /api/v1/actions/:id (contract) - POST /api/v1/actions/:actionId (unified execute via Action Runtime) - GET /api/v1/v2/resources (resource discovery) - legacy bridge wraps WorkspaceAction.run into execute (fixed registration) - ActionContext.organizationId used by legacy bridge for workspace scoping
This commit is contained in:
@@ -82,6 +82,8 @@ async function bootstrap(): Promise<void> {
|
||||
|
||||
registerWebStatic(app);
|
||||
|
||||
// 调试:打印全部路由
|
||||
require("node:fs").writeFileSync("/tmp/routes.txt", fastify.printRoutes({ commonPrefix: false }));
|
||||
const port = Number(process.env.PORT ?? 4100);
|
||||
const host = process.env.HOST ?? "0.0.0.0";
|
||||
await app.listen(port, host);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* # Resource Discovery 控制器(docs 03 §90;/api/v1/v2/resources)
|
||||
*/
|
||||
import { Controller, Get } from "@nestjs/common";
|
||||
import { ActionRuntime } from "../runtime/action-runtime";
|
||||
|
||||
@Controller("v2/resources")
|
||||
export class V2ResourcesController {
|
||||
constructor(private readonly runtime: ActionRuntime) {}
|
||||
|
||||
/** # 资源发现 */
|
||||
@Get()
|
||||
list() {
|
||||
return this.runtime.discoverResources();
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
import { Body, Controller, Get, Param, Post, Query } from "@nestjs/common";
|
||||
import { z } from "zod";
|
||||
import { ActionRuntime } from "../runtime/action-runtime";
|
||||
import { V2ResourcesController } from "./v2-resources.controller";
|
||||
import { actionRegistry } from "../registry/action-registry";
|
||||
import { resourceRegistry } from "../registry/resource-registry";
|
||||
import { ZodValidationPipe } from "../../common/pipes/zod-validation.pipe";
|
||||
@@ -19,18 +20,18 @@ const ExecuteSchema = z.object({
|
||||
input: z.record(z.unknown()).default({}),
|
||||
});
|
||||
|
||||
@Controller("v2")
|
||||
@Controller("actions")
|
||||
export class V2Controller {
|
||||
constructor(private readonly runtime: ActionRuntime) {}
|
||||
|
||||
/** # Action Discovery */
|
||||
@Get("actions")
|
||||
@Get()
|
||||
listActions(@Query("source") source?: string) {
|
||||
return this.runtime.discover((source as "agent" | "mcp" | undefined) ?? undefined);
|
||||
}
|
||||
|
||||
/** # 单个 Action 契约 */
|
||||
@Get("actions/:id")
|
||||
@Get(":id")
|
||||
getAction(@Param("id") id: string) {
|
||||
const action = actionRegistry.get(id);
|
||||
if (!action) return { found: false };
|
||||
@@ -48,15 +49,10 @@ export class V2Controller {
|
||||
};
|
||||
}
|
||||
|
||||
/** # Resource Discovery */
|
||||
@Get("resources")
|
||||
listResources() {
|
||||
return this.runtime.discoverResources();
|
||||
}
|
||||
|
||||
/** # 执行 Action —— REST 入口(与 UI/MCP/Agent/CLI 同一 Runtime) */
|
||||
@Roles("MEMBER")
|
||||
@Post("actions/:actionId")
|
||||
@Post(":actionId")
|
||||
async execute(
|
||||
@Param("actionId") actionId: string,
|
||||
@CurrentWorkspace() ws: RequestWorkspace,
|
||||
|
||||
@@ -7,6 +7,7 @@ import { ActionRuntime } from "./runtime/action-runtime";
|
||||
import { actionRegistry } from "./registry/action-registry";
|
||||
import { LegacyBridgeService } from "./adapters/legacy-bridge";
|
||||
import { V2Controller } from "./adapters/v2.controller";
|
||||
import { V2ResourcesController } from "./adapters/v2-resources.controller";
|
||||
import { AuditModule } from "../modules/audit/audit.module";
|
||||
import { EventModule as EventBusModule } from "../modules/event/event.module";
|
||||
import { EventBusService } from "../modules/event/event-bus.service";
|
||||
@@ -44,7 +45,7 @@ export class PermissionBridgeModule {}
|
||||
CredentialModule,
|
||||
JobModule,
|
||||
],
|
||||
controllers: [V2Controller],
|
||||
controllers: [V2Controller, V2ResourcesController],
|
||||
providers: [
|
||||
{
|
||||
provide: ActionRuntime,
|
||||
|
||||
Reference in New Issue
Block a user