76 lines
No EOL
1.9 KiB
TypeScript
76 lines
No EOL
1.9 KiB
TypeScript
import { Article } from '../../models/Article'
|
|
import { checkAccessLevel } from '../../utils/auth'
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const query = getQuery(event)
|
|
|
|
// Pagination
|
|
const page = parseInt(query.page as string) || 1
|
|
const limit = parseInt(query.limit as string) || 20
|
|
const skip = (page - 1) * limit
|
|
|
|
// Build filter
|
|
const filter: any = { status: 'published' }
|
|
|
|
// Category filter
|
|
if (query.category) {
|
|
filter.category = query.category
|
|
}
|
|
|
|
// Tags filter
|
|
if (query.tags) {
|
|
const tags = (query.tags as string).split(',')
|
|
filter.tags = { $in: tags }
|
|
}
|
|
|
|
// Search filter
|
|
if (query.search) {
|
|
filter.$or = [
|
|
{ title: { $regex: query.search, $options: 'i' } },
|
|
{ description: { $regex: query.search, $options: 'i' } },
|
|
{ content: { $regex: query.search, $options: 'i' } }
|
|
]
|
|
}
|
|
|
|
// Get articles
|
|
const articles = await Article.find(filter)
|
|
.populate('author', 'username displayName avatar')
|
|
.select('-content -revisions -comments')
|
|
.sort({ publishedAt: -1 })
|
|
.skip(skip)
|
|
.limit(limit)
|
|
|
|
// Filter by access level
|
|
const filteredArticles = []
|
|
for (const article of articles) {
|
|
const hasAccess = await checkAccessLevel(
|
|
event,
|
|
article.accessLevel,
|
|
article.cohorts
|
|
)
|
|
|
|
if (hasAccess) {
|
|
filteredArticles.push(article)
|
|
} else if (article.accessLevel === 'member' || article.accessLevel === 'cohort') {
|
|
// Show preview for protected content
|
|
filteredArticles.push({
|
|
...article.toObject(),
|
|
description: article.description.substring(0, 200) + '...',
|
|
restricted: true
|
|
})
|
|
}
|
|
}
|
|
|
|
// Get total count
|
|
const total = await Article.countDocuments(filter)
|
|
|
|
return {
|
|
articles: filteredArticles,
|
|
pagination: {
|
|
page,
|
|
limit,
|
|
total,
|
|
pages: Math.ceil(total / limit)
|
|
}
|
|
}
|
|
}) |