Eventbuzz_Concierge/src/models/WebChatSession.js

67 lines
2.7 KiB
JavaScript

const mongoose = require('mongoose');
const messageSchema = new mongoose.Schema(
{
role: { type: String, enum: ['user', 'assistant'], required: true },
text: { type: String, required: true },
ts: { type: Date, default: Date.now },
modelId: { type: String, default: null },
inputTokens: { type: Number, default: 0 },
outputTokens: { type: Number, default: 0 },
/** Client-facing id for assistant replies (feedback). */
msgId: { type: String, default: null },
/** Thumb feedback: true = satisfied, false = not satisfied. */
satisfied: { type: Boolean, default: null },
feedbackAt: { type: Date, default: null },
},
{ _id: false },
);
const webChatSessionSchema = new mongoose.Schema(
{
botId: { type: mongoose.Schema.Types.ObjectId, ref: 'ConciergeBot', required: true, index: true },
eventId: { type: mongoose.Schema.Types.ObjectId, ref: 'Event' },
organization: { type: mongoose.Schema.Types.ObjectId, ref: 'Organization' },
sessionId: { type: String, required: true, trim: true, index: true },
history: { type: [messageSchema], default: [] },
lastIntent: { type: String, default: null },
lastSeenAt: { type: Date, default: Date.now },
endedAt: { type: Date, default: null },
inputTokensTotal: { type: Number, default: 0 },
outputTokensTotal: { type: Number, default: 0 },
// Identity / OTP
participant: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Participant',
default: null,
index: true,
},
identityVerifiedAt: { type: Date, default: null },
identityMethod: { type: String, default: null },
authState: {
type: String,
enum: ['awaiting_email', 'awaiting_otp'],
default: undefined,
},
authEmail: { type: String, trim: true, lowercase: true, default: null },
otpHash: { type: String, default: null },
otpExpiresAt: { type: Date, default: null },
pendingIntent: { type: String, default: null },
pendingMessage: { type: String, default: null },
pendingEntities: { type: mongoose.Schema.Types.Mixed, default: null },
/** Last session ids shown as cards — used to resolve "add it" / "yes". */
lastSessionIds: { type: [String], default: [] },
/** Rate-limit ticket QR emails from this chat session. */
lastTicketEmailAt: { type: Date, default: null },
/** Rate-limit organizer escalation emails from this chat session. */
lastEscalationEmailAt: { type: Date, default: null },
},
{ timestamps: true, collection: 'webchatsessions' },
);
webChatSessionSchema.index({ botId: 1, sessionId: 1 }, { unique: true });
module.exports =
mongoose.models.WebChatSession || mongoose.model('WebChatSession', webChatSessionSchema);