rspace-online/modules/network/mod.ts

65 lines
2.0 KiB
TypeScript

/**
* Network module — community relationship graph viewer.
*
* Visualizes CRM data as interactive force-directed graphs.
* Nodes: people, companies, opportunities. Edges: relationships.
* Syncs from Twenty CRM via API proxy.
*/
import { Hono } from "hono";
import { renderShell } from "../../server/shell";
import { getModuleInfoList } from "../../shared/module";
import type { RSpaceModule } from "../../shared/module";
const routes = new Hono();
// No database — network data lives in Automerge CRDT docs or is proxied from Twenty CRM.
// The existing rNetwork-online at /opt/apps/rNetwork-online/ already uses Bun+Hono+Automerge.
// ── API: Health ──
routes.get("/api/health", (c) => {
return c.json({ ok: true, module: "network", sync: true });
});
// ── API: Graph info (placeholder — real data from Automerge) ──
routes.get("/api/info", (c) => {
return c.json({
module: "network",
description: "Community relationship graph visualization",
entityTypes: ["person", "company", "opportunity"],
features: ["force-directed layout", "CRM sync", "real-time collaboration"],
});
});
// ── API: Workspaces ──
routes.get("/api/workspaces", (c) => {
// In production, this would scan Automerge graph docs
return c.json([
{ slug: "demo", name: "Demo Network", nodeCount: 0, edgeCount: 0 },
]);
});
// ── Page route ──
routes.get("/", (c) => {
const space = c.req.param("space") || "demo";
return c.html(renderShell({
title: `${space} — Network | rSpace`,
moduleId: "network",
spaceSlug: space,
modules: getModuleInfoList(),
theme: "light",
styles: `<link rel="stylesheet" href="/modules/network/network.css">`,
body: `<folk-graph-viewer space="${space}"></folk-graph-viewer>`,
scripts: `<script type="module" src="/modules/network/folk-graph-viewer.js"></script>`,
}));
});
export const networkModule: RSpaceModule = {
id: "network",
name: "rNetwork",
icon: "\u{1F310}",
description: "Community relationship graph visualization with CRM sync",
routes,
standaloneDomain: "rnetwork.online",
};