Tactical Media Broadcast Hub — initial release

Self-hosted multi-platform broadcast newsroom for activist collectives:
publishing pipeline with group approval and DST-proof scheduling, TweetDeck-style
column wall with hostile-content-safe rendering, live control room with Auto
Director, bridged chat governance with polls and quorum, distributed sandboxed
transcode workers, encrypted content-addressed archive, monthly analytics.

MIT licensed. See README.md and docs/.
This commit is contained in:
glass beadian 2026-10-10 11:56:42 +00:00
commit aa5e262f3a
880 changed files with 111042 additions and 0 deletions

View file

@ -0,0 +1,57 @@
import { Controller, Get, Post, Body, Req, UseGuards } from "@nestjs/common";
import { RbacGuard, RequirePermission, type AuthenticatedRequest } from "../rbac/rbac.guard.js";
import { appendTenantAudit } from "../audit/audit.service.js";
import { withTenant } from "../db/client.js";
import type { Request } from "express";
@Controller("demo")
@UseGuards(RbacGuard)
export class DemoController {
@Get("health-audit")
@RequirePermission("audit.view")
async viewAudit(@Req() req: Request & AuthenticatedRequest): Promise<{ workspaceId: string }> {
return { workspaceId: req.session?.workspaceId ?? "none" };
}
@Post("connections")
@RequirePermission("connection.manage")
async addConnection(
@Req() req: Request & AuthenticatedRequest,
@Body() body: { provider: string; channelId: string },
): Promise<{ id: string }> {
const session = req.session;
if (session === undefined) throw new Error("unreachable: guard sets session");
const workspaceId = session.workspaceId;
return withTenant(workspaceId, async (client) => {
const inserted = await client.query(
"INSERT INTO connections (workspace_id, provider, channel_id) VALUES ($1, $2, $3) RETURNING id",
[workspaceId, body.provider, body.channelId],
);
const id = inserted.rows[0]?.id as string;
await client.query("SELECT audit_append($1, $2, $3, 'connection.created', 'connection', $4, $5)", [
workspaceId,
session.userId,
session.role,
id,
JSON.stringify({ provider: body.provider }),
]);
return { id };
});
}
@Post("echo-audited")
@RequirePermission("workspace.view")
async echoAudited(@Req() req: Request & AuthenticatedRequest, @Body() body: { apiKey?: string; note?: string }): Promise<{ ok: true }> {
const session = req.session;
if (session === undefined) throw new Error("unreachable: guard sets session");
await appendTenantAudit(session.workspaceId, {
actorUserId: session.userId,
actorRole: session.role,
action: "demo.echo",
targetType: "demo",
targetId: "echo",
diff: { apiKey: body.apiKey ?? null, note: body.note ?? null },
});
return { ok: true };
}
}