// GET /posts?search=node&author=42&tag=tutorial&from=2024-01-01&sort=popular&page=2
app.get('/posts', async (req, res) => {
const { search, author, tag, from, to, sort, page = 1 } = req.query;
const posts = await Post.query()
.with('user', 'tags')
.withCount('comments')
// Text search
.when(search, (q) =>
q.where((inner) =>
inner
.where('title', 'like', `%${search}%`)
.orWhere('body', 'like', `%${search}%`)
)
)
// Author filter
.when(author, (q) => q.where('user_id', author))
// Tag filter (relation constraint)
.when(tag, (q) => q.whereHas('tags', (sq) => sq.where('slug', tag)))
// Date range
.when(from, (q) => q.where('created_at', '>=', new Date(from)))
.when(to, (q) => q.where('created_at', '<=', new Date(to)))
// Sorting
.when(sort === 'popular', (q) => q.orderBy('views', 'desc'))
.when(sort === 'comments', (q) => q.orderBy('comments_count', 'desc'))
.unless(sort, (q) => q.orderBy('created_at', 'desc')) // default sort
// Always published for non-admins
.unless(req.user?.isAdmin(), (q) => q.where('published', true))
.paginate(page, 15);
res.json(posts);
});