feat(service): P2.1 messaging tables — IiosMessageReceipt + IiosUnreadCounter

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 01:04:26 +05:30
parent 072c541e09
commit 7197157058
2 changed files with 91 additions and 3 deletions
+47 -3
View File
@@ -66,6 +66,15 @@ enum IiosDeliveryState {
REDACTED
}
enum IiosReceiptKind {
DELIVERED
READ
ACKED
FAILED
SUPPRESSED
RATE_LIMITED
}
// ─── Kernel tables ────────────────────────────────────────────────
/// Frozen six-vector scope. orgId + appId are REQUIRED (no global-by-null).
@@ -124,6 +133,8 @@ model IiosActorRef {
threadsCreated IiosThread[] @relation("ThreadCreatedBy")
participations IiosThreadParticipant[]
interactions IiosInteraction[]
receipts IiosMessageReceipt[]
unreadCounters IiosUnreadCounter[]
}
/// A configured channel surface (PORTAL in P1).
@@ -163,8 +174,9 @@ model IiosThread {
updatedAt DateTime @updatedAt
metadata Json?
participants IiosThreadParticipant[]
interactions IiosInteraction[]
participants IiosThreadParticipant[]
interactions IiosInteraction[]
unreadCounters IiosUnreadCounter[]
@@index([scopeId, status])
}
@@ -207,7 +219,8 @@ model IiosInteraction {
traceId String?
metadata Json?
parts IiosMessagePart[]
parts IiosMessagePart[]
receipts IiosMessageReceipt[]
@@unique([scopeId, idempotencyKey])
@@index([threadId, occurredAt])
@@ -255,3 +268,34 @@ model IiosProcessedEvent {
@@id([consumerName, eventId])
}
// ─── P2: messaging — receipts & unread ────────────────────────────
/// Delivery/read receipt for a message interaction, per actor.
model IiosMessageReceipt {
id String @id @default(cuid())
interactionId String
interaction IiosInteraction @relation(fields: [interactionId], references: [id], onDelete: Cascade)
actorId String?
actor IiosActorRef? @relation(fields: [actorId], references: [id])
receiptKind IiosReceiptKind
occurredAt DateTime @default(now())
providerReceiptRef String?
metadata Json?
@@unique([interactionId, actorId, receiptKind])
@@index([interactionId])
}
/// Per-(thread, actor) unread count + last-read marker.
model IiosUnreadCounter {
threadId String
thread IiosThread @relation(fields: [threadId], references: [id], onDelete: Cascade)
actorId String
actor IiosActorRef @relation(fields: [actorId], references: [id])
unreadCount Int @default(0)
lastReadInteractionId String?
updatedAt DateTime @updatedAt
@@id([threadId, actorId])
}