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
67
packages/connector-runtime/src/outcome.ts
Normal file
67
packages/connector-runtime/src/outcome.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* Typed result of one publish dispatch. Only `retryable` permits calling
|
||||
* connector.publish again with the same idempotency key; `unknown` means the
|
||||
* send may have happened and must never be resent automatically.
|
||||
*/
|
||||
export type PublishFailureCode =
|
||||
| "RATE_LIMITED"
|
||||
| "PROVIDER_UNAVAILABLE"
|
||||
| "TRANSPORT_FAILURE"
|
||||
| "PUBLISH_AMBIGUOUS_DEDUPED"
|
||||
| "CREDENTIAL_REJECTED"
|
||||
| "PROVIDER_REJECTED"
|
||||
| "INVALID_POST"
|
||||
| "UNSUPPORTED"
|
||||
| "PUBLISH_OUTCOME_UNKNOWN";
|
||||
|
||||
/**
|
||||
* Sanitized provider evidence. Deliberately omits the connector's local
|
||||
* Publication.id and draftId: those are placeholders, never DB identities.
|
||||
*/
|
||||
export interface PublishReceipt {
|
||||
provider: string;
|
||||
connectionId: string;
|
||||
idempotencyKey: string;
|
||||
remoteId: string;
|
||||
remoteUrl?: string;
|
||||
publishedAt: Date;
|
||||
providerMetadata: Record<string, unknown>;
|
||||
}
|
||||
|
||||
interface FailureBase {
|
||||
code: PublishFailureCode;
|
||||
/** Whether any mutating provider request left the process in this call. */
|
||||
dispatched: boolean;
|
||||
/** SDK error class name — a fixed identifier, never the raw message. */
|
||||
errorName?: string;
|
||||
status?: number;
|
||||
}
|
||||
|
||||
export type PublishOutcome =
|
||||
| { kind: "published"; receipt: PublishReceipt }
|
||||
| {
|
||||
kind: "provider_scheduled";
|
||||
receipt: PublishReceipt;
|
||||
scheduledRemoteId: string;
|
||||
scheduledAt: Date;
|
||||
}
|
||||
| (FailureBase & {
|
||||
kind: "rejected_permanent";
|
||||
code: "CREDENTIAL_REJECTED" | "PROVIDER_REJECTED" | "INVALID_POST" | "UNSUPPORTED";
|
||||
/** Credential refused: pause for reauthorization, do not retry. */
|
||||
needsReauthorization: boolean;
|
||||
})
|
||||
| (FailureBase & {
|
||||
kind: "retryable";
|
||||
code: "RATE_LIMITED" | "PROVIDER_UNAVAILABLE" | "TRANSPORT_FAILURE" | "PUBLISH_AMBIGUOUS_DEDUPED";
|
||||
retryAfterMs?: number;
|
||||
/**
|
||||
* "not_delivered": the provider definitively did not apply the send.
|
||||
* "deduplicated": delivery is ambiguous but a same-key resend is
|
||||
* deduped by the provider inside its verified window.
|
||||
*/
|
||||
resend: "not_delivered" | "deduplicated";
|
||||
})
|
||||
| (FailureBase & { kind: "unknown"; code: "PUBLISH_OUTCOME_UNKNOWN"; dispatched: true });
|
||||
|
||||
export type PublishOutcomeKind = PublishOutcome["kind"];
|
||||
Loading…
Add table
Add a link
Reference in a new issue