import { Channels } from "../Common/index"; import { UserInfo } from "../Users/UserTrii"; import { ConversationAssignmentSnapshot, ConversationCapabilitiesDto, ConversationStatus, ConversationUserRelationDto } from "./Conversation"; import { ILabel } from "./Label"; export interface Post { id: string; spaceId: string; externalId: string; title: string; details: string; imageUrl: string; photos: string[]; videos: string[]; reactions: string[]; channelInfo: Channels.IChannelInfo; newMessagesCount: number; postUrl?: string; counters: PostStats; participants: UserInfo[]; archived: boolean; assignment: ConversationAssignmentSnapshot; /** Concurrencia optimista + idempotencia de comandos, igual que Conversation.version. */ version: number; createdAt: Date; updatedAt: Date; } export interface PostStats { likes: number; comments: number; } export interface WallMessage { id: string; spaceId: string; postId: string; parentId: string; readed: boolean; externalUserSender?: ExternalUserInfo; contactId?: string; contactAddressId?: string; userSender?: string; message?: string; imageUrl?: string; videoUrl?: string; reactions?: WallReaction; responses?: WallMessage[]; createdAt: Date; updatedAt: Date; } export interface WallReaction { like: number; likeUsers: ExternalUserInfo[]; love: number; loveUsers: ExternalUserInfo[]; haha: number; hahaUsers: ExternalUserInfo[]; wow: number; wowUsers: ExternalUserInfo[]; sad: number; sadUsers: ExternalUserInfo[]; angry: number; angryUsers: ExternalUserInfo[]; } export interface Response { id: string; external_parent_id: string; externalUserSender?: ExternalUserInfo; userSender?: UserInfo; message: string; response?: Response[]; createdAt: Date; updatedAt: Date; } export interface ExternalUserInfo { id: string; name: string; imageUrl: string; } /** * Estado de una interaccion wall (post/comment/mention), equivalente a lo que para una * conversacion vive directo en IConversation. Post no tiene estos campos persistidos (no hay * assignment/sla reales para posts todavia), asi que este objeto se arma al vuelo del lado del * backend a partir de UserInboxItemDocument.snapshot (owner/status/queueId/unreadCount) y del * propio Post (participants/channelInfo/fechas). */ export interface WallInteractionState { id: string; spaceId: string; status: ConversationStatus; priority: 'low' | 'normal' | 'high' | 'urgent'; assignment: ConversationAssignmentSnapshot; sla: { status: 'none' | 'running' | 'warning' | 'breached' | 'met'; deadlineAt?: Date; policyId?: string; version: number; }; labels: ILabel[]; participants: UserInfo[]; channelInfo: Channels.IChannelInfo; unreadCount: number; lastActivityAt: Date; createdAt: Date; updatedAt: Date; finalizedAt?: Date; } /** * DTO API - GET /Walls/{postId}/detail. Rama "wall" del sobre que en conversaciones da * ConversationDetailResponse. interactionKind viaja igual (wall_post/comment/mention) aunque el * front ya sepa que pego en el endpoint de walls, por si quiere distinguir el motivo de la fila. */ export interface WallPostDetailResponse { interactionKind: 'wall_post' | 'comment' | 'mention'; post: Post; interaction: WallInteractionState; /** Comentario que origino la interaccion (comment/mention). Ausente para wall_post o cuando * todavia no se implementa el tracking de comentario puntual (P1, ver discusion). */ focusCommentId?: string; relation: ConversationUserRelationDto; capabilities: ConversationCapabilitiesDto; availableActions: string[]; } /** * DTO API - GET /inbox/items/{id}. Resuelve deep-link (F5, link compartido) sin tener el snapshot * del listado: solo dice de que tipo es el id para que el front pegue en * /Conversations/{id}/detail o en /Walls/{postId}/detail segun corresponda. */ export interface InboxItemKindDto { id: string; interactionKind: 'private' | 'wall_post' | 'comment' | 'mention'; }