Migrate all repos into monorepo context folders

Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
      Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
      Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)

Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
This commit is contained in:
2026-06-30 20:39:52 +02:00
parent 2f2b295531
commit a5f8fb49ab
1717 changed files with 447332 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
import express, { Router } from 'express';
import cors from 'cors';
import path from 'path';
import { fileURLToPath } from 'url';
import { apiRouter } from './routes.js';
import { sseRouter } from './sse.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
const PORT = parseInt(process.env.PORT || '3001', 10);
const APP_PASSWORD = process.env.APP_PASSWORD || 'UNIKAT_jury';
app.use(cors());
app.use(express.json());
// Health check (no auth required)
app.get('/api/health', (_req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
// Password protection middleware
app.use((req, res, next) => {
if (req.path === '/api/health') { next(); return; }
// Check query param
const token = req.query.token as string | undefined;
if (token === APP_PASSWORD) {
res.cookie('jury_auth', APP_PASSWORD, { httpOnly: true, maxAge: 24 * 60 * 60 * 1000 });
if (!req.path.startsWith('/api')) {
res.redirect(req.path || '/');
return;
}
next();
return;
}
// Check cookie
const cookieHeader = req.headers.cookie || '';
const cookies = Object.fromEntries(
cookieHeader.split(';').map(c => {
const [key, ...val] = c.trim().split('=');
return [key, val.join('=')];
})
);
if (cookies.jury_auth === APP_PASSWORD) { next(); return; }
// Not authenticated
if (req.path.startsWith('/api')) {
res.status(401).json({ error: 'Unauthorized' });
return;
}
// Login page
res.status(401).send(`<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>UNIKAT Jury Voting</title>
<style>
body { background: #0a0a0a; color: #f0f0f0; font-family: 'Outfit', sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }
.login { text-align: center; max-width: 320px; padding: 40px; }
h1 { font-size: 1.5rem; margin-bottom: 8px; }
p { color: #999; margin-bottom: 24px; }
input { width: 100%; padding: 14px; border-radius: 12px; border: 1px solid rgba(255,255,255,0.1); background: rgba(25,25,25,0.6); color: #f0f0f0; font-size: 1rem; text-align: center; outline: none; }
input:focus { border-color: #00FF00; }
button { width: 100%; margin-top: 12px; padding: 14px; border-radius: 50px; border: none; background: linear-gradient(135deg, #00FF00, #00b300); color: #000; font-weight: 800; font-size: 1.1rem; cursor: pointer; }
</style>
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;800&display=swap" rel="stylesheet">
</head>
<body>
<div class="login">
<h1>🗳️ Jury Voting</h1>
<p>15. UNIKAT Ideenwettbewerb</p>
<form onsubmit="login(event)">
<input type="password" id="pw" placeholder="Passwort eingeben" autofocus>
<button type="submit">Einloggen</button>
</form>
</div>
<script>
function login(e) {
e.preventDefault();
const pw = document.getElementById('pw').value;
window.location.href = '/?token=' + encodeURIComponent(pw);
}
</script>
</body>
</html>`);
});
// API routes
app.use(apiRouter);
app.use(sseRouter);
// Serve static frontend in production
const distPath = path.resolve(__dirname, '..', 'dist');
if (process.env.NODE_ENV === 'production') {
app.use(express.static(distPath));
app.use((_req, res) => {
res.sendFile(path.join(distPath, 'index.html'));
});
}
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
export default app;