- 導入 Prisma 7.9.1 + SQLite(better-sqlite3 driver adapter),prisma.config.ts 管理連線設定 - 完整資料模型:User/Work/Character/CharacterAlias/EpisodicMemory/SemanticMemory/ ProceduralRule/EmotionState/Relationship/SentimentLedgerEntry - packages/db:Prisma Client 存取層(ESM,因 Prisma 7 產出的 generated client 僅支援 ESM) - apps/api 隨之改為 ESM 以相容 packages/db - packages/shared:新增角色/記憶/情緒/關係共用型別,api 與 web 皆從此匯入 - prisma/seed.ts:建立測試使用者與元氣型測試角色,含完整關係帳本與記憶種子資料 - apps/api:新增 GET /characters - scripts/smoke/B.mjs:驗證資料表齊全、API 讀出種子角色、關係與記憶可寫入讀出 - 保留 Prisma 官方隨 CLI 附的 agent skill 文件(.agents/skills 等),供後續群組查閱 npm run restart && npm run smoke -- B 皆通過(B-V),A 群組冒煙測試無回歸。
66 lines
1.9 KiB
JavaScript
66 lines
1.9 KiB
JavaScript
#!/usr/bin/env node
|
||
import "dotenv/config";
|
||
import path from "node:path";
|
||
import { readdir } from "node:fs/promises";
|
||
import { existsSync } from "node:fs";
|
||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||
import { log } from "../../packages/shared/dist/index.js";
|
||
|
||
const SMOKE_DIR = path.dirname(fileURLToPath(import.meta.url));
|
||
|
||
async function listGroupFiles() {
|
||
const files = await readdir(SMOKE_DIR);
|
||
return files.filter((f) => f.endsWith(".mjs") && f !== "run.mjs").sort();
|
||
}
|
||
|
||
async function runOne(file) {
|
||
const group = file.replace(/\.mjs$/, "");
|
||
const modUrl = pathToFileURL(path.join(SMOKE_DIR, file)).href;
|
||
log("冒煙測試", "INF", `開始執行 ${group} 群組冒煙測試`);
|
||
try {
|
||
const mod = await import(modUrl);
|
||
if (typeof mod.default !== "function") {
|
||
throw new Error(`${file} 未匯出預設測試函式`);
|
||
}
|
||
await mod.default();
|
||
log("冒煙測試", "INF", `${group} 群組冒煙測試全綠`);
|
||
return true;
|
||
} catch (err) {
|
||
log("冒煙測試", "ERR", `${group} 群組冒煙測試失敗:${err.message}`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
async function main() {
|
||
const arg = process.argv[2];
|
||
if (!arg) {
|
||
log("冒煙測試", "ERR", "請指定群組代號,例如:npm run smoke -- A(或 all 執行全部群組)");
|
||
process.exit(1);
|
||
}
|
||
|
||
let files;
|
||
if (arg === "all") {
|
||
files = await listGroupFiles();
|
||
if (files.length === 0) {
|
||
log("冒煙測試", "WRN", "尚無任何冒煙測試檔案");
|
||
}
|
||
} else {
|
||
const file = `${arg}.mjs`;
|
||
if (!existsSync(path.join(SMOKE_DIR, file))) {
|
||
log("冒煙測試", "ERR", `找不到群組 ${arg} 的冒煙測試檔案(scripts/smoke/${file})`);
|
||
process.exit(1);
|
||
}
|
||
files = [file];
|
||
}
|
||
|
||
let allOk = true;
|
||
for (const file of files) {
|
||
const ok = await runOne(file);
|
||
allOk = allOk && ok;
|
||
}
|
||
|
||
process.exit(allOk ? 0 : 1);
|
||
}
|
||
|
||
main();
|