Files
Jeffery f44200f543 feat: 完成 B 群組 — 資料層與核心領域模型
- 導入 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 群組冒煙測試無回歸。
2026-08-13 09:43:15 +08:00

66 lines
1.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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();