feat(app): wire up Express app factory and production entry point (Task 13)
Initializes DB, creates default admin user, connects brokers/PG sources, starts query timers, and serves frontend/dist as SPA. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
44f4b6d010
commit
9e96ecc231
45
display/middleware/src/api/index.ts
Normal file
45
display/middleware/src/api/index.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import path from 'path';
|
||||
import authRouter from './routes/auth';
|
||||
import displayApiRouter from './routes/display-api';
|
||||
import mqttBrokersRouter from './routes/mqtt-brokers';
|
||||
import mqttTopicsRouter from './routes/mqtt-topics';
|
||||
import pgSourcesRouter from './routes/pg-sources';
|
||||
import datapointsRouter from './routes/datapoints';
|
||||
import displaysRouter from './routes/displays';
|
||||
import layoutsRouter from './routes/layouts';
|
||||
import { authMiddleware } from './middleware/auth';
|
||||
|
||||
export function createApp(): express.Application {
|
||||
const app = express();
|
||||
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
|
||||
// Health check
|
||||
app.get('/health', (_req, res) => {
|
||||
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
||||
});
|
||||
|
||||
// Public routes
|
||||
app.use('/api/auth', authRouter);
|
||||
app.use('/api/display', displayApiRouter);
|
||||
|
||||
// Protected management routes
|
||||
app.use('/api/mqtt/brokers/:brokerId/topics', authMiddleware, mqttTopicsRouter);
|
||||
app.use('/api/mqtt/brokers', authMiddleware, mqttBrokersRouter);
|
||||
app.use('/api/pg/sources', authMiddleware, pgSourcesRouter);
|
||||
app.use('/api/datapoints', authMiddleware, datapointsRouter);
|
||||
app.use('/api/displays', authMiddleware, displaysRouter);
|
||||
app.use('/api/layouts', authMiddleware, layoutsRouter);
|
||||
|
||||
// Serve frontend/dist as static files with SPA fallback
|
||||
const frontendDist = path.join(__dirname, '..', '..', '..', 'frontend', 'dist');
|
||||
app.use(express.static(frontendDist));
|
||||
app.get('*', (_req, res) => {
|
||||
res.sendFile(path.join(frontendDist, 'index.html'));
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
@ -1,23 +1,54 @@
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import authRouter from './api/routes/auth';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { initDb } from './db/index';
|
||||
import { createApp } from './api/index';
|
||||
import { connectAllEnabledBrokers } from './modules/mqtt/broker-manager';
|
||||
import { connectAllEnabledSources } from './modules/postgres/source-manager';
|
||||
import { startAllQueryTimers } from './modules/postgres/query-scheduler';
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT ? parseInt(process.env.PORT) : 4000;
|
||||
const DB_PATH = process.env.DB_PATH ?? './display.db';
|
||||
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
async function main(): Promise<void> {
|
||||
// Initialize database
|
||||
const db = initDb(DB_PATH);
|
||||
|
||||
app.get('/health', (_req, res) => {
|
||||
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
||||
});
|
||||
// Create default admin user if no users exist
|
||||
const userCount = db
|
||||
.prepare('SELECT COUNT(*) as count FROM users')
|
||||
.get() as { count: number };
|
||||
|
||||
app.use('/api/auth', authRouter);
|
||||
if (userCount.count === 0) {
|
||||
const hash = bcrypt.hashSync('admin', 10);
|
||||
db.run(
|
||||
`INSERT INTO users (username, password_hash) VALUES (?, ?)`,
|
||||
['admin', hash]
|
||||
);
|
||||
console.log('Created default admin user (admin/admin)');
|
||||
}
|
||||
|
||||
// Connect all enabled MQTT brokers
|
||||
await connectAllEnabledBrokers();
|
||||
|
||||
// Connect all enabled PostgreSQL sources and start query timers
|
||||
await connectAllEnabledSources();
|
||||
startAllQueryTimers();
|
||||
|
||||
// Create and start Express app
|
||||
const app = createApp();
|
||||
|
||||
if (require.main === module) {
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Middleware server running on port ${PORT}`);
|
||||
});
|
||||
}
|
||||
|
||||
export default app;
|
||||
// Only run when executed directly (not during tests)
|
||||
if (require.main === module) {
|
||||
main().catch((err) => {
|
||||
console.error('Fatal startup error:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
// Export createApp for tests that import from index
|
||||
export { createApp };
|
||||
export default createApp();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user