initial commit
This commit is contained in:
228
server.js
Normal file
228
server.js
Normal file
@@ -0,0 +1,228 @@
|
||||
/**
|
||||
* Express server to serve FFXI Trust character data from PostgreSQL database
|
||||
*/
|
||||
|
||||
const express = require('express');
|
||||
const { Pool } = require('pg');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Database configuration
|
||||
let dbConfig = {};
|
||||
|
||||
// Try to read from environment variables first
|
||||
if (process.env.PSQL_HOST && process.env.PSQL_USER && process.env.PSQL_DBNAME) {
|
||||
console.log('Using database configuration from environment variables');
|
||||
dbConfig = {
|
||||
PSQL_USER: process.env.PSQL_USER,
|
||||
PSQL_HOST: process.env.PSQL_HOST,
|
||||
PSQL_DBNAME: process.env.PSQL_DBNAME,
|
||||
PSQL_PASSWORD: process.env.PSQL_PASSWORD,
|
||||
PSQL_PORT: process.env.PSQL_PORT || '5432',
|
||||
};
|
||||
} else {
|
||||
// Fall back to db.conf file
|
||||
try {
|
||||
console.log('Reading database configuration from db.conf file');
|
||||
const dbConfFile = fs.readFileSync('db.conf', 'utf8');
|
||||
|
||||
// Parse the db.conf file
|
||||
dbConfFile.split('\n').forEach(line => {
|
||||
if (line.trim() === '') return;
|
||||
|
||||
const [key, value] = line.split('=');
|
||||
if (key && value) {
|
||||
// Remove quotes if present
|
||||
const cleanValue = value.replace(/^['"]|['"]$/g, '');
|
||||
dbConfig[key] = cleanValue;
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Error reading db.conf file:', err.message);
|
||||
console.error('Please ensure db.conf exists or provide environment variables');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Configure PostgreSQL connection
|
||||
const pool = new Pool({
|
||||
user: dbConfig.PSQL_USER,
|
||||
host: dbConfig.PSQL_HOST,
|
||||
database: dbConfig.PSQL_DBNAME,
|
||||
password: dbConfig.PSQL_PASSWORD,
|
||||
port: dbConfig.PSQL_PORT,
|
||||
});
|
||||
|
||||
// Create Express app
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3000;
|
||||
|
||||
// Middleware to parse JSON bodies
|
||||
app.use(express.json());
|
||||
|
||||
// Set up EJS as the template engine
|
||||
app.set('view engine', 'ejs');
|
||||
app.set('views', path.join(__dirname, '.'));
|
||||
|
||||
// Serve static files (except index.html which will be rendered with EJS)
|
||||
app.use(express.static('.', {
|
||||
index: false
|
||||
}));
|
||||
|
||||
// Render index.ejs with environment variables
|
||||
app.get('/', (req, res) => {
|
||||
res.render('index.ejs', {
|
||||
process: {
|
||||
env: {
|
||||
PSQL_HOST: dbConfig.PSQL_HOST,
|
||||
PSQL_PORT: dbConfig.PSQL_PORT,
|
||||
PSQL_USER: dbConfig.PSQL_USER,
|
||||
PSQL_PASSWORD: dbConfig.PSQL_PASSWORD,
|
||||
PSQL_DBNAME: dbConfig.PSQL_DBNAME
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// API endpoint to get all trusts
|
||||
app.get('/api/trusts', async (req, res) => {
|
||||
try {
|
||||
const client = await pool.connect();
|
||||
const result = await client.query('SELECT * FROM trusts ORDER BY name');
|
||||
const trusts = result.rows;
|
||||
client.release();
|
||||
|
||||
res.json(trusts);
|
||||
} catch (err) {
|
||||
console.error('Error executing query', err);
|
||||
res.status(500).json({ error: 'Database error' });
|
||||
}
|
||||
});
|
||||
|
||||
// API endpoint to get a specific trust by ID
|
||||
app.get('/api/trusts/:id', async (req, res) => {
|
||||
try {
|
||||
const id = parseInt(req.params.id);
|
||||
const client = await pool.connect();
|
||||
const result = await client.query('SELECT * FROM trusts WHERE id = $1', [id]);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
res.status(404).json({ error: 'Trust not found' });
|
||||
} else {
|
||||
res.json(result.rows[0]);
|
||||
}
|
||||
|
||||
client.release();
|
||||
} catch (err) {
|
||||
console.error('Error executing query', err);
|
||||
res.status(500).json({ error: 'Database error' });
|
||||
}
|
||||
});
|
||||
|
||||
// API endpoint to get trusts by role
|
||||
app.get('/api/trusts/role/:role', async (req, res) => {
|
||||
try {
|
||||
const role = req.params.role;
|
||||
const client = await pool.connect();
|
||||
const result = await client.query('SELECT * FROM trusts WHERE role = $1 ORDER BY name', [role]);
|
||||
const trusts = result.rows;
|
||||
client.release();
|
||||
|
||||
res.json(trusts);
|
||||
} catch (err) {
|
||||
console.error('Error executing query', err);
|
||||
res.status(500).json({ error: 'Database error' });
|
||||
}
|
||||
});
|
||||
|
||||
// API endpoint to search trusts
|
||||
app.get('/api/trusts/search/:query', async (req, res) => {
|
||||
try {
|
||||
const query = req.params.query;
|
||||
const client = await pool.connect();
|
||||
const result = await client.query(`
|
||||
SELECT * FROM trusts
|
||||
WHERE
|
||||
name ILIKE $1 OR
|
||||
role ILIKE $1 OR
|
||||
job ILIKE $1 OR
|
||||
spells ILIKE $1 OR
|
||||
abilities ILIKE $1
|
||||
ORDER BY name
|
||||
`, [`%${query}%`]);
|
||||
|
||||
const trusts = result.rows;
|
||||
client.release();
|
||||
|
||||
res.json(trusts);
|
||||
} catch (err) {
|
||||
console.error('Error executing query', err);
|
||||
res.status(500).json({ error: 'Database error' });
|
||||
}
|
||||
});
|
||||
|
||||
// API endpoint to toggle the acquired status of a trust
|
||||
app.put('/api/trusts/:id/toggle-acquired', async (req, res) => {
|
||||
try {
|
||||
const id = parseInt(req.params.id);
|
||||
const client = await pool.connect();
|
||||
|
||||
// Get the current acquired status
|
||||
const getResult = await client.query('SELECT acquired FROM trusts WHERE id = $1', [id]);
|
||||
|
||||
if (getResult.rows.length === 0) {
|
||||
client.release();
|
||||
return res.status(404).json({ error: 'Trust not found' });
|
||||
}
|
||||
|
||||
// Toggle the acquired status
|
||||
const currentStatus = getResult.rows[0].acquired;
|
||||
const newStatus = !currentStatus;
|
||||
|
||||
// Update the acquired status
|
||||
await client.query('UPDATE trusts SET acquired = $1 WHERE id = $2', [newStatus, id]);
|
||||
|
||||
// Get the updated trust
|
||||
const result = await client.query('SELECT * FROM trusts WHERE id = $1', [id]);
|
||||
client.release();
|
||||
|
||||
res.json(result.rows[0]);
|
||||
} catch (err) {
|
||||
console.error('Error executing query', err);
|
||||
res.status(500).json({ error: 'Database error' });
|
||||
}
|
||||
});
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', async (req, res) => {
|
||||
try {
|
||||
// Check database connection
|
||||
const client = await pool.connect();
|
||||
await client.query('SELECT 1');
|
||||
client.release();
|
||||
|
||||
res.status(200).json({
|
||||
status: 'ok',
|
||||
message: 'Service is healthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
version: process.env.npm_package_version || '1.0.0',
|
||||
database: 'connected'
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Health check failed:', err);
|
||||
res.status(500).json({
|
||||
status: 'error',
|
||||
message: 'Service is unhealthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
error: err.message,
|
||||
database: 'disconnected'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Start the server
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Server running on port ${PORT}`);
|
||||
console.log(`Access the web app at http://localhost:${PORT}`);
|
||||
console.log(`API available at http://localhost:${PORT}/api/trusts`);
|
||||
});
|
||||
Reference in New Issue
Block a user