Files
retoor 3c4334cec9 feat: implement MoloApp plans 01-15 with integration
Full C++23 framework tree: runtime, observability, security,
data, app, realtime, supervisor, clients, CLI, example plus
enterprise tenancy, audit, operability, governance,
supplychain. Postgres via docker compose for tests.
2026-10-23 18:20:04 +02:00

94 lines
3.8 KiB
C++

#include "App.hpp"
#include "../fw/Data.hpp"
#include "../fw/Router.hpp"
#include "../fw/Validate.hpp"
namespace molo::example::app {
// Realtime demos answer over plain HTTP in the skeleton: the WebSocket and
// Socket.IO endpoints describe the upgrade contract and echo posted frames,
// SSE streams real event text. Gap: real framing, namespaces, rooms, and
// long-polling fallback in 06-realtime.md plus matching clients.
void register_realtime_demo(fw::Router& router, Services& services) {
fw::WebdavStore* webdav = services.webdav.get();
router.get("/streaming/feed", "stream", [](fw::Request req) {
(void)req;
return fw::Response(
fw::StreamingResponse({"chunk-1\n", "chunk-2\n", "chunk-3\n"}));
});
router.get("/streaming/passthrough", "passthrough", [](fw::Request req) {
std::string target = req.query_or("target", "/health");
return fw::Response(fw::StreamingResponse(
{"passthrough from " + target + "\n", "{\"status\":\"ok\"}\n"}));
});
router.get("/ws/chat", "ws", [](fw::Request req) {
std::string upgrade = req.headers.get("Upgrade");
if (upgrade == "websocket")
return fw::JsonResponse(
"{\"upgraded\":false,\"note\":\"skeleton: echo over POST\"}", 200);
return fw::JsonResponse(
"{\"protocol\":\"websocket\",\"path\":\"/ws/chat\",\"upgrade\":"
"\"send Upgrade: websocket\"}",
200);
});
router.post("/ws/chat", "ws-echo", [](fw::Request req) {
return fw::JsonResponse(
"{\"echo\":\"" + fw::json_escape(req.body) + "\"}", 200);
});
router.get("/socketio/rooms", "socketio", [](fw::Request req) {
(void)req;
return fw::JsonResponse(
"{\"protocol\":\"socket.io\",\"namespaces\":[\"/\"],\"rooms\":["
"\"lobby\"],\"fallback\":\"long-polling\"}",
200);
});
router.post("/socketio/rooms", "socketio-emit", [](fw::Request req) {
auto input = fw::parse_json_object_flat(req.body);
if (input.empty()) input = fw::parse_form(req.body);
std::string room = input.count("room") ? input["room"] : "lobby";
std::string event = input.count("event") ? input["event"] : "message";
return fw::JsonResponse("{\"emitted\":\"" + fw::json_escape(event) +
"\",\"room\":\"" + fw::json_escape(room) +
"\",\"ack\":true}",
200);
});
router.get("/sse/events", "sse", [](fw::Request req) {
(void)req;
return fw::Response(
fw::SseResponse({"hello", "tick", "goodbye"}));
});
router.any({fw::Method::Propfind}, "/webdav/files/", "webdav-propfind",
[webdav](fw::Request req) {
(void)req;
return fw::Response(207, webdav->propfind_xml("/files/"),
"application/xml");
});
router.any({fw::Method::Get}, "/webdav/files/{name}", "webdav-get",
[webdav](fw::Request req) -> fw::Response {
std::string content;
if (!webdav->get("/files/" + req.param_or("name", ""), content))
return fw::JsonResponse("{\"error\":\"not found\"}", 404);
return fw::TextResponse(content, 200);
});
router.any({fw::Method::Put}, "/webdav/files/{name}", "webdav-put",
[webdav](fw::Request req) {
webdav->put("/files/" + req.param_or("name", ""), req.body);
return fw::JsonResponse("{\"stored\":true}", 201);
});
router.any({fw::Method::Delete}, "/webdav/files/{name}", "webdav-delete",
[webdav](fw::Request req) {
if (!webdav->remove("/files/" + req.param_or("name", "")))
return fw::JsonResponse("{\"error\":\"not found\"}", 404);
return fw::JsonResponse("{\"deleted\":true}", 200);
});
}
} // namespace molo::example::app