- Add verify-migration.js script for testing database migrations - Add database config module for centralized configuration - Add chutes.txt prompt for system responses - Update database implementation and testing documentation - Add database migration and setup scripts - Update session system and LLM tool configuration - Update deployment checklist and environment example - Update Dockerfile and docker-compose configuration
131 lines
4.4 KiB
JavaScript
Executable File
131 lines
4.4 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
/**
|
|
* Database initialization script for container startup
|
|
* Automatically sets up database on first run or when database doesn't exist
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const crypto = require('crypto');
|
|
const { DATA_ROOT, DB_PATH, KEY_FILE } = require('../src/database/config');
|
|
|
|
const DATABASE_PATH = DB_PATH;
|
|
const USE_JSON_DATABASE = process.env.USE_JSON_DATABASE === '1' || process.env.USE_JSON_DATABASE === 'true';
|
|
|
|
async function initializeDatabase() {
|
|
// Skip if using JSON mode
|
|
if (USE_JSON_DATABASE) {
|
|
console.log('📁 Using JSON database mode (backward compatibility)');
|
|
return;
|
|
}
|
|
|
|
console.log('🔍 Checking database status...');
|
|
|
|
// Ensure data directory exists
|
|
const dataDir = path.dirname(DATABASE_PATH);
|
|
if (!fs.existsSync(dataDir)) {
|
|
console.log('📁 Creating data directory:', dataDir);
|
|
fs.mkdirSync(dataDir, { recursive: true });
|
|
}
|
|
|
|
// Check if database exists
|
|
const dbExists = fs.existsSync(DATABASE_PATH);
|
|
|
|
if (dbExists) {
|
|
console.log('✅ Database already exists:', DATABASE_PATH);
|
|
|
|
if (!process.env.DATABASE_ENCRYPTION_KEY && KEY_FILE && fs.existsSync(KEY_FILE)) {
|
|
const persistedKey = fs.readFileSync(KEY_FILE, 'utf8').trim();
|
|
if (persistedKey) {
|
|
process.env.DATABASE_ENCRYPTION_KEY = persistedKey;
|
|
console.log('✅ Loaded encryption key from file');
|
|
}
|
|
}
|
|
|
|
// Verify encryption key is set
|
|
if (!process.env.DATABASE_ENCRYPTION_KEY) {
|
|
console.error('❌ DATABASE_ENCRYPTION_KEY not set!');
|
|
console.error(' Database exists but encryption key is missing.');
|
|
console.error(' Set DATABASE_ENCRYPTION_KEY to the key used when creating the database.');
|
|
process.exit(1);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
console.log('🔧 Database not found, setting up new database...');
|
|
|
|
// Generate encryption key if not provided
|
|
if (!process.env.DATABASE_ENCRYPTION_KEY && KEY_FILE && fs.existsSync(KEY_FILE)) {
|
|
const persistedKey = fs.readFileSync(KEY_FILE, 'utf8').trim();
|
|
if (persistedKey) {
|
|
process.env.DATABASE_ENCRYPTION_KEY = persistedKey;
|
|
console.log('✅ Loaded encryption key from file');
|
|
}
|
|
}
|
|
|
|
if (!process.env.DATABASE_ENCRYPTION_KEY) {
|
|
const generatedKey = crypto.randomBytes(32).toString('hex');
|
|
process.env.DATABASE_ENCRYPTION_KEY = generatedKey;
|
|
|
|
console.log('⚠️ Generated new encryption key (save this!)');
|
|
console.log('⚠️ DATABASE_ENCRYPTION_KEY=' + generatedKey);
|
|
console.log('⚠️ Add this to your environment configuration to persist it!');
|
|
|
|
// Save to a file for persistence
|
|
const keyFile = KEY_FILE || path.join(dataDir, '.encryption_key');
|
|
fs.writeFileSync(keyFile, generatedKey, { mode: 0o600 });
|
|
console.log('⚠️ Saved to:', keyFile);
|
|
}
|
|
|
|
// Generate JWT secret if not provided
|
|
if (!process.env.JWT_SECRET && !process.env.SESSION_SECRET) {
|
|
const jwtSecret = crypto.randomBytes(32).toString('hex');
|
|
process.env.JWT_SECRET = jwtSecret;
|
|
|
|
console.log('⚠️ Generated new JWT secret (save this!)');
|
|
console.log('⚠️ JWT_SECRET=' + jwtSecret);
|
|
|
|
// Save to a file for persistence
|
|
const jwtFile = path.join(dataDir, '.jwt_secret');
|
|
fs.writeFileSync(jwtFile, jwtSecret, { mode: 0o600 });
|
|
console.log('⚠️ Saved to:', jwtFile);
|
|
}
|
|
|
|
// Run setup script
|
|
try {
|
|
const setupScript = require('./setup-database.js');
|
|
console.log('✅ Database setup complete');
|
|
} catch (error) {
|
|
console.error('❌ Failed to setup database:', error.message);
|
|
throw error;
|
|
}
|
|
|
|
// Check if there are JSON files to migrate
|
|
const usersFile = path.join(path.join(DATA_ROOT, '.opencode-chat'), 'users.json');
|
|
const sessionsFile = path.join(path.join(DATA_ROOT, '.opencode-chat'), 'user-sessions.json');
|
|
|
|
const hasJsonData = fs.existsSync(usersFile) || fs.existsSync(sessionsFile);
|
|
|
|
if (hasJsonData) {
|
|
console.log('📦 Found existing JSON data files');
|
|
console.log(' To migrate data, run: node scripts/migrate-to-database.js');
|
|
console.log(' Or set USE_JSON_DATABASE=1 to continue using JSON files');
|
|
}
|
|
}
|
|
|
|
// Auto-initialize if called directly
|
|
if (require.main === module) {
|
|
initializeDatabase()
|
|
.then(() => {
|
|
console.log('✅ Database initialization complete');
|
|
process.exit(0);
|
|
})
|
|
.catch(error => {
|
|
console.error('❌ Database initialization failed:', error);
|
|
process.exit(1);
|
|
});
|
|
}
|
|
|
|
module.exports = { initializeDatabase };
|