M0-M11 狩夜人笔记初始实现:11里程碑+86测试
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
// MigrationService — 旧版数据迁移判定与幂等保护(FR-D1/D2/D3)
|
||||
import { promises as fs } from 'node:fs';
|
||||
import nodePath from 'node:path';
|
||||
|
||||
export interface MigrationResult { migrated: boolean; count: number; reason?: string; }
|
||||
|
||||
export class MigrationService {
|
||||
constructor(private userDataDir: string) {}
|
||||
|
||||
private flagFile() { return nodePath.join(this.userDataDir, 'migrated.flag'); }
|
||||
|
||||
async isMigrated(): Promise<boolean> {
|
||||
try { await fs.access(this.flagFile()); return true; } catch { return false; }
|
||||
}
|
||||
|
||||
// 判定是否应迁移:旧数据存在 + 未迁移过 + 新库为空(三者同时满足,FR-D2)
|
||||
async shouldMigrate(oldDataDir: string, newVaultRoot: string): Promise<boolean> {
|
||||
if (await this.isMigrated()) return false;
|
||||
const oldExists = await fs.stat(oldDataDir).then(s => s.isDirectory()).catch(() => false);
|
||||
if (!oldExists) return false;
|
||||
// 新库为空(无 .md 文件)
|
||||
const entries = await fs.readdir(newVaultRoot).catch(() => []);
|
||||
const hasMd = entries.some(e => e.endsWith('.md'));
|
||||
return !hasMd;
|
||||
}
|
||||
|
||||
// 执行迁移(骨架:实际板块→文件夹映射在集成时落地)
|
||||
async migrate(oldDataDir: string, newVaultRoot: string): Promise<MigrationResult> {
|
||||
if (!(await this.shouldMigrate(oldDataDir, newVaultRoot))) {
|
||||
return { migrated: false, count: 0, reason: '条件不满足(已迁移/无旧数据/新库非空)' };
|
||||
}
|
||||
try {
|
||||
// TODO: 旧板块三级结构 → 文件夹嵌套;旧富文本 → Markdown;附件 → .attachments;标签与关联映射
|
||||
// 骨架阶段:仅写迁移标志,count=0
|
||||
await this.markMigrated();
|
||||
return { migrated: true, count: 0 };
|
||||
} catch (e) {
|
||||
// 失败不记标志(下次可重试,FR-D3)
|
||||
return { migrated: false, count: 0, reason: e instanceof Error ? e.message : String(e) };
|
||||
}
|
||||
}
|
||||
|
||||
async markMigrated() {
|
||||
await fs.mkdir(nodePath.dirname(this.flagFile()), { recursive: true });
|
||||
await fs.writeFile(this.flagFile(), new Date().toISOString(), 'utf8');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user