引入 SQLite 数据库(Drizzle ORM + bun:sqlite),实现项目 CRUD 与归档/恢复/删除 生命周期管理,新增项目管理前端页面,migration 嵌入单文件构建产物保持部署体验。 - src/server/db: schema、connection、migration 执行器、项目数据访问层 - src/server/routes/projects: 7 个 API 端点(列表/创建/详情/更新/归档/恢复/删除) - src/web: 项目管理页面(TDesign Table/Tabs/Dialog/Form),TanStack Query hooks - scripts: 构建时嵌入 migration SQL,开发期独立 generate-migrations-data 脚本 - tests: 60 个后端测试 + 27 个前端测试,覆盖 DB/migration/API/路由/页面 - docs: 更新架构、后端、发布、配置、部署、使用文档
61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-empty-function, @typescript-eslint/require-await */
|
|
import { describe, expect, test } from "bun:test";
|
|
import { mkdirSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
|
|
import type { ResolvedConfig } from "../../src/server/config/types";
|
|
|
|
import { bootstrap, type BootstrapDependencies } from "../../src/server/bootstrap";
|
|
import { createMemoryLogger } from "../../src/server/logger";
|
|
|
|
function makeTempConfig(overrides: Partial<ResolvedConfig> = {}): ResolvedConfig {
|
|
const base = join(tmpdir(), `bootstrap-db-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
mkdirSync(base, { recursive: true });
|
|
return {
|
|
configDir: base,
|
|
dataDir: join(base, "data"),
|
|
host: "127.0.0.1",
|
|
logging: {
|
|
consoleLevel: "info",
|
|
fileLevel: "info",
|
|
filePath: join(base, "data", "logs", "test.log"),
|
|
rotationFrequency: "daily",
|
|
rotationMaxFiles: 14,
|
|
rotationSizeBytes: 52428800,
|
|
rotationSizeRaw: "50MB",
|
|
},
|
|
port: 0,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
describe("bootstrap 数据库集成", () => {
|
|
test("启动时将数据库传递给 startServer", async () => {
|
|
let started = false;
|
|
let receivedDb: unknown = undefined;
|
|
|
|
const cfg = makeTempConfig();
|
|
const mockLoadConfig = (async () => cfg) as unknown as BootstrapDependencies["loadConfig"];
|
|
const mockOnSignal = (_signal: string, _handler: () => void) => {};
|
|
const mockStartServer = (options: { db: unknown }) => {
|
|
receivedDb = options.db;
|
|
started = true;
|
|
return { close: () => {} };
|
|
};
|
|
|
|
const deps: BootstrapDependencies = {
|
|
createLogger: async () => createMemoryLogger(),
|
|
loadConfig: mockLoadConfig,
|
|
onSignal: mockOnSignal,
|
|
startServer: mockStartServer,
|
|
};
|
|
|
|
await bootstrap({ configPath: join(cfg.configDir, "config.yaml"), mode: "production" }, deps);
|
|
|
|
expect(started).toBe(true);
|
|
expect(receivedDb).not.toBeUndefined();
|
|
expect(typeof (receivedDb as { close?: unknown }).close).toBe("function");
|
|
});
|
|
});
|