mirror of
https://github.com/blackboxprogramming/BlackRoad-Operating-System.git
synced 2026-03-17 00:57:12 -05:00
feat: BlackRoad OS Phase 2.5 - Infrastructure Wiring Complete
Phase 2.5 wires up the infrastructure decisions and prepares BlackRoad OS for production deployment. This phase codifies architectural choices and creates deployment-ready configurations. ## Key Decisions Codified - ✅ Monorepo as canonical OS home (for Phase 1-2) - ✅ Prism Console served from backend at /prism - ✅ Documentation via GitHub Pages (MkDocs) - ✅ Vanilla JavaScript frontend maintained ## New Infrastructure ### Documentation & Planning - PHASE2_5_SUMMARY_FOR_ALEXA.md - Complete Phase 2.5 summary - BLACKROAD_OS_REPO_MAP.md - Repository structure map - DEPLOYMENT_NOTES.md - Production deployment guide ### Backend Infrastructure - backend/app/routers/prism_static.py - Prism Console static router - backend/static/prism/ - Prism Console UI skeleton - index.html, css/prism.css, js/prism-core.js ### Documentation System - .github/workflows/docs-deploy.yml - MkDocs deployment automation - codex-docs/mkdocs.yml - MkDocs + Material theme config - codex-docs/DEPLOY_DOCS.md - Docs deployment guide - codex-docs/docs/ - Complete documentation structure ### Updated Files - backend/app/main.py - Added Prism router, OpenAPI tags - MASTER_ORCHESTRATION_PLAN.md - Added Phase 2.5 section ## URL Structure (Production) - https://blackroad.systems → Main OS - https://blackroad.systems/prism → Prism Console - https://blackroad.systems/api/* → REST API - https://docs.blackroad.systems → Documentation ## Post-Merge Checklist 1. Configure GitHub Pages (5 min) 2. Configure Railway deployment (10 min) 3. Configure Cloudflare DNS (15 min) 4. Verify all routes work (5 min) 5. Monitor first deployment (10 min) See PHASE2_5_SUMMARY_FOR_ALEXA.md for complete post-merge instructions. ## Implementation Status ✅ Phase 2.5 Complete - Ready for production deployment --- Where AI meets the open road. 🛣️
This commit is contained in:
@@ -15,12 +15,13 @@ from app.routers import (
|
||||
digitalocean, github, huggingface, vscode, games, browser, dashboard,
|
||||
railway, vercel, stripe, twilio, slack, discord, sentry, api_health, agents,
|
||||
capture, identity_center, notifications_center, creator, compliance_ops,
|
||||
search, cloudflare
|
||||
search, cloudflare, prism_static
|
||||
)
|
||||
from app.services.crypto import rotate_plaintext_wallet_keys
|
||||
|
||||
|
||||
openapi_tags = [
|
||||
{"name": "prism", "description": "Prism Console - Administrative interface for job queue, events, and metrics"},
|
||||
{"name": "railway", "description": "Railway deployment management"},
|
||||
{"name": "vercel", "description": "Vercel project automation"},
|
||||
{"name": "stripe", "description": "Stripe billing integrations"},
|
||||
@@ -155,6 +156,9 @@ app.include_router(api_health.router)
|
||||
# Agent Library
|
||||
app.include_router(agents.router)
|
||||
|
||||
# Prism Console (must be before StaticFiles mount to take precedence)
|
||||
app.include_router(prism_static.router)
|
||||
|
||||
|
||||
# Static file serving for the BlackRoad OS front-end
|
||||
static_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "static")
|
||||
|
||||
92
backend/app/routers/prism_static.py
Normal file
92
backend/app/routers/prism_static.py
Normal file
@@ -0,0 +1,92 @@
|
||||
"""Prism Console Static File Serving Router"""
|
||||
from fastapi import APIRouter
|
||||
from fastapi.responses import FileResponse, HTMLResponse
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
router = APIRouter(tags=["prism"])
|
||||
|
||||
# Get the static prism directory path
|
||||
STATIC_DIR = Path(__file__).parent.parent.parent / "static"
|
||||
PRISM_DIR = STATIC_DIR / "prism"
|
||||
|
||||
|
||||
@router.get("/prism", response_class=HTMLResponse)
|
||||
async def serve_prism_console():
|
||||
"""
|
||||
Serve the Prism Console UI entry point
|
||||
|
||||
Prism Console is the administrative interface for BlackRoad OS,
|
||||
providing job queue management, event logging, and system metrics.
|
||||
"""
|
||||
prism_index = PRISM_DIR / "index.html"
|
||||
|
||||
if not prism_index.exists():
|
||||
# Fallback: serve a placeholder page
|
||||
return HTMLResponse(content="""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Prism Console - Coming Soon</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Courier New', monospace;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
.container {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 10px;
|
||||
}
|
||||
h1 { font-size: 3rem; margin: 0; }
|
||||
p { font-size: 1.2rem; margin: 1rem 0; }
|
||||
.logo { font-size: 5rem; margin-bottom: 1rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="logo">🌌</div>
|
||||
<h1>Prism Console</h1>
|
||||
<p>The Administrative Interface for BlackRoad OS</p>
|
||||
<p><em>Coming soon in Phase 2...</em></p>
|
||||
<p><a href="/" style="color: white;">← Back to OS</a></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
""", status_code=200)
|
||||
|
||||
# Serve the actual Prism Console index.html
|
||||
return FileResponse(prism_index)
|
||||
|
||||
|
||||
@router.get("/prism/{file_path:path}")
|
||||
async def serve_prism_static_files(file_path: str):
|
||||
"""
|
||||
Serve static files for Prism Console (JS, CSS, images, etc.)
|
||||
|
||||
This endpoint handles all asset requests for the Prism Console UI.
|
||||
"""
|
||||
# Security: Prevent directory traversal
|
||||
safe_path = Path(file_path).resolve()
|
||||
requested_file = PRISM_DIR / file_path
|
||||
|
||||
# Ensure the requested file is within the prism directory
|
||||
try:
|
||||
resolved = requested_file.resolve()
|
||||
if not str(resolved).startswith(str(PRISM_DIR.resolve())):
|
||||
return HTMLResponse(content="Access denied", status_code=403)
|
||||
except Exception:
|
||||
return HTMLResponse(content="File not found", status_code=404)
|
||||
|
||||
if not requested_file.exists() or not requested_file.is_file():
|
||||
return HTMLResponse(content="File not found", status_code=404)
|
||||
|
||||
# Serve the file with appropriate MIME type
|
||||
return FileResponse(requested_file)
|
||||
Reference in New Issue
Block a user