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:
commit
aa5e262f3a
880 changed files with 111042 additions and 0 deletions
13
packages/publishing-execution/src/approval.ts
Normal file
13
packages/publishing-execution/src/approval.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { createHash } from "node:crypto";
|
||||
function canonical(value: unknown): unknown {
|
||||
if (Array.isArray(value)) return value.map(canonical);
|
||||
if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, item]) => [key, canonical(item)]));
|
||||
return value;
|
||||
}
|
||||
/** The target lives in providerMetadata.connectionId; execution keys are excluded. */
|
||||
export function canonicalPostHash<T extends { providerMetadata: Record<string, unknown> }>(post: T): string {
|
||||
const metadata = { ...post.providerMetadata };
|
||||
delete metadata.idempotencyKey;
|
||||
delete metadata.draftId;
|
||||
return createHash("sha256").update(JSON.stringify(canonical({ ...post, providerMetadata: metadata }))).digest("hex");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue