138 lines
3.3 KiB
TypeScript
138 lines
3.3 KiB
TypeScript
/**
|
|
* Model Chat - Representa uma conversa entre comprador e vendedor
|
|
*/
|
|
|
|
import { model, models, Schema } 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);
|