import { Schema, model, Document, Types } from "mongoose"; export interface IRevision { content: string; author: Types.ObjectId; message: string; createdAt: Date; } export interface IComment { author: Types.ObjectId; content: string; parentComment?: Types.ObjectId; createdAt: Date; updatedAt: Date; resolved: boolean; } export interface IArticle extends Document { slug: string; title: string; description: string; content: string; // Current content in markdown category: string; tags: string[]; // Access control accessLevel: "public" | "member" | "cohort" | "admin"; cohorts?: string[]; // Specific cohorts if accessLevel is 'cohort' // Metadata author: Types.ObjectId; contributors: Types.ObjectId[]; views: number; likes: number; // Editing status: "draft" | "published" | "archived"; lockedBy?: Types.ObjectId; // If someone is currently editing lockedAt?: Date; // History revisions: IRevision[]; comments: IComment[]; // Timestamps createdAt: Date; updatedAt: Date; publishedAt?: Date; } const revisionSchema = new Schema({ content: { type: String, required: true }, author: { type: Schema.Types.ObjectId, ref: "User", required: true }, message: { type: String, required: true }, createdAt: { type: Date, default: Date.now }, }); const commentSchema = new Schema( { author: { type: Schema.Types.ObjectId, ref: "User", required: true }, content: { type: String, required: true }, parentComment: { type: Schema.Types.ObjectId, ref: "Comment" }, resolved: { type: Boolean, default: false }, }, { timestamps: true, }, ); const articleSchema = new Schema( { slug: { type: String, required: true, unique: true }, title: { type: String, required: true }, description: { type: String, required: true }, content: { type: String, required: true }, category: { type: String, required: true }, tags: [{ type: String }], accessLevel: { type: String, enum: ["public", "member", "cohort", "admin"], default: "public", }, cohorts: [{ type: String }], author: { type: Schema.Types.ObjectId, ref: "User", required: true }, contributors: [{ type: Schema.Types.ObjectId, ref: "User" }], views: { type: Number, default: 0 }, likes: { type: Number, default: 0 }, status: { type: String, enum: ["draft", "published", "archived"], default: "draft", }, lockedBy: { type: Schema.Types.ObjectId, ref: "User" }, lockedAt: Date, revisions: [revisionSchema], comments: [commentSchema], publishedAt: Date, }, { timestamps: true, }, ); // Indexes for better query performance articleSchema.index({ slug: 1 }); articleSchema.index({ accessLevel: 1, status: 1 }); articleSchema.index({ tags: 1 }); articleSchema.index({ category: 1 }); articleSchema.index({ author: 1 }); export const Article = model("Article", articleSchema);