stage 1
This commit is contained in:
+54
-7
@@ -1,29 +1,76 @@
|
||||
import cors from 'cors';
|
||||
import express from 'express';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import path from 'node:path';
|
||||
|
||||
import { errorHandler, notFoundHandler } from './middleware/errorHandler.js';
|
||||
import configRoutes from './routes/configRoutes.js';
|
||||
import healthRoutes from './routes/healthRoutes.js';
|
||||
import lookupRoutes from './routes/lookupRoutes.js';
|
||||
import reportRoutes from './routes/reportRoutes.js';
|
||||
import templateRoutes from './routes/templateRoutes.js';
|
||||
|
||||
const app = express();
|
||||
|
||||
/*
|
||||
* The application serves two concerns from the same Express process:
|
||||
* 1. a versioned REST API (v1) used by the proof-of-concept frontend,
|
||||
* 2. static frontend assets for the chooser portal and the app shell itself.
|
||||
*
|
||||
* All API endpoints live under /api/v1/ so the contract can evolve without
|
||||
* breaking older clients. Keeping both concerns in one process keeps the PoC
|
||||
* easy to run in Docker and avoids introducing an additional frontend dev
|
||||
* server before the product shape is stable.
|
||||
*/
|
||||
const publicDir = fileURLToPath(new URL('../public', import.meta.url));
|
||||
const userPagePath = path.join(publicDir, 'user.html');
|
||||
const adminPagePath = path.join(publicDir, 'admin.html');
|
||||
const portalPath = path.join(publicDir, 'portal.html');
|
||||
|
||||
app.use(cors());
|
||||
app.use(express.json({ limit: '10mb' }));
|
||||
|
||||
app.get('/', (_req, res) => {
|
||||
app.get('/api/v1', (_req, res) => {
|
||||
res.json({
|
||||
service: 'check-list-poc-api',
|
||||
version: '0.1.0',
|
||||
description: 'PoC API for template and configuration delivery.'
|
||||
version: '0.2.0',
|
||||
description: 'Versioned PoC API for template, configuration, and report management.'
|
||||
});
|
||||
});
|
||||
|
||||
app.use('/api/health', healthRoutes);
|
||||
app.use('/api/templates', templateRoutes);
|
||||
app.use('/api/lookups', lookupRoutes);
|
||||
app.use('/api/config', configRoutes);
|
||||
/*
|
||||
* All API routes are grouped under /api/v1/. The version prefix ensures future
|
||||
* breaking changes can be introduced on /api/v2/ without disrupting existing
|
||||
* frontend deployments that still reference v1 contract shapes.
|
||||
*/
|
||||
app.use('/api/v1/health', healthRoutes);
|
||||
app.use('/api/v1/templates', templateRoutes);
|
||||
app.use('/api/v1/lookups', lookupRoutes);
|
||||
app.use('/api/v1/config', configRoutes);
|
||||
app.use('/api/v1/reports', reportRoutes);
|
||||
|
||||
/*
|
||||
* The root route intentionally serves a neutral portal page. This gives the
|
||||
* project distinct user and administrator entry points without introducing a
|
||||
* full authentication flow yet.
|
||||
*/
|
||||
app.get('/', (_req, res) => {
|
||||
res.sendFile(portalPath);
|
||||
});
|
||||
|
||||
/*
|
||||
* User and admin workspaces live in separate HTML files so each page only loads
|
||||
* the markup it needs. The shared frontend JavaScript (app.js) detects which
|
||||
* elements are present and binds behavior accordingly.
|
||||
*/
|
||||
app.get(['/user', '/user/'], (_req, res) => {
|
||||
res.sendFile(userPagePath);
|
||||
});
|
||||
|
||||
app.get(['/admin', '/admin/'], (_req, res) => {
|
||||
res.sendFile(adminPagePath);
|
||||
});
|
||||
app.use(express.static(publicDir));
|
||||
|
||||
app.use(notFoundHandler);
|
||||
app.use(errorHandler);
|
||||
|
||||
Reference in New Issue
Block a user