Add Claude API support and fix CORS issues
- Add Claude API integration to LLM service - Create Express backend server with CORS support - Add API proxy example page - Fix CORS errors by routing through backend - Update LLM configuration to support Claude - Add package.json with dependencies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
151
server.js
Normal file
151
server.js
Normal file
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* Express Server
|
||||
* HR 績效評核系統後端伺服器
|
||||
*/
|
||||
|
||||
require('dotenv').config();
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const helmet = require('helmet');
|
||||
const morgan = require('morgan');
|
||||
const path = require('path');
|
||||
|
||||
// Import routes
|
||||
const llmRoutes = require('./routes/llm.routes');
|
||||
|
||||
// Import error handler
|
||||
const { handleError } = require('./utils/errorHandler');
|
||||
|
||||
// Create Express app
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3000;
|
||||
|
||||
// ============================================
|
||||
// Middleware
|
||||
// ============================================
|
||||
|
||||
// Security headers
|
||||
app.use(helmet());
|
||||
|
||||
// CORS configuration
|
||||
app.use(cors({
|
||||
origin: process.env.FRONTEND_URL || '*',
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
|
||||
allowedHeaders: ['Content-Type', 'Authorization'],
|
||||
credentials: true,
|
||||
}));
|
||||
|
||||
// Body parsing
|
||||
app.use(express.json({ limit: '10mb' }));
|
||||
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
||||
|
||||
// Logging
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
app.use(morgan('dev'));
|
||||
} else {
|
||||
app.use(morgan('combined'));
|
||||
}
|
||||
|
||||
// Static files
|
||||
app.use(express.static('public'));
|
||||
|
||||
// ============================================
|
||||
// Routes
|
||||
// ============================================
|
||||
|
||||
// Health check
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'HR Performance System API is running',
|
||||
timestamp: new Date().toISOString(),
|
||||
environment: process.env.NODE_ENV,
|
||||
});
|
||||
});
|
||||
|
||||
// API routes
|
||||
app.use('/api/llm', llmRoutes);
|
||||
|
||||
// Root endpoint
|
||||
app.get('/', (req, res) => {
|
||||
res.json({
|
||||
name: 'HR Performance System API',
|
||||
version: '1.0.0',
|
||||
description: '四卡循環績效管理系統',
|
||||
endpoints: {
|
||||
health: '/health',
|
||||
llm: '/api/llm',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// Error Handling
|
||||
// ============================================
|
||||
|
||||
// 404 handler
|
||||
app.use((req, res, next) => {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
error: {
|
||||
statusCode: 404,
|
||||
message: `Cannot ${req.method} ${req.path}`,
|
||||
timestamp: new Date().toISOString(),
|
||||
path: req.path,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// Global error handler
|
||||
app.use(handleError);
|
||||
|
||||
// ============================================
|
||||
// Server Start
|
||||
// ============================================
|
||||
|
||||
const server = app.listen(PORT, () => {
|
||||
console.log('='.repeat(50));
|
||||
console.log('🚀 HR Performance System API Server');
|
||||
console.log('='.repeat(50));
|
||||
console.log(`📡 Server running on: http://localhost:${PORT}`);
|
||||
console.log(`🌍 Environment: ${process.env.NODE_ENV || 'development'}`);
|
||||
console.log(`📅 Started at: ${new Date().toLocaleString('zh-TW')}`);
|
||||
console.log('='.repeat(50));
|
||||
console.log('\n📚 Available endpoints:');
|
||||
console.log(` GET / - API information`);
|
||||
console.log(` GET /health - Health check`);
|
||||
console.log(` POST /api/llm/test/* - Test LLM connections`);
|
||||
console.log(` POST /api/llm/generate - Generate content with LLM`);
|
||||
console.log('\n✨ Server is ready to accept connections!\n');
|
||||
});
|
||||
|
||||
// Graceful shutdown
|
||||
process.on('SIGTERM', () => {
|
||||
console.log('\n⚠️ SIGTERM received. Shutting down gracefully...');
|
||||
server.close(() => {
|
||||
console.log('✅ Server closed');
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
|
||||
process.on('SIGINT', () => {
|
||||
console.log('\n⚠️ SIGINT received. Shutting down gracefully...');
|
||||
server.close(() => {
|
||||
console.log('✅ Server closed');
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
|
||||
// Uncaught exception handler
|
||||
process.on('uncaughtException', (error) => {
|
||||
console.error('❌ Uncaught Exception:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Unhandled rejection handler
|
||||
process.on('unhandledRejection', (reason, promise) => {
|
||||
console.error('❌ Unhandled Rejection at:', promise, 'reason:', reason);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
Reference in New Issue
Block a user