// src/models/user.ts // Copyright (C) 2025 DTP Technologies, LLC // All Rights Reserved import { Types, Schema, Document, model } from "mongoose"; export interface IUserFlags { isAdmin: boolean; isTest: boolean; isBanned: boolean; } export const UserFlagsSchema = new Schema( { isAdmin: { type: Boolean, default: false, required: true }, isTest: { type: Boolean, default: false, required: true }, isBanned: { type: Boolean, default: false, required: true }, }, { _id: false }, ); export interface IAiConfig { providerIds: Types.ObjectId[]; agentProviderId: Types.ObjectId | null; agentModel: string; vectorProviderId: Types.ObjectId | null; vectorModel: string; utilityProviderId: Types.ObjectId | null; utilityModel: string; } export interface IGabConnection { social: { apiToken: string; }; ai: { apiToken: string; }; } export interface IGoogleCseConnection { apiKey: string; engineId: string; } export interface IUserServiceConnections { gab: IGabConnection; ai: IAiConfig; google?: { cse?: IGoogleCseConnection; }; } export interface IUser extends Document { _id: Types.ObjectId; username: string; username_lc: string; passwordSalt?: string; password?: string; displayName: string; flags: IUserFlags; connections: IUserServiceConnections; projectsDirectory?: string; } export const AiConfigSchema = new Schema( { providerIds: { type: [Schema.Types.ObjectId], ref: "AiProvider", default: [], }, agentProviderId: { type: Schema.Types.ObjectId, ref: "AiProvider", default: null, }, agentModel: { type: String, default: "" }, vectorProviderId: { type: Schema.Types.ObjectId, ref: "AiProvider", default: null, }, vectorModel: { type: String, default: "" }, utilityProviderId: { type: Schema.Types.ObjectId, ref: "AiProvider", default: null, }, utilityModel: { type: String, default: "" }, }, { _id: false }, ); const GabConnectionSchema = new Schema( { social: { apiToken: { type: String, select: false }, }, ai: { apiToken: { type: String, select: false }, }, }, { _id: false }, ); const GoogleCseConnectionSchema = new Schema( { apiKey: { type: String, select: false }, engineId: { type: String, select: false }, }, { _id: false }, ); const UserConnectionsSchema = new Schema( { gab: { type: GabConnectionSchema, default: {} }, ai: { type: AiConfigSchema, default: {} }, google: { cse: { type: GoogleCseConnectionSchema, default: null }, }, }, { _id: false }, ); export const UserSchema = new Schema({ username: { type: String, required: true, minlength: 3, maxlength: 12, }, username_lc: { type: String, required: true, lowercase: true, unique: true, minlength: 3, maxlength: 12, }, passwordSalt: { type: String, required: true, select: false }, password: { type: String, required: true, select: false }, displayName: { type: String, minlength: 3, maxlength: 30, required: true }, flags: { type: UserFlagsSchema, required: true }, connections: { type: UserConnectionsSchema, default: {} }, projectsDirectory: { type: String, default: null }, }); UserSchema.index( { username: "text", displayName: "text", }, { weights: { username: 10, displayName: 5, }, }, ); export const User = model("User", UserSchema); export default User; // Note: Index synchronization is now handled during application startup // to ensure the database connection is established first. // See src/lib/db.ts for the syncDatabaseIndexes function.