Phase 0 & Phase 2 completed: - Project structure setup - Environment configuration (.env, .gitignore) - Enterprise-grade dependencies (bcrypt, helmet, mysql2, etc.) - Complete database schema with 8 tables + 2 views - Database initialization scripts - Comprehensive documentation Database Tables: - users (user management with 3-tier permissions) - analyses (analysis records) - analysis_perspectives (multi-angle analysis) - analysis_whys (detailed 5 Why records) - llm_configs (LLM API configurations) - system_settings (system parameters) - audit_logs (security audit trail) - sessions (session management) Tech Stack: - Backend: Node.js + Express - Frontend: React 18 + Vite + Tailwind CSS - Database: MySQL 9.4.0 - AI: Ollama API (qwen2.5:3b) Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
76 lines
2.5 KiB
JavaScript
76 lines
2.5 KiB
JavaScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import mysql from 'mysql2/promise';
|
|
import dotenv from 'dotenv';
|
|
import bcrypt from 'bcryptjs';
|
|
|
|
dotenv.config();
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
const dbConfig = {
|
|
host: process.env.DB_HOST,
|
|
port: parseInt(process.env.DB_PORT),
|
|
user: process.env.DB_USER,
|
|
password: process.env.DB_PASSWORD,
|
|
database: process.env.DB_NAME,
|
|
multipleStatements: true
|
|
};
|
|
|
|
async function initDatabase() {
|
|
let connection;
|
|
|
|
try {
|
|
console.log('\n╔════════════════════════════════════════════╗');
|
|
console.log('║ 5 Why Analyzer - Database Initialization ║');
|
|
console.log('╚════════════════════════════════════════════╝\n');
|
|
|
|
console.log('🔄 Connecting...');
|
|
connection = await mysql.createConnection(dbConfig);
|
|
console.log('✅ Connected\n');
|
|
|
|
// 生成密碼 hash
|
|
const adminPassword = process.env.ADMIN_PASSWORD || 'Admin@123456';
|
|
const adminHash = await bcrypt.hash(adminPassword, 10);
|
|
|
|
// 讀取並執行 SQL
|
|
const sqlPath = path.join(__dirname, '../docs/db_schema.sql');
|
|
let sqlContent = fs.readFileSync(sqlPath, 'utf8');
|
|
sqlContent = sqlContent.replace(/\$2a\$10\$YourBcryptHashHere/g, adminHash);
|
|
|
|
console.log('📝 Executing SQL statements...\n');
|
|
await connection.query(sqlContent);
|
|
|
|
console.log('\n✅ Database initialized successfully!\n');
|
|
|
|
// 列出資料表
|
|
const [tables] = await connection.execute(
|
|
"SELECT table_name FROM information_schema.tables WHERE table_schema = ? AND table_name LIKE '%' ORDER BY table_name",
|
|
[dbConfig.database]
|
|
);
|
|
|
|
const fiveWhyTables = tables.filter(t => !t.table_name.startsWith('hr_') && !t.table_name.startsWith('pm_'));
|
|
|
|
if (fiveWhyTables.length > 0) {
|
|
console.log('📊 5 Why Analyzer Tables:');
|
|
fiveWhyTables.forEach((table, index) => {
|
|
console.log(` ${index + 1}. ${table.table_name}`);
|
|
});
|
|
}
|
|
|
|
console.log(`\n🔐 Admin credentials:`);
|
|
console.log(` Email: ${process.env.ADMIN_EMAIL || 'admin@example.com'}`);
|
|
console.log(` Password: ${adminPassword}\n`);
|
|
|
|
} catch (error) {
|
|
console.error('\n❌ Error:', error.message);
|
|
process.exit(1);
|
|
} finally {
|
|
if (connection) await connection.end();
|
|
}
|
|
}
|
|
|
|
initDatabase();
|