refactor(federation): generalize outbox function params and add friend relay helpers

Rename appendMutationLog and queueOutboxEvent params from DM-specific names
(dmMessageId/dmChannelId/messageId) to generic (entityId/contextId) with a new
contextType param defaulting to 'dm'. Update all internal schema column references
to match the renamed outbox/mutation-log schema columns. Add buildFriendContextId
and getFriendEventTargets helper functions for friend event relay routing.
This commit is contained in:
Jannis Braun
2026-03-27 00:43:51 +01:00
parent 917827536e
commit fe3d8b06d8
+44 -10
View File
@@ -77,10 +77,11 @@ export function getRelayTtlDays(): number {
* Failures are logged but never propagate — federation must not break DM flow. * Failures are logged but never propagate — federation must not break DM flow.
*/ */
export function appendMutationLog( export function appendMutationLog(
dmMessageId: string, entityId: string,
dmChannelId: string, contextId: string,
mutationType: string, mutationType: string,
payload?: string, payload?: string,
contextType: string = 'dm',
): void { ): void {
try { try {
if (!isFederationRelayEnabled()) { if (!isFederationRelayEnabled()) {
@@ -91,8 +92,9 @@ export function appendMutationLog(
db.insert(schema.federationMutationLog) db.insert(schema.federationMutationLog)
.values({ .values({
id: generateSnowflake(), id: generateSnowflake(),
dmMessageId, entityId,
dmChannelId, contextId,
contextType,
mutationType, mutationType,
mutatedAt: Date.now(), mutatedAt: Date.now(),
payload: payload ?? null, payload: payload ?? null,
@@ -117,11 +119,12 @@ export function appendMutationLog(
* Failures are logged but never propagate — federation must not break DM flow. * Failures are logged but never propagate — federation must not break DM flow.
*/ */
export function queueOutboxEvent( export function queueOutboxEvent(
messageId: string, entityId: string,
dmChannelId: string, contextId: string,
eventType: string, eventType: string,
payload: string, payload: string,
targetPeerOrigins?: string[], targetPeerOrigins?: string[],
contextType: string = 'dm',
): void { ): void {
try { try {
if (!isFederationRelayEnabled()) { if (!isFederationRelayEnabled()) {
@@ -161,13 +164,13 @@ export function queueOutboxEvent(
.where( .where(
and( and(
eq(schema.federationOutbox.peerId, peer.id), eq(schema.federationOutbox.peerId, peer.id),
eq(schema.federationOutbox.messageId, messageId), eq(schema.federationOutbox.entityId, entityId),
), ),
) )
.get(); .get();
if (eventType === 'delete' && existing?.eventType === 'create') { if (eventType === 'delete' && existing?.eventType === 'create') {
// Message created and deleted before relay — net effect is nothing // Entity created and deleted before relay — net effect is nothing
tx.delete(schema.federationOutbox) tx.delete(schema.federationOutbox)
.where(eq(schema.federationOutbox.id, existing.id)) .where(eq(schema.federationOutbox.id, existing.id))
.run(); .run();
@@ -191,8 +194,9 @@ export function queueOutboxEvent(
.values({ .values({
id: generateSnowflake(), id: generateSnowflake(),
peerId: peer.id, peerId: peer.id,
dmChannelId, contextId,
messageId, entityId,
contextType,
eventType, eventType,
payload, payload,
encryptionVersion: 0, encryptionVersion: 0,
@@ -337,6 +341,36 @@ export function queueDmRelay(
}), targetOrigins); }), targetOrigins);
} }
/**
* Compute a deterministic context ID for friend events between two users.
* Sorts home user IDs so the context is the same regardless of who initiates.
*/
export function buildFriendContextId(homeUserIdA: string, homeUserIdB: string): string {
const sorted = [homeUserIdA, homeUserIdB].sort();
return `friend:${sorted[0]}:${sorted[1]}`;
}
/**
* Determine which peer instance origins need to receive a friend event.
* Returns an empty array if both users are local (no relay needed).
*/
export function getFriendEventTargets(
fromHomeInstance: string | null | undefined,
toHomeInstance: string | null | undefined,
): string[] {
const ourOrigin = getOurOrigin();
const targets = new Set<string>();
if (fromHomeInstance && fromHomeInstance !== ourOrigin) {
targets.add(fromHomeInstance);
}
if (toHomeInstance && toHomeInstance !== ourOrigin) {
targets.add(toHomeInstance);
}
return Array.from(targets);
}
/** /**
* Build the relay payload object for a DM message. * Build the relay payload object for a DM message.
* Used internally by queueDmRelay and the sync endpoint. * Used internally by queueDmRelay and the sync endpoint.