memento-mcp-server 1.16.2 → 1.16.3-b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/domains/anchor/services/anchor/n-hop-search-service.d.ts.map +1 -1
- package/dist/domains/anchor/services/anchor/n-hop-search-service.js +4 -5
- package/dist/domains/anchor/services/anchor/n-hop-search-service.js.map +1 -1
- package/dist/domains/embedding/services/embedding-service.d.ts.map +1 -1
- package/dist/domains/embedding/services/embedding-service.js +5 -2
- package/dist/domains/embedding/services/embedding-service.js.map +1 -1
- package/dist/domains/embedding/services/gemini-embedding-service.d.ts.map +1 -1
- package/dist/domains/embedding/services/gemini-embedding-service.js +6 -3
- package/dist/domains/embedding/services/gemini-embedding-service.js.map +1 -1
- package/dist/domains/embedding/services/lightweight-embedding-service.d.ts.map +1 -1
- package/dist/domains/embedding/services/lightweight-embedding-service.js +4 -2
- package/dist/domains/embedding/services/lightweight-embedding-service.js.map +1 -1
- package/dist/domains/embedding/services/minilm-embedding-service.d.ts.map +1 -1
- package/dist/domains/embedding/services/minilm-embedding-service.js +6 -3
- package/dist/domains/embedding/services/minilm-embedding-service.js.map +1 -1
- package/dist/domains/embedding/services/openai-embedding-service.d.ts.map +1 -1
- package/dist/domains/embedding/services/openai-embedding-service.js +5 -2
- package/dist/domains/embedding/services/openai-embedding-service.js.map +1 -1
- package/dist/domains/embedding/services/unified-embedding-service.d.ts.map +1 -1
- package/dist/domains/embedding/services/unified-embedding-service.js +6 -3
- package/dist/domains/embedding/services/unified-embedding-service.js.map +1 -1
- package/dist/domains/forgetting/services/forgetting-policy-service.d.ts.map +1 -1
- package/dist/domains/forgetting/services/forgetting-policy-service.js +3 -1
- package/dist/domains/forgetting/services/forgetting-policy-service.js.map +1 -1
- package/dist/domains/memory/services/memory-embedding-service.d.ts +1 -0
- package/dist/domains/memory/services/memory-embedding-service.d.ts.map +1 -1
- package/dist/domains/memory/services/memory-embedding-service.js +43 -39
- package/dist/domains/memory/services/memory-embedding-service.js.map +1 -1
- package/dist/domains/memory/services/memory-neighbor-service.d.ts.map +1 -1
- package/dist/domains/memory/services/memory-neighbor-service.js +13 -4
- package/dist/domains/memory/services/memory-neighbor-service.js.map +1 -1
- package/dist/domains/memory/tools/convert-episodic-to-semantic-tool.js +5 -6
- package/dist/domains/memory/tools/convert-episodic-to-semantic-tool.js.map +1 -1
- package/dist/domains/memory/tools/forget-tool.d.ts.map +1 -1
- package/dist/domains/memory/tools/forget-tool.js +5 -2
- package/dist/domains/memory/tools/forget-tool.js.map +1 -1
- package/dist/domains/memory/tools/memory-injection-prompt.d.ts.map +1 -1
- package/dist/domains/memory/tools/memory-injection-prompt.js +3 -1
- package/dist/domains/memory/tools/memory-injection-prompt.js.map +1 -1
- package/dist/domains/memory/tools/pin-tool.d.ts.map +1 -1
- package/dist/domains/memory/tools/pin-tool.js +5 -2
- package/dist/domains/memory/tools/pin-tool.js.map +1 -1
- package/dist/domains/memory/tools/unpin-tool.d.ts.map +1 -1
- package/dist/domains/memory/tools/unpin-tool.js +5 -2
- package/dist/domains/memory/tools/unpin-tool.js.map +1 -1
- package/dist/domains/monitoring/services/error-logging-service.d.ts +5 -0
- package/dist/domains/monitoring/services/error-logging-service.d.ts.map +1 -1
- package/dist/domains/monitoring/services/error-logging-service.js +28 -10
- package/dist/domains/monitoring/services/error-logging-service.js.map +1 -1
- package/dist/domains/monitoring/services/performance-alert-service.d.ts.map +1 -1
- package/dist/domains/monitoring/services/performance-alert-service.js +5 -2
- package/dist/domains/monitoring/services/performance-alert-service.js.map +1 -1
- package/dist/domains/relation/services/relation-graph.d.ts.map +1 -1
- package/dist/domains/relation/services/relation-graph.js +3 -4
- package/dist/domains/relation/services/relation-graph.js.map +1 -1
- package/dist/domains/search/algorithms/hybrid-search-engine.d.ts.map +1 -1
- package/dist/domains/search/algorithms/hybrid-search-engine.js +15 -10
- package/dist/domains/search/algorithms/hybrid-search-engine.js.map +1 -1
- package/dist/domains/search/algorithms/search-engine.d.ts.map +1 -1
- package/dist/domains/search/algorithms/search-engine.js +8 -4
- package/dist/domains/search/algorithms/search-engine.js.map +1 -1
- package/dist/domains/search/algorithms/vector-search-engine-migration.d.ts +13 -8
- package/dist/domains/search/algorithms/vector-search-engine-migration.d.ts.map +1 -1
- package/dist/domains/search/algorithms/vector-search-engine-migration.js +28 -45
- package/dist/domains/search/algorithms/vector-search-engine-migration.js.map +1 -1
- package/dist/domains/search/algorithms/vector-search-engine.d.ts +17 -35
- package/dist/domains/search/algorithms/vector-search-engine.d.ts.map +1 -1
- package/dist/domains/search/algorithms/vector-search-engine.js +94 -478
- package/dist/domains/search/algorithms/vector-search-engine.js.map +1 -1
- package/dist/domains/search/repositories/vector-performance.repository.d.ts.map +1 -1
- package/dist/domains/search/repositories/vector-performance.repository.js +3 -1
- package/dist/domains/search/repositories/vector-performance.repository.js.map +1 -1
- package/dist/domains/search/repositories/vector-search.repository.d.ts +1 -0
- package/dist/domains/search/repositories/vector-search.repository.d.ts.map +1 -1
- package/dist/domains/search/repositories/vector-search.repository.js +178 -157
- package/dist/domains/search/repositories/vector-search.repository.js.map +1 -1
- package/dist/domains/search/services/vector-search/vector-index-manager.d.ts.map +1 -1
- package/dist/domains/search/services/vector-search/vector-index-manager.js +7 -3
- package/dist/domains/search/services/vector-search/vector-index-manager.js.map +1 -1
- package/dist/domains/search/services/vector-search/vector-performance-tester.d.ts.map +1 -1
- package/dist/domains/search/services/vector-search/vector-performance-tester.js +3 -1
- package/dist/domains/search/services/vector-search/vector-performance-tester.js.map +1 -1
- package/dist/infrastructure/database/database/init.d.ts.map +1 -1
- package/dist/infrastructure/database/database/init.js +29 -7
- package/dist/infrastructure/database/database/init.js.map +1 -1
- package/dist/infrastructure/database/database/migrate.d.ts.map +1 -1
- package/dist/infrastructure/database/database/migrate.js +5 -2
- package/dist/infrastructure/database/database/migrate.js.map +1 -1
- package/dist/infrastructure/database/database/migration/backup-manager.d.ts.map +1 -1
- package/dist/infrastructure/database/database/migration/backup-manager.js +11 -5
- package/dist/infrastructure/database/database/migration/backup-manager.js.map +1 -1
- package/dist/infrastructure/database/database/migration/migration-detector.d.ts.map +1 -1
- package/dist/infrastructure/database/database/migration/migration-detector.js +3 -1
- package/dist/infrastructure/database/database/migration/migration-detector.js.map +1 -1
- package/dist/infrastructure/database/database/migration/migration-logger.d.ts.map +1 -1
- package/dist/infrastructure/database/database/migration/migration-logger.js +5 -2
- package/dist/infrastructure/database/database/migration/migration-logger.js.map +1 -1
- package/dist/infrastructure/database/database/migration/migration-runner.d.ts.map +1 -1
- package/dist/infrastructure/database/database/migration/migration-runner.js +24 -13
- package/dist/infrastructure/database/database/migration/migration-runner.js.map +1 -1
- package/dist/infrastructure/database/database/migration/schema-version-manager.d.ts.map +1 -1
- package/dist/infrastructure/database/database/migration/schema-version-manager.js +7 -3
- package/dist/infrastructure/database/database/migration/schema-version-manager.js.map +1 -1
- package/dist/infrastructure/database/database-optimizer.d.ts.map +1 -1
- package/dist/infrastructure/database/database-optimizer.js +7 -6
- package/dist/infrastructure/database/database-optimizer.js.map +1 -1
- package/dist/infrastructure/database/migration-history-service.d.ts.map +1 -1
- package/dist/infrastructure/database/migration-history-service.js +3 -1
- package/dist/infrastructure/database/migration-history-service.js.map +1 -1
- package/dist/infrastructure/logging/triple-extraction-logger.d.ts +6 -0
- package/dist/infrastructure/logging/triple-extraction-logger.d.ts.map +1 -1
- package/dist/infrastructure/logging/triple-extraction-logger.js +50 -12
- package/dist/infrastructure/logging/triple-extraction-logger.js.map +1 -1
- package/dist/infrastructure/scheduler/batch-scheduler.d.ts.map +1 -1
- package/dist/infrastructure/scheduler/batch-scheduler.js +5 -2
- package/dist/infrastructure/scheduler/batch-scheduler.js.map +1 -1
- package/dist/infrastructure/scheduler/file-logger.d.ts +4 -1
- package/dist/infrastructure/scheduler/file-logger.d.ts.map +1 -1
- package/dist/infrastructure/scheduler/file-logger.js +46 -16
- package/dist/infrastructure/scheduler/file-logger.js.map +1 -1
- package/dist/scripts/check-migration-status.d.ts.map +1 -1
- package/dist/scripts/check-migration-status.js +19 -6
- package/dist/scripts/check-migration-status.js.map +1 -1
- package/dist/server/http-server.d.ts.map +1 -1
- package/dist/server/http-server.js +2 -7
- package/dist/server/http-server.js.map +1 -1
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +33 -7
- package/dist/server/index.js.map +1 -1
- package/dist/server/server-factory.d.ts +65 -0
- package/dist/server/server-factory.d.ts.map +1 -0
- package/dist/server/server-factory.js +40 -0
- package/dist/server/server-factory.js.map +1 -0
- package/dist/server/servers/sse-server.d.ts +33 -0
- package/dist/server/servers/sse-server.d.ts.map +1 -0
- package/dist/server/servers/sse-server.js +48 -0
- package/dist/server/servers/sse-server.js.map +1 -0
- package/dist/server/servers/stdio-server.d.ts +34 -0
- package/dist/server/servers/stdio-server.d.ts.map +1 -0
- package/dist/server/servers/stdio-server.js +58 -0
- package/dist/server/servers/stdio-server.js.map +1 -0
- package/dist/server/simple-mcp-server.d.ts +5 -0
- package/dist/server/simple-mcp-server.d.ts.map +1 -1
- package/dist/server/simple-mcp-server.js +17 -7
- package/dist/server/simple-mcp-server.js.map +1 -1
- package/dist/server/sse-server-impl.d.ts +22 -0
- package/dist/server/sse-server-impl.d.ts.map +1 -0
- package/dist/server/sse-server-impl.js +39 -0
- package/dist/server/sse-server-impl.js.map +1 -0
- package/dist/server/stdio-server-impl.d.ts +12 -0
- package/dist/server/stdio-server-impl.d.ts.map +1 -0
- package/dist/server/stdio-server-impl.js +19 -0
- package/dist/server/stdio-server-impl.js.map +1 -0
- package/dist/services/quality-assurance/quality-recorder.js +2 -2
- package/dist/services/quality-assurance/quality-recorder.js.map +1 -1
- package/dist/services/quality-assurance/quality-threshold-manager.js +1 -1
- package/dist/services/quality-assurance/quality-threshold-manager.js.map +1 -1
- package/dist/shared/config/environment.d.ts.map +1 -1
- package/dist/shared/config/environment.js +3 -1
- package/dist/shared/config/environment.js.map +1 -1
- package/dist/shared/types/vector-search.types.d.ts +1 -0
- package/dist/shared/types/vector-search.types.d.ts.map +1 -1
- package/dist/shared/utils/fts5-migration-status.d.ts.map +1 -1
- package/dist/shared/utils/fts5-migration-status.js +6 -2
- package/dist/shared/utils/fts5-migration-status.js.map +1 -1
- package/dist/shared/utils/logger.d.ts.map +1 -1
- package/dist/shared/utils/logger.js +15 -2
- package/dist/shared/utils/logger.js.map +1 -1
- package/dist/shared/utils/path-validator.d.ts +27 -0
- package/dist/shared/utils/path-validator.d.ts.map +1 -0
- package/dist/shared/utils/path-validator.js +166 -0
- package/dist/shared/utils/path-validator.js.map +1 -0
- package/dist/shared/utils/pii-masker.d.ts +31 -0
- package/dist/shared/utils/pii-masker.d.ts.map +1 -1
- package/dist/shared/utils/pii-masker.js +99 -0
- package/dist/shared/utils/pii-masker.js.map +1 -1
- package/dist/shared/utils/procedural-memory-extractor.d.ts.map +1 -1
- package/dist/shared/utils/procedural-memory-extractor.js +39 -33
- package/dist/shared/utils/procedural-memory-extractor.js.map +1 -1
- package/dist/shared/utils/prompt-template-loader.d.ts +6 -0
- package/dist/shared/utils/prompt-template-loader.d.ts.map +1 -1
- package/dist/shared/utils/prompt-template-loader.js +20 -8
- package/dist/shared/utils/prompt-template-loader.js.map +1 -1
- package/dist/shared/utils/reflection-notes-merge.d.ts.map +1 -1
- package/dist/shared/utils/reflection-notes-merge.js +5 -4
- package/dist/shared/utils/reflection-notes-merge.js.map +1 -1
- package/dist/shared/utils/sql-security-validator.d.ts +25 -0
- package/dist/shared/utils/sql-security-validator.d.ts.map +1 -0
- package/dist/shared/utils/sql-security-validator.js +67 -0
- package/dist/shared/utils/sql-security-validator.js.map +1 -0
- package/dist/shared/utils/write-coalescing.d.ts.map +1 -1
- package/dist/shared/utils/write-coalescing.js +7 -3
- package/dist/shared/utils/write-coalescing.js.map +1 -1
- package/package.json +2 -1
- package/scripts/__tests__/check-db-integrity.integration.spec.ts +163 -0
- package/scripts/__tests__/fix-migration.integration.spec.ts +203 -0
- package/scripts/__tests__/migrate-embedding-data.integration.spec.ts +219 -0
- package/scripts/__tests__/regenerate-embeddings.integration.spec.ts +192 -0
- package/scripts/backup-daily.bat +10 -2
- package/scripts/backup-embeddings.js +67 -56
- package/scripts/check-db-integrity.js +49 -25
- package/scripts/check-file-sizes.ts +4 -4
- package/scripts/check-path-traversal.ts +370 -0
- package/scripts/check-pii-masking.ts +357 -0
- package/scripts/check-sql-injection.ts +598 -0
- package/scripts/debug-embeddings.js +74 -93
- package/scripts/fix-migration.js +115 -80
- package/scripts/fix-vector-dimensions.js +70 -89
- package/scripts/migrate-embedding-data.js +111 -25
- package/scripts/regenerate-embeddings.js +31 -15
- package/scripts/run-migration.js +144 -107
- package/scripts/safe-migration.js +192 -142
- package/scripts/save-work-memory.ts +6 -7
- package/scripts/simple-migrate.js +66 -34
- package/scripts/simple-update.js +147 -109
- package/dist/domains/search/algorithms/vector-search-engine-refactored.d.ts +0 -56
- package/dist/domains/search/algorithms/vector-search-engine-refactored.d.ts.map +0 -1
- package/dist/domains/search/algorithms/vector-search-engine-refactored.js +0 -101
- package/dist/domains/search/algorithms/vector-search-engine-refactored.js.map +0 -1
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* migrate-embedding-data.js 통합 테스트
|
|
3
|
+
*
|
|
4
|
+
* Given/When/Then 구조를 따르는 통합 테스트
|
|
5
|
+
* 공통 모듈(initializeDatabase)을 사용하는 버전으로 리팩토링 후 검증
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
9
|
+
import { existsSync, unlinkSync, mkdirSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
import { tmpdir } from 'os';
|
|
12
|
+
import { initializeDatabase, closeDatabase } from '../../src/infrastructure/database/database/init.js';
|
|
13
|
+
import Database from 'better-sqlite3';
|
|
14
|
+
|
|
15
|
+
describe('migrate-embedding-data 통합 테스트', () => {
|
|
16
|
+
let testDbPath: string;
|
|
17
|
+
let testBackupPath: string;
|
|
18
|
+
let originalDbPath: string | undefined;
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
// 테스트용 임시 디렉토리 생성
|
|
22
|
+
const testDir = join(tmpdir(), `memento-test-${Date.now()}`);
|
|
23
|
+
mkdirSync(testDir, { recursive: true });
|
|
24
|
+
|
|
25
|
+
testDbPath = join(testDir, 'memory.db');
|
|
26
|
+
testBackupPath = join(testDir, `memory-backup-${Date.now()}.db`);
|
|
27
|
+
|
|
28
|
+
// 환경 변수 백업 및 설정
|
|
29
|
+
originalDbPath = process.env.DB_PATH;
|
|
30
|
+
process.env.DB_PATH = testDbPath;
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
// 환경 변수 복원
|
|
35
|
+
if (originalDbPath !== undefined) {
|
|
36
|
+
process.env.DB_PATH = originalDbPath;
|
|
37
|
+
} else {
|
|
38
|
+
delete process.env.DB_PATH;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 테스트 파일 정리
|
|
42
|
+
try {
|
|
43
|
+
if (existsSync(testDbPath)) {
|
|
44
|
+
unlinkSync(testDbPath);
|
|
45
|
+
}
|
|
46
|
+
if (existsSync(testBackupPath)) {
|
|
47
|
+
unlinkSync(testBackupPath);
|
|
48
|
+
}
|
|
49
|
+
} catch (error) {
|
|
50
|
+
// 파일 정리 실패는 무시
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @given 공통 모듈(initializeDatabase)을 사용하는 migrate-embedding-data 함수
|
|
56
|
+
* @when 데이터베이스 연결 및 백업 생성
|
|
57
|
+
* @then 백업 파일이 정상적으로 생성됨
|
|
58
|
+
*/
|
|
59
|
+
it('should create backup successfully', async () => {
|
|
60
|
+
// Given: 정상적인 데이터베이스 초기화
|
|
61
|
+
const db = await initializeDatabase();
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
// 테스트 데이터 삽입
|
|
65
|
+
db.exec(`
|
|
66
|
+
INSERT INTO memory_embedding (id, embedding, dim, model)
|
|
67
|
+
VALUES (1, '[]', 384, 'lightweight-hybrid')
|
|
68
|
+
`);
|
|
69
|
+
|
|
70
|
+
// When: 백업 생성
|
|
71
|
+
const backupDb = new Database(testBackupPath);
|
|
72
|
+
db.backup(testBackupPath);
|
|
73
|
+
backupDb.close();
|
|
74
|
+
|
|
75
|
+
// Then: 백업 파일이 생성되었는지 확인
|
|
76
|
+
expect(existsSync(testBackupPath)).toBe(true);
|
|
77
|
+
} finally {
|
|
78
|
+
closeDatabase(db);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @given 공통 모듈(initializeDatabase)을 사용하는 migrate-embedding-data 함수
|
|
84
|
+
* @when 기존 데이터 분석 실행
|
|
85
|
+
* @then 분석 결과가 정상적으로 반환됨
|
|
86
|
+
*/
|
|
87
|
+
it('should analyze existing data correctly', async () => {
|
|
88
|
+
// Given: 정상적인 데이터베이스 초기화 및 테스트 데이터
|
|
89
|
+
const db = await initializeDatabase();
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
// memory_embedding 테이블이 있는지 확인
|
|
93
|
+
const tableExists = db.prepare(`
|
|
94
|
+
SELECT name FROM sqlite_master
|
|
95
|
+
WHERE type='table' AND name='memory_embedding'
|
|
96
|
+
`).get();
|
|
97
|
+
|
|
98
|
+
if (tableExists) {
|
|
99
|
+
// When: 데이터 분석
|
|
100
|
+
const dimensionStats = db.prepare(`
|
|
101
|
+
SELECT dim, COUNT(*) as count,
|
|
102
|
+
COUNT(CASE WHEN model IS NOT NULL AND model != '' THEN 1 END) as with_model
|
|
103
|
+
FROM memory_embedding
|
|
104
|
+
GROUP BY dim
|
|
105
|
+
`).all();
|
|
106
|
+
|
|
107
|
+
const totalStats = db.prepare(`
|
|
108
|
+
SELECT COUNT(*) as total,
|
|
109
|
+
COUNT(CASE WHEN embedding_provider IS NOT NULL THEN 1 END) as migrated
|
|
110
|
+
FROM memory_embedding
|
|
111
|
+
`).get();
|
|
112
|
+
|
|
113
|
+
// Then: 분석 결과가 정상적으로 반환됨
|
|
114
|
+
expect(dimensionStats).toBeDefined();
|
|
115
|
+
expect(totalStats).toBeDefined();
|
|
116
|
+
expect(totalStats.total).toBeGreaterThanOrEqual(0);
|
|
117
|
+
} else {
|
|
118
|
+
// 테이블이 없으면 스킵
|
|
119
|
+
console.log('⚠️ memory_embedding 테이블이 없습니다. 테스트 스킵');
|
|
120
|
+
}
|
|
121
|
+
} finally {
|
|
122
|
+
closeDatabase(db);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @given 공통 모듈(initializeDatabase)을 사용하는 migrate-embedding-data 함수
|
|
128
|
+
* @when 메타데이터 업데이트 실행
|
|
129
|
+
* @then 메타데이터가 정상적으로 업데이트됨
|
|
130
|
+
*/
|
|
131
|
+
it('should update metadata successfully', async () => {
|
|
132
|
+
// Given: 정상적인 데이터베이스 초기화 및 테스트 데이터
|
|
133
|
+
const db = await initializeDatabase();
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
// memory_embedding 테이블 확인
|
|
137
|
+
const tableExists = db.prepare(`
|
|
138
|
+
SELECT name FROM sqlite_master
|
|
139
|
+
WHERE type='table' AND name='memory_embedding'
|
|
140
|
+
`).get();
|
|
141
|
+
|
|
142
|
+
if (tableExists) {
|
|
143
|
+
// 컬럼 존재 확인
|
|
144
|
+
const schema = db.prepare("PRAGMA table_info(memory_embedding)").all() as Array<{ name: string }>;
|
|
145
|
+
const hasProvider = schema.some(col => col.name === 'embedding_provider');
|
|
146
|
+
const hasDimensions = schema.some(col => col.name === 'dimensions');
|
|
147
|
+
const hasCreatedBy = schema.some(col => col.name === 'created_by');
|
|
148
|
+
|
|
149
|
+
if (hasProvider && hasDimensions && hasCreatedBy) {
|
|
150
|
+
// When: 메타데이터 업데이트
|
|
151
|
+
const updateStmt = db.prepare(`
|
|
152
|
+
UPDATE memory_embedding
|
|
153
|
+
SET
|
|
154
|
+
embedding_provider = CASE
|
|
155
|
+
WHEN model = 'lightweight-hybrid' THEN 'tfidf'
|
|
156
|
+
WHEN model IS NULL OR model = '' THEN 'tfidf'
|
|
157
|
+
ELSE 'unknown'
|
|
158
|
+
END,
|
|
159
|
+
dimensions = dim,
|
|
160
|
+
created_by = 'legacy'
|
|
161
|
+
WHERE embedding_provider IS NULL
|
|
162
|
+
`);
|
|
163
|
+
|
|
164
|
+
const result = updateStmt.run();
|
|
165
|
+
|
|
166
|
+
// Then: 업데이트 성공 확인
|
|
167
|
+
expect(result.changes).toBeGreaterThanOrEqual(0);
|
|
168
|
+
} else {
|
|
169
|
+
console.log('⚠️ 필요한 컬럼이 없습니다. 테스트 스킵');
|
|
170
|
+
}
|
|
171
|
+
} else {
|
|
172
|
+
console.log('⚠️ memory_embedding 테이블이 없습니다. 테스트 스킵');
|
|
173
|
+
}
|
|
174
|
+
} finally {
|
|
175
|
+
closeDatabase(db);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* @given 공통 모듈(initializeDatabase)을 사용하는 migrate-embedding-data 함수
|
|
181
|
+
* @when 마이그레이션 검증 실행
|
|
182
|
+
* @then 검증 결과가 정상적으로 반환됨
|
|
183
|
+
*/
|
|
184
|
+
it('should validate migration successfully', async () => {
|
|
185
|
+
// Given: 정상적인 데이터베이스 초기화
|
|
186
|
+
const db = await initializeDatabase();
|
|
187
|
+
|
|
188
|
+
try {
|
|
189
|
+
// memory_embedding 테이블 확인
|
|
190
|
+
const tableExists = db.prepare(`
|
|
191
|
+
SELECT name FROM sqlite_master
|
|
192
|
+
WHERE type='table' AND name='memory_embedding'
|
|
193
|
+
`).get();
|
|
194
|
+
|
|
195
|
+
if (tableExists) {
|
|
196
|
+
// When: 마이그레이션 검증
|
|
197
|
+
const validation = db.prepare(`
|
|
198
|
+
SELECT
|
|
199
|
+
COUNT(*) as total,
|
|
200
|
+
COUNT(CASE WHEN embedding_provider IS NOT NULL THEN 1 END) as with_provider,
|
|
201
|
+
COUNT(CASE WHEN dimensions IS NOT NULL THEN 1 END) as with_dimensions,
|
|
202
|
+
COUNT(CASE WHEN created_by IS NOT NULL THEN 1 END) as with_created_by
|
|
203
|
+
FROM memory_embedding
|
|
204
|
+
`).get() as { total: number; with_provider: number; with_dimensions: number; with_created_by: number };
|
|
205
|
+
|
|
206
|
+
// Then: 검증 결과가 정상적으로 반환됨
|
|
207
|
+
expect(validation.total).toBeGreaterThanOrEqual(0);
|
|
208
|
+
expect(validation.with_provider).toBeGreaterThanOrEqual(0);
|
|
209
|
+
expect(validation.with_dimensions).toBeGreaterThanOrEqual(0);
|
|
210
|
+
expect(validation.with_created_by).toBeGreaterThanOrEqual(0);
|
|
211
|
+
} else {
|
|
212
|
+
console.log('⚠️ memory_embedding 테이블이 없습니다. 테스트 스킵');
|
|
213
|
+
}
|
|
214
|
+
} finally {
|
|
215
|
+
closeDatabase(db);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* regenerate-embeddings.js 통합 테스트
|
|
3
|
+
*
|
|
4
|
+
* Given/When/Then 구조를 따르는 통합 테스트
|
|
5
|
+
* 공통 모듈(initializeDatabase)을 사용하는 버전으로 리팩토링 후 검증
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
9
|
+
import { existsSync, unlinkSync, mkdirSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
import { tmpdir } from 'os';
|
|
12
|
+
import { initializeDatabase, closeDatabase } from '../../src/infrastructure/database/database/init.js';
|
|
13
|
+
import Database from 'better-sqlite3';
|
|
14
|
+
|
|
15
|
+
describe('regenerate-embeddings 통합 테스트', () => {
|
|
16
|
+
let testDbPath: string;
|
|
17
|
+
let originalDbPath: string | undefined;
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
// 테스트용 임시 디렉토리 생성
|
|
21
|
+
const testDir = join(tmpdir(), `memento-test-${Date.now()}`);
|
|
22
|
+
mkdirSync(testDir, { recursive: true });
|
|
23
|
+
|
|
24
|
+
testDbPath = join(testDir, 'memory.db');
|
|
25
|
+
|
|
26
|
+
// 환경 변수 백업 및 설정
|
|
27
|
+
originalDbPath = process.env.DB_PATH;
|
|
28
|
+
process.env.DB_PATH = testDbPath;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
// 환경 변수 복원
|
|
33
|
+
if (originalDbPath !== undefined) {
|
|
34
|
+
process.env.DB_PATH = originalDbPath;
|
|
35
|
+
} else {
|
|
36
|
+
delete process.env.DB_PATH;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 테스트 파일 정리
|
|
40
|
+
try {
|
|
41
|
+
if (existsSync(testDbPath)) {
|
|
42
|
+
unlinkSync(testDbPath);
|
|
43
|
+
}
|
|
44
|
+
} catch (error) {
|
|
45
|
+
// 파일 정리 실패는 무시
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @given 공통 모듈(initializeDatabase)을 사용하는 regenerate-embeddings 함수
|
|
51
|
+
* @when 데이터베이스 연결 및 기억 조회
|
|
52
|
+
* @then 기억 목록이 정상적으로 조회됨
|
|
53
|
+
*/
|
|
54
|
+
it('should query memories successfully', async () => {
|
|
55
|
+
// Given: 정상적인 데이터베이스 초기화
|
|
56
|
+
const db = await initializeDatabase();
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
// memory_item 테이블 확인
|
|
60
|
+
const tableExists = db.prepare(`
|
|
61
|
+
SELECT name FROM sqlite_master
|
|
62
|
+
WHERE type='table' AND name='memory_item'
|
|
63
|
+
`).get();
|
|
64
|
+
|
|
65
|
+
if (tableExists) {
|
|
66
|
+
// When: 기억 조회
|
|
67
|
+
const memories = db.prepare(`
|
|
68
|
+
SELECT id, content, type, importance, created_at
|
|
69
|
+
FROM memory_item
|
|
70
|
+
ORDER BY created_at
|
|
71
|
+
`).all();
|
|
72
|
+
|
|
73
|
+
// Then: 기억 목록이 정상적으로 조회됨
|
|
74
|
+
expect(memories).toBeDefined();
|
|
75
|
+
expect(Array.isArray(memories)).toBe(true);
|
|
76
|
+
} else {
|
|
77
|
+
console.log('⚠️ memory_item 테이블이 없습니다. 테스트 스킵');
|
|
78
|
+
}
|
|
79
|
+
} finally {
|
|
80
|
+
closeDatabase(db);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @given 공통 모듈(initializeDatabase)을 사용하는 regenerate-embeddings 함수
|
|
86
|
+
* @when 임베딩 통계 조회
|
|
87
|
+
* @then 통계가 정상적으로 반환됨
|
|
88
|
+
*/
|
|
89
|
+
it('should query embedding statistics successfully', async () => {
|
|
90
|
+
// Given: 정상적인 데이터베이스 초기화
|
|
91
|
+
const db = await initializeDatabase();
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
// memory_embedding 테이블 확인
|
|
95
|
+
const tableExists = db.prepare(`
|
|
96
|
+
SELECT name FROM sqlite_master
|
|
97
|
+
WHERE type='table' AND name='memory_embedding'
|
|
98
|
+
`).get();
|
|
99
|
+
|
|
100
|
+
if (tableExists) {
|
|
101
|
+
// When: 임베딩 통계 조회
|
|
102
|
+
const finalStats = db.prepare(`
|
|
103
|
+
SELECT
|
|
104
|
+
COUNT(*) as total,
|
|
105
|
+
AVG(dim) as avg_dim,
|
|
106
|
+
MIN(dim) as min_dim,
|
|
107
|
+
MAX(dim) as max_dim
|
|
108
|
+
FROM memory_embedding
|
|
109
|
+
`).get();
|
|
110
|
+
|
|
111
|
+
// Then: 통계가 정상적으로 반환됨
|
|
112
|
+
expect(finalStats).toBeDefined();
|
|
113
|
+
expect(finalStats.total).toBeGreaterThanOrEqual(0);
|
|
114
|
+
} else {
|
|
115
|
+
console.log('⚠️ memory_embedding 테이블이 없습니다. 테스트 스킵');
|
|
116
|
+
}
|
|
117
|
+
} finally {
|
|
118
|
+
closeDatabase(db);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @given 공통 모듈(initializeDatabase)을 사용하는 regenerate-embeddings 함수
|
|
124
|
+
* @when 차원 일치성 확인
|
|
125
|
+
* @then 차원 불일치가 정상적으로 감지됨
|
|
126
|
+
*/
|
|
127
|
+
it('should detect dimension mismatches correctly', async () => {
|
|
128
|
+
// Given: 정상적인 데이터베이스 초기화
|
|
129
|
+
const db = await initializeDatabase();
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
// memory_embedding 테이블 확인
|
|
133
|
+
const tableExists = db.prepare(`
|
|
134
|
+
SELECT name FROM sqlite_master
|
|
135
|
+
WHERE type='table' AND name='memory_embedding'
|
|
136
|
+
`).get();
|
|
137
|
+
|
|
138
|
+
if (tableExists) {
|
|
139
|
+
// When: 차원 일치성 확인
|
|
140
|
+
const expectedDim = 384; // 예상 차원
|
|
141
|
+
const mismatchedDims = db.prepare(`
|
|
142
|
+
SELECT COUNT(*) as count FROM memory_embedding WHERE dim != ?
|
|
143
|
+
`).get(expectedDim) as { count: number };
|
|
144
|
+
|
|
145
|
+
// Then: 차원 불일치가 정상적으로 감지됨
|
|
146
|
+
expect(mismatchedDims).toBeDefined();
|
|
147
|
+
expect(mismatchedDims.count).toBeGreaterThanOrEqual(0);
|
|
148
|
+
} else {
|
|
149
|
+
console.log('⚠️ memory_embedding 테이블이 없습니다. 테스트 스킵');
|
|
150
|
+
}
|
|
151
|
+
} finally {
|
|
152
|
+
closeDatabase(db);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @given 공통 모듈(initializeDatabase)을 사용하는 regenerate-embeddings 함수
|
|
158
|
+
* @when 빈 기억 목록 처리
|
|
159
|
+
* @then 적절한 메시지 출력 및 종료
|
|
160
|
+
*/
|
|
161
|
+
it('should handle empty memory list gracefully', async () => {
|
|
162
|
+
// Given: 정상적인 데이터베이스 초기화
|
|
163
|
+
const db = await initializeDatabase();
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
// memory_item 테이블 확인
|
|
167
|
+
const tableExists = db.prepare(`
|
|
168
|
+
SELECT name FROM sqlite_master
|
|
169
|
+
WHERE type='table' AND name='memory_item'
|
|
170
|
+
`).get();
|
|
171
|
+
|
|
172
|
+
if (tableExists) {
|
|
173
|
+
// When: 기억 조회
|
|
174
|
+
const memories = db.prepare(`
|
|
175
|
+
SELECT id, content, type, importance, created_at
|
|
176
|
+
FROM memory_item
|
|
177
|
+
ORDER BY created_at
|
|
178
|
+
`).all();
|
|
179
|
+
|
|
180
|
+
// Then: 빈 목록도 정상적으로 처리됨
|
|
181
|
+
expect(memories).toBeDefined();
|
|
182
|
+
expect(Array.isArray(memories)).toBe(true);
|
|
183
|
+
// 빈 목록인 경우에도 에러 없이 처리되어야 함
|
|
184
|
+
} else {
|
|
185
|
+
console.log('⚠️ memory_item 테이블이 없습니다. 테스트 스킵');
|
|
186
|
+
}
|
|
187
|
+
} finally {
|
|
188
|
+
closeDatabase(db);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
package/scripts/backup-daily.bat
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
@echo off
|
|
2
2
|
REM Memento 데이터베이스 일일 백업 스크립트
|
|
3
3
|
REM 실행 시간: 매일 오전 2시
|
|
4
|
+
REM PRD 0019: 보안 강화 (Phase 1) - Path Traversal 방지
|
|
4
5
|
|
|
5
6
|
set timestamp=%date:~0,4%%date:~5,2%%date:~8,2%-%time:~0,2%%time:~3,2%%time:~6,2%
|
|
6
7
|
set timestamp=%timestamp: =0%
|
|
7
8
|
|
|
8
9
|
echo [%date% %time%] 데이터베이스 백업 시작...
|
|
9
10
|
|
|
10
|
-
REM 백업 디렉토리 생성
|
|
11
|
+
REM 백업 디렉토리 생성 (PRD 0019: Path Traversal 방지 - 허용된 디렉토리만 사용)
|
|
11
12
|
if not exist "backup" mkdir backup
|
|
12
13
|
|
|
14
|
+
REM 백업 파일명 정제 (PRD 0019: Path Traversal 방지)
|
|
15
|
+
REM timestamp는 날짜/시간에서 생성되므로 상대적으로 안전하지만,
|
|
16
|
+
REM 추가 보안을 위해 Node.js 유틸리티로 파일명 정제 (선택사항)
|
|
17
|
+
set backupFileName=memory-backup-%timestamp%.db
|
|
18
|
+
|
|
13
19
|
REM 메인 데이터베이스 백업
|
|
14
|
-
|
|
20
|
+
REM PRD 0019: Path Traversal 방지 - 경로는 하드코딩되어 있어 상대적으로 안전
|
|
21
|
+
REM data\memory.db와 backup\ 디렉토리는 기본 허용 디렉토리 목록에 포함됨
|
|
22
|
+
copy "data\memory.db" "backup\%backupFileName%"
|
|
15
23
|
|
|
16
24
|
if %errorlevel% equ 0 (
|
|
17
25
|
echo [%date% %time%] 백업 완료: memory-backup-%timestamp%.db
|
|
@@ -3,106 +3,117 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* 임베딩 백업 스크립트
|
|
5
5
|
* 기존 벡터값을 백업한 후 삭제하고 재생성하는 스크립트
|
|
6
|
+
*
|
|
7
|
+
* 리팩토링: 공통 모듈(initializeDatabase)을 사용하여 일관된 DB 초기화 보장
|
|
8
|
+
*
|
|
9
|
+
* 사용법:
|
|
10
|
+
* - 개발 환경: npx tsx scripts/backup-embeddings.js
|
|
11
|
+
* - 프로덕션: npm run build && node dist/scripts/backup-embeddings.js
|
|
6
12
|
*/
|
|
7
13
|
|
|
8
|
-
import
|
|
14
|
+
// TypeScript 소스를 직접 import (tsx로 실행 시)
|
|
15
|
+
// 빌드된 파일을 사용하려면 '../dist/infrastructure/database/database/init.js'로 변경
|
|
16
|
+
import { initializeDatabase, closeDatabase } from '../src/infrastructure/database/database/init.js';
|
|
9
17
|
import fs from 'fs';
|
|
10
18
|
import path from 'path';
|
|
11
19
|
import { fileURLToPath } from 'url';
|
|
20
|
+
import { validateFilePath, sanitizeFileName } from '../src/shared/utils/path-validator.js';
|
|
12
21
|
|
|
13
22
|
const __filename = fileURLToPath(import.meta.url);
|
|
14
23
|
const __dirname = path.dirname(__filename);
|
|
15
24
|
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
const backupDir = path.join(
|
|
19
|
-
|
|
25
|
+
// 백업 디렉토리 설정
|
|
26
|
+
// PRD 0019: 보안 강화 (Phase 1) - Path Traversal 방지
|
|
27
|
+
const backupDir = path.join(process.cwd(), 'backup');
|
|
28
|
+
if (!validateFilePath(backupDir, 'backup')) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Path Traversal 방지: 허용되지 않은 백업 디렉토리 경로입니다. ` +
|
|
31
|
+
`경로: ${backupDir}`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 백업 파일명 정제
|
|
36
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
37
|
+
const sanitizedFileName = sanitizeFileName(`embeddings-backup-${timestamp}.json`);
|
|
38
|
+
const backupFile = path.join(backupDir, sanitizedFileName);
|
|
20
39
|
|
|
21
40
|
async function backupEmbeddings() {
|
|
22
41
|
console.log('🔄 임베딩 백업 시작...');
|
|
23
42
|
|
|
24
|
-
// 백업 디렉토리 생성
|
|
43
|
+
// 백업 디렉토리 생성 (PRD 0019: Path Traversal 방지)
|
|
44
|
+
// 경로 검증은 이미 위에서 수행됨
|
|
25
45
|
if (!fs.existsSync(backupDir)) {
|
|
26
46
|
fs.mkdirSync(backupDir, { recursive: true });
|
|
27
47
|
}
|
|
28
48
|
|
|
29
|
-
|
|
30
|
-
const db = new Database(dbPath);
|
|
49
|
+
let db = null;
|
|
31
50
|
|
|
32
51
|
try {
|
|
33
|
-
//
|
|
52
|
+
// 공통 모듈을 사용하여 데이터베이스 초기화
|
|
53
|
+
// initializeDatabase는 DB 파일이 없으면 자동으로 생성하고 초기화함
|
|
54
|
+
db = await initializeDatabase();
|
|
55
|
+
|
|
56
|
+
// 모든 임베딩 데이터 조회
|
|
34
57
|
const embeddings = db.prepare(`
|
|
35
58
|
SELECT
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
mi.type
|
|
43
|
-
FROM memory_embedding me
|
|
44
|
-
JOIN memory_item mi ON me.memory_id = mi.id
|
|
45
|
-
ORDER BY me.created_at
|
|
59
|
+
memory_id,
|
|
60
|
+
embedding,
|
|
61
|
+
dim,
|
|
62
|
+
model,
|
|
63
|
+
created_at
|
|
64
|
+
FROM memory_embedding
|
|
46
65
|
`).all();
|
|
47
66
|
|
|
48
|
-
console.log(`📊
|
|
67
|
+
console.log(`📊 백업할 임베딩 개수: ${embeddings.length}`);
|
|
49
68
|
|
|
50
69
|
if (embeddings.length === 0) {
|
|
51
70
|
console.log('⚠️ 백업할 임베딩이 없습니다.');
|
|
52
71
|
return;
|
|
53
72
|
}
|
|
54
73
|
|
|
55
|
-
//
|
|
56
|
-
const dimensionStats = {};
|
|
57
|
-
embeddings.forEach(emb => {
|
|
58
|
-
const dim = emb.dim;
|
|
59
|
-
dimensionStats[dim] = (dimensionStats[dim] || 0) + 1;
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
console.log('📈 차원별 통계:');
|
|
63
|
-
Object.entries(dimensionStats).forEach(([dim, count]) => {
|
|
64
|
-
console.log(` - ${dim}차원: ${count}개`);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// 백업 데이터 생성
|
|
74
|
+
// 백업 데이터 준비
|
|
68
75
|
const backupData = {
|
|
69
76
|
timestamp: new Date().toISOString(),
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
dim: emb.dim,
|
|
78
|
-
model: emb.model,
|
|
79
|
-
created_at: emb.created_at
|
|
77
|
+
count: embeddings.length,
|
|
78
|
+
embeddings: embeddings.map(e => ({
|
|
79
|
+
memory_id: e.memory_id,
|
|
80
|
+
embedding: e.embedding,
|
|
81
|
+
dim: e.dim,
|
|
82
|
+
model: e.model,
|
|
83
|
+
created_at: e.created_at
|
|
80
84
|
}))
|
|
81
85
|
};
|
|
82
86
|
|
|
83
|
-
//
|
|
84
|
-
fs.writeFileSync(backupFile, JSON.stringify(backupData, null, 2));
|
|
87
|
+
// JSON 파일로 저장
|
|
88
|
+
fs.writeFileSync(backupFile, JSON.stringify(backupData, null, 2), 'utf8');
|
|
85
89
|
console.log(`✅ 백업 완료: ${backupFile}`);
|
|
90
|
+
console.log(`📦 백업 크기: ${(fs.statSync(backupFile).size / 1024).toFixed(2)} KB`);
|
|
86
91
|
|
|
87
|
-
//
|
|
88
|
-
console.log('
|
|
89
|
-
|
|
90
|
-
console.log(
|
|
91
|
-
|
|
92
|
-
console.log('🎉 백업 및 삭제 완료!');
|
|
93
|
-
console.log('다음 단계: npm run regenerate-embeddings');
|
|
92
|
+
// 사용자 확인
|
|
93
|
+
console.log('\n⚠️ 백업이 완료되었습니다.');
|
|
94
|
+
console.log('다음 단계로 임베딩을 삭제하고 재생성할 수 있습니다.');
|
|
95
|
+
console.log('백업 파일:', backupFile);
|
|
94
96
|
|
|
95
97
|
} catch (error) {
|
|
96
|
-
console.error('❌ 백업 실패:', error);
|
|
98
|
+
console.error('❌ 백업 실패:', error.message);
|
|
99
|
+
if (error.stack) {
|
|
100
|
+
console.error(' 스택 트레이스:', error.stack);
|
|
101
|
+
}
|
|
97
102
|
process.exit(1);
|
|
98
103
|
} finally {
|
|
99
|
-
|
|
104
|
+
// 데이터베이스 연결 종료
|
|
105
|
+
if (db) {
|
|
106
|
+
closeDatabase(db);
|
|
107
|
+
}
|
|
100
108
|
}
|
|
101
109
|
}
|
|
102
110
|
|
|
103
111
|
// 스크립트 실행
|
|
104
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
105
|
-
backupEmbeddings().catch(
|
|
112
|
+
if (import.meta.url === `file://${process.argv[1]}` || import.meta.url.endsWith(process.argv[1])) {
|
|
113
|
+
backupEmbeddings().catch((error) => {
|
|
114
|
+
console.error('❌ 스크립트 실행 중 오류 발생:', error);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
});
|
|
106
117
|
}
|
|
107
118
|
|
|
108
119
|
export { backupEmbeddings };
|