feat(p9): propagate trace id into emitted events + structured relay/gateway logs

Task O.2: ai/calendar/route/ingest emit sites now stamp traceparent + insignia.
correlationId from interaction.traceId ?? currentTraceId() ?? generated (mirroring
message.send; inbox/inbound already carried correlationId). toTraceparent is hex-safe
(UUID used as-is, other ids hashed). OutboxRelay logs a structured relay.publish per
event (eventType/aggregateId/correlationId); MessageGateway logs ws.deliver. Tests:
an event's correlationId equals the active request trace, with a generated fallback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-03 01:04:24 +05:30
parent 0f923303d3
commit 1d3e18f417
8 changed files with 78 additions and 5 deletions
@@ -11,6 +11,7 @@ import {
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { IIOS_EVENTS } from '@insignia/iios-contracts';
import { logJson } from '../observability/logger';
import { MessageService, type MessagePrincipal } from './message.service';
import { SessionVerifier } from '../platform/session.verifier';
import { OutboxBus } from '../outbox/outbox.bus';
@@ -45,8 +46,10 @@ export class MessageGateway implements OnGatewayInit, OnGatewayConnection {
const threadId = ce?.data?.threadId;
if (!interactionId || !threadId) return;
if (this.emittedLocally.delete(interactionId)) return; // already emitted inline
const correlationId = (payload as { insignia?: { correlationId?: string } })?.insignia?.correlationId;
void this.messages.getMessageById(interactionId).then((m) => {
if (m) this.server.to(threadId).emit('message', m);
logJson('info', 'ws.deliver', { interactionId, threadId, correlationId });
});
});
}