Initial commit: 5 Why Root Cause Analyzer v1.0.0

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>
This commit is contained in:
donald
2025-12-05 18:29:29 +08:00
commit 78efac64e2
23 changed files with 3059 additions and 0 deletions

102
config.js Normal file
View File

@@ -0,0 +1,102 @@
import dotenv from 'dotenv';
import mysql from 'mysql2/promise';
// 載入環境變數
dotenv.config();
// 資料庫配置
export const dbConfig = {
host: process.env.DB_HOST || 'localhost',
port: parseInt(process.env.DB_PORT) || 3306,
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || '',
database: process.env.DB_NAME || 'db_A102',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
enableKeepAlive: true,
keepAliveInitialDelay: 0
};
// 建立連線池
export const pool = mysql.createPool(dbConfig);
// 測試資料庫連線
export async function testConnection() {
try {
const connection = await pool.getConnection();
console.log('✅ Database connected successfully');
console.log(` Host: ${dbConfig.host}:${dbConfig.port}`);
console.log(` Database: ${dbConfig.database}`);
connection.release();
return true;
} catch (error) {
console.error('❌ Database connection failed:', error.message);
return false;
}
}
// 執行查詢的輔助函數
export async function query(sql, params = []) {
try {
const [results] = await pool.execute(sql, params);
return results;
} catch (error) {
console.error('Query error:', error.message);
throw error;
}
}
// Ollama API 配置
export const ollamaConfig = {
apiUrl: process.env.OLLAMA_API_URL || 'https://ollama_pjapi.theaken.com',
model: process.env.OLLAMA_MODEL || 'qwen2.5:3b',
maxTokens: 6000,
temperature: 0.7,
timeout: 120000
};
// 伺服器配置
export const serverConfig = {
host: process.env.SERVER_HOST || 'localhost',
port: parseInt(process.env.SERVER_PORT) || 3001,
clientPort: parseInt(process.env.CLIENT_PORT) || 5173
};
// Session 配置
export const sessionConfig = {
secret: process.env.SESSION_SECRET || 'change-this-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === 'production',
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000 // 24 hours
}
};
// 安全配置
export const securityConfig = {
bcryptRounds: parseInt(process.env.BCRYPT_ROUNDS) || 10,
rateLimitMax: parseInt(process.env.RATE_LIMIT_MAX) || 100,
rateLimitWindowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 900000 // 15 minutes
};
// Gitea 配置
export const giteaConfig = {
url: process.env.GITEA_URL || 'https://gitea.theaken.com/',
user: process.env.GITEA_USER || '',
token: process.env.GITEA_TOKEN || ''
};
export default {
dbConfig,
pool,
testConnection,
query,
ollamaConfig,
serverConfig,
sessionConfig,
securityConfig,
giteaConfig
};