feat(wiki): add admin wiki management API routes

This commit is contained in:
Jennie Robinson Faber 2026-04-09 22:36:44 +01:00
parent 3797ff7925
commit e4f2efd6d0
5 changed files with 375 additions and 0 deletions

View file

@ -0,0 +1,28 @@
import * as z from 'zod'
import WikiArticle from '../../../models/wikiArticle.js'
import { connectDB } from '../../../utils/mongoose.js'
const wikiTagsSchema = z.object({
tags: z.array(z.string())
})
export default defineEventHandler(async (event) => {
await requireAdmin(event)
const body = await validateBody(event, wikiTagsSchema)
const id = getRouterParam(event, 'id')
await connectDB()
const article = await WikiArticle.findByIdAndUpdate(
id,
{ tags: body.tags },
{ new: true }
)
if (!article) {
throw createError({ statusCode: 404, statusMessage: 'Article not found' })
}
return article
})

View file

@ -0,0 +1,55 @@
import * as z from 'zod'
import WikiArticle from '../../../models/wikiArticle.js'
import { connectDB } from '../../../utils/mongoose.js'
const batchTagSchema = z.object({
articleIds: z.array(z.string()).optional(),
collection: z.string().optional(),
addTags: z.array(z.string()).optional(),
removeTags: z.array(z.string()).optional()
})
export default defineEventHandler(async (event) => {
await requireAdmin(event)
const body = await validateBody(event, batchTagSchema)
if (!body.articleIds && !body.collection) {
throw createError({
statusCode: 400,
statusMessage: 'Must provide either articleIds or collection'
})
}
if (!body.addTags?.length && !body.removeTags?.length) {
throw createError({
statusCode: 400,
statusMessage: 'Must provide at least one of addTags or removeTags'
})
}
await connectDB()
const filter = body.articleIds
? { _id: { $in: body.articleIds } }
: { collection: body.collection }
let modified = 0
if (body.addTags?.length) {
const result = await WikiArticle.updateMany(filter, {
$addToSet: { tags: { $each: body.addTags } }
})
modified = result.modifiedCount || 0
}
if (body.removeTags?.length) {
const result = await WikiArticle.updateMany(filter, {
$pull: { tags: { $in: body.removeTags } }
})
// Use the higher count if both operations ran
modified = Math.max(modified, result.modifiedCount || 0)
}
return { modified }
})

View file

@ -0,0 +1,24 @@
import WikiArticle from '../../../models/wikiArticle.js'
import { connectDB } from '../../../utils/mongoose.js'
export default defineEventHandler(async (event) => {
await requireAdmin(event)
await connectDB()
const { collection, search } = getQuery(event)
const filter = {}
if (collection) {
filter.collection = collection
}
if (search) {
filter.title = { $regex: search, $options: 'i' }
}
const articles = await WikiArticle.find(filter)
.select('collection title tags url outlineId publishedAt')
.sort({ collection: 1, title: 1 })
.lean()
return articles
})