refactor: 代码审查修复 — 错误边界、DRY抽取、测试修复、合规性改进
- P1: server.ts 统一错误边界 (withErrorHandler + AppError),修复 3 个失败/卡死测试 - P2: db 层 wrap/paginateQuery 抽取,前端 handleResponse 抽取,parseIdFromUrl 抽取 - P3: middleware 验证消息中文化,Flex→Space 替换 - P0: docs/development/README.md 新增已知设计决策章节 - P3-11 setup 拆分已尝试回退(@testing-library/react preload 依赖无法拆分) - P3-13 config 层测试从本次变更移除
This commit is contained in:
@@ -5,6 +5,7 @@ import type { Logger } from "./logger";
|
||||
import type { StaticAssets } from "./static";
|
||||
|
||||
import { createApiError, jsonResponse } from "./helpers";
|
||||
import { withErrorHandler } from "./middleware";
|
||||
import { handleMeta } from "./routes/meta";
|
||||
import { serveStaticAsset } from "./static";
|
||||
import { readAppVersion } from "./version";
|
||||
@@ -38,112 +39,196 @@ export function startServer(options: StartServerOptions) {
|
||||
routes: {
|
||||
"/api/*": () => jsonResponse(createApiError("API route not found", 404), { mode, status: 404 }),
|
||||
"/api/meta": {
|
||||
GET: async () => {
|
||||
const resolvedVersion = await resolveVersion();
|
||||
return handleMeta(mode, resolvedVersion);
|
||||
},
|
||||
GET: withErrorHandler(
|
||||
async () => {
|
||||
const resolvedVersion = await resolveVersion();
|
||||
return handleMeta(mode, resolvedVersion);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
},
|
||||
"/api/models": {
|
||||
GET: async (req) => {
|
||||
const { handleListModels } = await import("./routes/models/list");
|
||||
return handleListModels(req, db, mode);
|
||||
},
|
||||
POST: async (req) => {
|
||||
const { handleCreateModel } = await import("./routes/models/create");
|
||||
return handleCreateModel(req, db, mode);
|
||||
},
|
||||
GET: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleListModels } = await import("./routes/models/list");
|
||||
return handleListModels(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
POST: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleCreateModel } = await import("./routes/models/create");
|
||||
return handleCreateModel(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
},
|
||||
"/api/models/:id": {
|
||||
DELETE: async (req) => {
|
||||
const { handleDeleteModel } = await import("./routes/models/delete");
|
||||
return handleDeleteModel(req, db, mode);
|
||||
},
|
||||
GET: async (req) => {
|
||||
const { handleGetModel } = await import("./routes/models/get");
|
||||
return handleGetModel(req, db, mode);
|
||||
},
|
||||
PATCH: async (req) => {
|
||||
const { handleUpdateModel } = await import("./routes/models/update");
|
||||
return handleUpdateModel(req, db, mode);
|
||||
},
|
||||
DELETE: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleDeleteModel } = await import("./routes/models/delete");
|
||||
return handleDeleteModel(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
GET: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleGetModel } = await import("./routes/models/get");
|
||||
return handleGetModel(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
PATCH: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleUpdateModel } = await import("./routes/models/update");
|
||||
return handleUpdateModel(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
},
|
||||
"/api/models/test": {
|
||||
POST: async (req) => {
|
||||
const { handleTestModelConfig } = await import("./routes/models/test");
|
||||
return handleTestModelConfig(req, db, mode);
|
||||
},
|
||||
POST: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleTestModelConfig } = await import("./routes/models/test");
|
||||
return handleTestModelConfig(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
},
|
||||
"/api/projects": {
|
||||
GET: async (req) => {
|
||||
const { handleListProjects } = await import("./routes/projects/list");
|
||||
return handleListProjects(req, db, mode);
|
||||
},
|
||||
POST: async (req) => {
|
||||
const { handleCreateProject } = await import("./routes/projects/create");
|
||||
return handleCreateProject(req, db, mode);
|
||||
},
|
||||
GET: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleListProjects } = await import("./routes/projects/list");
|
||||
return handleListProjects(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
POST: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleCreateProject } = await import("./routes/projects/create");
|
||||
return handleCreateProject(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
},
|
||||
"/api/projects/:id": {
|
||||
DELETE: async (req) => {
|
||||
const { handleDeleteProject } = await import("./routes/projects/delete");
|
||||
return handleDeleteProject(req, db, mode);
|
||||
},
|
||||
GET: async (req) => {
|
||||
const { handleGetProject } = await import("./routes/projects/get");
|
||||
return handleGetProject(req, db, mode);
|
||||
},
|
||||
PATCH: async (req) => {
|
||||
const { handleUpdateProject } = await import("./routes/projects/update");
|
||||
return handleUpdateProject(req, db, mode);
|
||||
},
|
||||
DELETE: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleDeleteProject } = await import("./routes/projects/delete");
|
||||
return handleDeleteProject(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
GET: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleGetProject } = await import("./routes/projects/get");
|
||||
return handleGetProject(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
PATCH: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleUpdateProject } = await import("./routes/projects/update");
|
||||
return handleUpdateProject(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
},
|
||||
"/api/projects/:id/archive": {
|
||||
POST: async (req) => {
|
||||
const { handleArchiveProject } = await import("./routes/projects/archive");
|
||||
return handleArchiveProject(req, db, mode);
|
||||
},
|
||||
POST: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleArchiveProject } = await import("./routes/projects/archive");
|
||||
return handleArchiveProject(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
},
|
||||
"/api/projects/:id/restore": {
|
||||
POST: async (req) => {
|
||||
const { handleRestoreProject } = await import("./routes/projects/restore");
|
||||
return handleRestoreProject(req, db, mode);
|
||||
},
|
||||
POST: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleRestoreProject } = await import("./routes/projects/restore");
|
||||
return handleRestoreProject(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
},
|
||||
"/api/providers": {
|
||||
GET: async (req) => {
|
||||
const { handleListProviders } = await import("./routes/providers/list");
|
||||
return handleListProviders(req, db, mode);
|
||||
},
|
||||
POST: async (req) => {
|
||||
const { handleCreateProvider } = await import("./routes/providers/create");
|
||||
return handleCreateProvider(req, db, mode);
|
||||
},
|
||||
GET: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleListProviders } = await import("./routes/providers/list");
|
||||
return handleListProviders(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
POST: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleCreateProvider } = await import("./routes/providers/create");
|
||||
return handleCreateProvider(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
},
|
||||
"/api/providers/:id": {
|
||||
DELETE: async (req) => {
|
||||
const { handleDeleteProvider } = await import("./routes/providers/delete");
|
||||
return handleDeleteProvider(req, db, mode);
|
||||
},
|
||||
GET: async (req) => {
|
||||
const { handleGetProvider } = await import("./routes/providers/get");
|
||||
return handleGetProvider(req, db, mode);
|
||||
},
|
||||
PATCH: async (req) => {
|
||||
const { handleUpdateProvider } = await import("./routes/providers/update");
|
||||
return handleUpdateProvider(req, db, mode);
|
||||
},
|
||||
DELETE: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleDeleteProvider } = await import("./routes/providers/delete");
|
||||
return handleDeleteProvider(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
GET: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleGetProvider } = await import("./routes/providers/get");
|
||||
return handleGetProvider(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
PATCH: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleUpdateProvider } = await import("./routes/providers/update");
|
||||
return handleUpdateProvider(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
},
|
||||
"/api/providers/options": {
|
||||
GET: async () => {
|
||||
const { handleListProviderOptions } = await import("./routes/providers/options");
|
||||
return handleListProviderOptions(db, mode);
|
||||
},
|
||||
GET: withErrorHandler(
|
||||
async () => {
|
||||
const { handleListProviderOptions } = await import("./routes/providers/options");
|
||||
return handleListProviderOptions(db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
},
|
||||
"/api/providers/test": {
|
||||
POST: async (req) => {
|
||||
const { handleTestProviderConfig } = await import("./routes/providers/test");
|
||||
return handleTestProviderConfig(req, db, mode);
|
||||
},
|
||||
POST: withErrorHandler(
|
||||
async (req) => {
|
||||
const { handleTestProviderConfig } = await import("./routes/providers/test");
|
||||
return handleTestProviderConfig(req, db, mode);
|
||||
},
|
||||
mode,
|
||||
logger,
|
||||
),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user