feat(plaza-ops): add post management API for admin console

Expose categories listing, category filter on review queue, and invalidate
feed caches when ops hides a published post.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-05 19:27:09 +08:00
parent dd091e6e2c
commit 0c2cb9e283
4 changed files with 114 additions and 4 deletions
+24 -1
View File
@@ -46,11 +46,27 @@ export function createPlazaOpsService(
);
};
const listCategories = async () => {
const [rows] = await pool.query(
`SELECT id, name, slug, icon
FROM plaza_categories
WHERE is_active = 1
ORDER BY sort_order ASC, name ASC`,
);
return rows.map((row) => ({
id: row.id,
name: row.name,
slug: row.slug,
icon: row.icon ?? '',
}));
};
const listReviewQueue = async ({
status = 'pending_review',
cursor = null,
limit = 20,
keyword = null,
category = null,
} = {}) => {
const pageLimit = clampLimit(limit, 20, 100);
const params = [status];
@@ -65,13 +81,19 @@ export function createPlazaOpsService(
const pattern = `%${String(keyword).trim()}%`;
params.push(pattern, pattern, pattern);
}
let categoryClause = '';
const categorySlug = String(category ?? '').trim();
if (categorySlug) {
categoryClause = 'AND c.slug = ?';
params.push(categorySlug);
}
params.push(pageLimit + 1);
const [rows] = await pool.query(
`SELECT pp.id, pp.title, pp.summary, pp.cover_url, pp.status, pp.user_display_name, pp.user_slug,
pp.published_at, pp.created_at, c.name AS category_name, c.slug AS category_slug, c.icon AS category_icon
FROM plaza_posts pp
JOIN plaza_categories c ON c.id = pp.category_id
WHERE pp.status = ? ${cursorClause} ${keywordClause}
WHERE pp.status = ? ${cursorClause} ${keywordClause} ${categoryClause}
ORDER BY pp.published_at DESC, pp.id DESC
LIMIT ?`,
params,
@@ -419,6 +441,7 @@ export function createPlazaOpsService(
return {
loadOperatorRole,
hasOpsRole,
listCategories,
listReviewQueue,
reviewPostAsOps,
batchReviewPosts,