feat(service): P2.3 Socket.io /message gateway + real SessionVerifier
open_thread (create-or-join) / send_message / read / delivered / typing; HS256 token verified on connect (SessionVerifier reuses AppTokenVerifier pattern); OutboxBus bridge propagates REST/ingest messages to rooms (dedup vs inline emit). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -183,6 +183,31 @@ export class MessageService {
|
||||
return { interactionId, actorId: actor.id };
|
||||
}
|
||||
|
||||
async markDelivered(
|
||||
threadId: string,
|
||||
principal: MessagePrincipal,
|
||||
interactionId: string,
|
||||
): Promise<{ interactionId: string; actorId: string }> {
|
||||
const thread = await this.prisma.iiosThread.findUnique({ where: { id: threadId } });
|
||||
if (!thread) throw new NotFoundException('thread not found');
|
||||
const actor = await this.resolveActor(thread.scopeId, principal);
|
||||
await this.prisma.iiosMessageReceipt.upsert({
|
||||
where: { interactionId_actorId_receiptKind: { interactionId, actorId: actor.id, receiptKind: 'DELIVERED' } },
|
||||
create: { interactionId, actorId: actor.id, receiptKind: 'DELIVERED' },
|
||||
update: { occurredAt: new Date() },
|
||||
});
|
||||
return { interactionId, actorId: actor.id };
|
||||
}
|
||||
|
||||
async getMessageById(id: string): Promise<MessageDto | null> {
|
||||
const i = await this.prisma.iiosInteraction.findUnique({
|
||||
where: { id },
|
||||
include: { parts: { orderBy: { partIndex: 'asc' } } },
|
||||
});
|
||||
if (!i || !i.threadId) return null;
|
||||
return this.toDto(i, i.threadId);
|
||||
}
|
||||
|
||||
async history(threadId: string): Promise<MessageDto[]> {
|
||||
const interactions = await this.prisma.iiosInteraction.findMany({
|
||||
where: { threadId },
|
||||
|
||||
Reference in New Issue
Block a user