Files
pagodera/lib/mongodb/models/Chat.ts
T
Evandro Fonseca Junior 7f42def478 feat(market): add Minha Intenções tab with panel, hook, and badge
- Introduced "Minhas Intenções" tab visible only to logged-in users.
- Integrated MyPurchaseIntentionsPanel and useMyPurchaseIntentions hook.
- Added tab badge showing count of pending intentions.
- Extended session API to include user’s main character for downstream features.
2025-11-07 17:25:51 -03:00

139 lines
3.3 KiB
TypeScript

/**
* Model Chat - Representa uma conversa entre comprador e vendedor
*/
import mongoose, { Schema, model, models } from "mongoose";
export interface IChat {
chat_id: string; // ID único: `${listing_id}_${buyer_id}_${seller_id}`
listing_id: number; // ID do anúncio (PostgreSQL)
buyer_id: number; // ID do comprador (PostgreSQL)
seller_id: number; // ID do vendedor (PostgreSQL)
created_at: Date;
updated_at: Date;
last_message_at: Date | null;
last_message_preview: string | null;
buyer_unread_count: number;
seller_unread_count: number;
is_active: boolean; // Chat ativo (anúncio ainda disponível)
// Dados cached do anúncio (para performance)
listing_cache: {
item_name: string;
item_image_url?: string;
price_pix?: number;
price_tibia_coins?: number;
price_gold_coins?: number;
server_name: string;
listing_status: string;
};
// Dados cached dos usuários
buyer_cache: {
user_id: number;
username: string;
character_name?: string;
};
seller_cache: {
user_id: number;
username: string;
character_name?: string;
};
}
const ChatSchema = new Schema<IChat>(
{
chat_id: {
type: String,
required: true,
unique: true,
index: true,
},
listing_id: {
type: Number,
required: true,
index: true,
},
buyer_id: {
type: Number,
required: true,
index: true,
},
seller_id: {
type: Number,
required: true,
index: true,
},
created_at: {
type: Date,
default: Date.now,
index: true,
},
updated_at: {
type: Date,
default: Date.now,
},
last_message_at: {
type: Date,
default: null,
index: true,
},
last_message_preview: {
type: String,
default: null,
maxlength: 100,
},
buyer_unread_count: {
type: Number,
default: 0,
},
seller_unread_count: {
type: Number,
default: 0,
},
is_active: {
type: Boolean,
default: true,
index: true,
},
listing_cache: {
item_name: { type: String, required: true },
item_image_url: { type: String, default: null },
price_pix: { type: Number, default: null },
price_tibia_coins: { type: Number, default: null },
price_gold_coins: { type: Number, default: null },
server_name: { type: String, required: true },
listing_status: { type: String, required: true },
},
buyer_cache: {
user_id: { type: Number, required: true },
username: { type: String, required: true },
character_name: { type: String, default: null },
},
seller_cache: {
user_id: { type: Number, required: true },
username: { type: String, required: true },
character_name: { type: String, default: null },
},
},
{
timestamps: false, // Usamos campos manuais
collection: "chats",
}
);
// Índices compostos para queries eficientes
ChatSchema.index({ buyer_id: 1, updated_at: -1 });
ChatSchema.index({ seller_id: 1, updated_at: -1 });
ChatSchema.index({ listing_id: 1, buyer_id: 1, seller_id: 1 });
// Atualizar updated_at antes de salvar
ChatSchema.pre("save", function (next) {
this.updated_at = new Date();
next();
});
export const Chat = models.Chat || model<IChat>("Chat", ChatSchema);