forked from UKSOURCE/cms.lams
feat: add programme module and blog integration
- Add Programme Mongoose model with sub-schemas and migrateFromJson static method - Add programme CRUD controller with audit logging and icon sanitization - Add programme admin views (index, edit) with tabbed form and dynamic arrays - Add seed migration script for programmes - Add /api/programmes and /api/programmes/:id public API endpoints - Register programme routes in admin and public router - Update dashboard with Programmes card and API endpoint entries - Update admin sidebar layout to include Programmes nav link
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
const mongoose = require("mongoose");
|
||||
|
||||
const courseSchema = new mongoose.Schema(
|
||||
{
|
||||
id: { type: String, default: "" },
|
||||
title: { type: String, default: "" },
|
||||
description: { type: String, default: "" },
|
||||
icon: { type: String, default: "" },
|
||||
},
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
const outcomeSchema = new mongoose.Schema(
|
||||
{
|
||||
title: { type: String, default: "" },
|
||||
description: { type: String, default: "" },
|
||||
icon: { type: String, default: "" },
|
||||
},
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
const faqSchema = new mongoose.Schema(
|
||||
{
|
||||
question: { type: String, default: "" },
|
||||
answer: { type: String, default: "" },
|
||||
},
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
const programmeSchema = new mongoose.Schema(
|
||||
{
|
||||
id: { type: String, required: true, unique: true, trim: true },
|
||||
level: { type: String, default: "" },
|
||||
title: { type: String, default: "" },
|
||||
description: { type: String, default: "" },
|
||||
duration: { type: String, default: "" },
|
||||
cost: { type: String, default: "" },
|
||||
selected: { type: Boolean, default: false },
|
||||
link: { type: String, default: "" },
|
||||
shortName: { type: String, default: "" },
|
||||
detailBadge: { type: String, default: "" },
|
||||
detailTitle: { type: String, default: "" },
|
||||
detailDescription: { type: String, default: "" },
|
||||
heroImage: { type: String, default: "" },
|
||||
overview: { type: String, default: "" },
|
||||
credits: { type: Number, default: 0 },
|
||||
format: { type: String, default: "100% Online" },
|
||||
nextStartDate: { type: String, default: "" },
|
||||
monthlyCost: { type: String, default: "" },
|
||||
perCourseCost: { type: String, default: "" },
|
||||
coreCourses: { type: [courseSchema], default: [] },
|
||||
electives: { type: [String], default: [] },
|
||||
outcomes: { type: [outcomeSchema], default: [] },
|
||||
faqs: { type: [faqSchema], default: [] },
|
||||
},
|
||||
{ timestamps: true }
|
||||
);
|
||||
|
||||
/**
|
||||
* Upsert from a JSON array. Used by migration scripts.
|
||||
*/
|
||||
programmeSchema.statics.migrateFromJson = async function (jsonArray) {
|
||||
const results = [];
|
||||
for (const item of jsonArray) {
|
||||
const existing = await this.findOne({ id: item.id });
|
||||
if (existing) {
|
||||
existing.set(item);
|
||||
await existing.save();
|
||||
results.push({ action: "updated", id: item.id });
|
||||
} else {
|
||||
await this.create(item);
|
||||
results.push({ action: "created", id: item.id });
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
module.exports = mongoose.model("Programme", programmeSchema);
|
||||
Reference in New Issue
Block a user