feat: add pagination support to admin categories endpoint
- Add page/limit query parameters with Zod validation (max 50) - Update listCategories service to return paginated results - Response format includes pagination metadata (total, page, limit) - Matches existing pattern from questions/feedback endpoints Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2dd5f18822
commit
6e65993f89
7
.claude/settings.json
Normal file
7
.claude/settings.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"enabledPlugins": {
|
||||
"typescript-lsp@claude-plugins-official": true,
|
||||
"claude-md-management@claude-plugins-official": true,
|
||||
"glm-plan-usage@zai-coding-plugins": false
|
||||
}
|
||||
}
|
||||
15
.claude/settings.local.json
Normal file
15
.claude/settings.local.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"mcp__plugin_ecc_context7__resolve-library-id",
|
||||
"mcp__plugin_ecc_context7__query-docs",
|
||||
"Bash(bun install:*)",
|
||||
"Bash(bun add:*)",
|
||||
"Bash(bunx tsc:*)",
|
||||
"Bash(git status:*)",
|
||||
"Bash(git add:*)",
|
||||
"Bash(git commit:*)",
|
||||
"Bash(bun run:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -18,10 +18,32 @@ const updateCategorySchema = z.object({
|
||||
status: z.enum(['active', 'inactive']).optional(),
|
||||
});
|
||||
|
||||
const listCategoriesQuerySchema = z.object({
|
||||
page: z.coerce.number().int().positive().optional().default(1),
|
||||
limit: z.coerce.number().int().positive().max(50).optional().default(20),
|
||||
});
|
||||
|
||||
export async function adminCategoriesRoutes(app: FastifyInstance): Promise<void> {
|
||||
app.get('/', async () => {
|
||||
const data = await categoryService.listCategories();
|
||||
return { success: true, data, error: null };
|
||||
app.get('/', async (request) => {
|
||||
const parsed = listCategoriesQuerySchema.safeParse(request.query);
|
||||
if (!parsed.success) {
|
||||
return {
|
||||
success: false,
|
||||
data: null,
|
||||
error: {
|
||||
code: 'VALIDATION_ERROR',
|
||||
message: parsed.error.issues[0]?.message ?? 'Invalid query parameters'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const result = await categoryService.listCategories(parsed.data);
|
||||
return {
|
||||
success: true,
|
||||
data: result.items,
|
||||
pagination: result.pagination,
|
||||
error: null
|
||||
};
|
||||
});
|
||||
|
||||
app.post('/', async (request) => {
|
||||
|
||||
@ -2,8 +2,33 @@ import { db } from '../../db/client.js';
|
||||
import { categories, questions } from '../../db/schema.js';
|
||||
import { eq, and, sql } from 'drizzle-orm';
|
||||
|
||||
export async function listCategories() {
|
||||
return db.select().from(categories).orderBy(categories.sortOrder);
|
||||
interface ListOptions {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export async function listCategories({ page = 1, limit = 20 }: ListOptions = {}) {
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
// Get total count
|
||||
const [countResult] = await db
|
||||
.select({ total: sql<number>`COUNT(*)` })
|
||||
.from(categories);
|
||||
|
||||
const total = Number(countResult?.total ?? 0);
|
||||
|
||||
// Get paginated items
|
||||
const items = await db
|
||||
.select()
|
||||
.from(categories)
|
||||
.orderBy(categories.sortOrder)
|
||||
.limit(limit)
|
||||
.offset(offset);
|
||||
|
||||
return {
|
||||
items,
|
||||
pagination: { total, page, limit }
|
||||
};
|
||||
}
|
||||
|
||||
export async function createCategory(data: { id: string; name: string; slug: string; parentId?: string; sortOrder?: number }) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user