Platform bundle: marketing publish, IT ops, packaging, agents mesh.

Volledige Foodlinkk Command Center uitbreiding met social automatisering,
reclamefolder filters, Proxmox monitoring en documentatie.
This commit is contained in:
Aissa
2026-06-09 00:41:27 +00:00
commit 5d60d33db1
212 changed files with 30044 additions and 0 deletions
+134
View File
@@ -0,0 +1,134 @@
import asyncio
import json
from pathlib import Path
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from app.db import close_pool, fetch_all, init_pool
from app.routes import (
retail,
agents,
analytics,
documents,
api,
clients,
dashboard,
deals,
herman,
studio,
marketing,
monitor,
products,
reports,
suppliers,
voice,
settings,
browser,
hermes,
beurs,
packaging,
ops,
ops_api,
)
from app.routes.admin_api import admin_router, ai_router, herman_api, voice_api
from app.routes.settings_api import settings_router
from app.routes.agents_api import router as agents_api_router
from app.routes.marketing_api import router as marketing_api_router
BASE_DIR = Path(__file__).resolve().parent.parent
templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))
app = FastAPI(title="Foodlinkk Command Center", version="2.5.0")
app.mount("/static", StaticFiles(directory=str(BASE_DIR / "static")), name="static")
for r in (
dashboard.router,
beurs.router,
agents.router,
marketing.router,
retail.router,
clients.router,
deals.router,
products.router,
suppliers.router,
monitor.router,
analytics.router,
documents.router,
reports.router,
voice.router,
settings.router,
browser.router,
herman.router,
studio.router,
hermes.router,
packaging.router,
ops.router,
api.router,
ops_api.router,
admin_router,
ai_router,
herman_api,
voice_api,
settings_router,
agents_api_router,
marketing_api_router,
):
app.include_router(r)
@app.on_event("startup")
def on_startup() -> None:
init_pool()
@app.on_event("shutdown")
def on_shutdown() -> None:
close_pool()
@app.websocket("/ws/agents")
async def ws_agents(websocket: WebSocket) -> None:
await websocket.accept()
last_payload: str | None = None
try:
while True:
try:
rows = fetch_all(
"""SELECT id, agent_name, event_type, title, body, status, created_at
FROM agent_events ORDER BY created_at DESC LIMIT 50"""
)
for row in rows:
if row.get("created_at") is not None:
row["created_at"] = row["created_at"].isoformat()
payload = json.dumps({"events": rows})
except Exception as exc:
payload = json.dumps({"error": str(exc), "events": []})
if payload != last_payload:
await websocket.send_text(payload)
last_payload = payload
await asyncio.sleep(3)
except WebSocketDisconnect:
return
@app.websocket("/ws/feed")
async def ws_feed(websocket: WebSocket) -> None:
await websocket.accept()
try:
while True:
snapshot = {"type": "heartbeat", "events": []}
try:
snapshot["events"] = fetch_all(
"SELECT agent_name, event_type, title, status, created_at FROM agent_events ORDER BY created_at DESC LIMIT 15"
)
for row in snapshot["events"]:
if row.get("created_at"):
row["created_at"] = row["created_at"].isoformat()
except Exception as exc:
snapshot["error"] = str(exc)
await websocket.send_text(json.dumps(snapshot))
await asyncio.sleep(5)
except WebSocketDisconnect:
return