feat(iios): @mentions via inbox fan-out + my-annotations query (pins/saves)
Mentions ride the existing event-driven inbox — no chat parsing in the kernel: - send() carries an OPAQUE mentions[] (userIds) into the message event; the kernel never parses "@". The app supplies the notify-list. - InboxProjector fans out a MENTION inbox item (new generic inbox kind) to each mentioned *participant* (never the sender), idempotent per source message; reading the thread resolves the reader's MENTION + NEEDS_REPLY items to DONE. - New MENTION value in the generic IiosInboxItemKind taxonomy (migration). Pins/saves reuse the annotation primitive; new generic query powers a Saved list: - MessageService.listMyAnnotated(principal, type) + GET /v1/threads/my-annotations returns the caller's annotated messages (type "save") with thread context. Tests: 182 pass (+4: mention fan-out, resolve-on-read, saved query, opaque mentions). Verified live: mention→inbox delivery, read→resolve, pin/save persistence. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -91,7 +91,7 @@ export class MessageGateway implements OnGatewayInit, OnGatewayConnection {
|
||||
@SubscribeMessage('send_message')
|
||||
async sendMessage(
|
||||
@ConnectedSocket() client: Socket,
|
||||
@MessageBody() body: { threadId: string; content: string; contentRef?: string; parentInteractionId?: string },
|
||||
@MessageBody() body: { threadId: string; content: string; contentRef?: string; parentInteractionId?: string; mentions?: string[] },
|
||||
) {
|
||||
const { principal } = client.data as SocketState;
|
||||
const msg = await this.messages.send(
|
||||
@@ -101,6 +101,7 @@ export class MessageGateway implements OnGatewayInit, OnGatewayConnection {
|
||||
randomUUID(),
|
||||
undefined,
|
||||
body.parentInteractionId,
|
||||
body.mentions,
|
||||
);
|
||||
this.emittedLocally.add(msg.id);
|
||||
this.server.to(body.threadId).emit('message', msg);
|
||||
|
||||
Reference in New Issue
Block a user