feat(checklist): add daily checklist feature with admin management

Add daily checklist view for users to track daily tasks
Support creating, editing, deleting, and drag-and-drop reordering in admin panel
This commit is contained in:
2026-05-01 09:40:00 +08:00
parent 60cad3f5e8
commit 91dd834413
10 changed files with 775 additions and 1 deletions

View File

@@ -5,11 +5,13 @@ import { getUserBySessionToken, loginUser, logoutSession, registerUser, verifyEm
import { initializeDatabase, pool } from './db.ts';
import {
createConfig,
createDailyChecklistItem,
createHabitat,
createItem,
createPokemon,
createRecipe,
deleteConfig,
deleteDailyChecklistItem,
deleteHabitat,
deleteItem,
deletePokemon,
@@ -21,11 +23,14 @@ import {
getRecipe,
isConfigType,
listConfig,
listDailyChecklistItems,
listHabitats,
listItems,
listPokemon,
listRecipes,
reorderDailyChecklistItems,
updateConfig,
updateDailyChecklistItem,
updateHabitat,
updateItem,
updatePokemon,
@@ -119,6 +124,8 @@ app.post('/api/auth/logout', async (request, reply) => {
app.get('/api/options', async () => getOptions());
app.get('/api/daily-checklist', async () => listDailyChecklistItems());
app.get('/api/pokemon', async (request) => listPokemon(request.query as Record<string, string | string[] | undefined>));
app.get('/api/pokemon/:id', async (request, reply) => {
@@ -291,6 +298,36 @@ app.delete('/api/recipes/:id', async (request, reply) => {
return deleted ? reply.code(204).send() : reply.code(404).send({ message: 'Not found' });
});
app.post('/api/admin/daily-checklist', async (request, reply) => {
const user = await requireVerifiedUser(request, reply);
return user ? reply.code(201).send(await createDailyChecklistItem(request.body as Record<string, unknown>, user.id)) : undefined;
});
app.put('/api/admin/daily-checklist/order', async (request, reply) => {
const user = await requireVerifiedUser(request, reply);
return user ? reorderDailyChecklistItems(request.body as Record<string, unknown>, user.id) : undefined;
});
app.put('/api/admin/daily-checklist/:id', async (request, reply) => {
const user = await requireVerifiedUser(request, reply);
if (!user) {
return;
}
const { id } = request.params as { id: string };
const item = await updateDailyChecklistItem(Number(id), request.body as Record<string, unknown>, user.id);
return item ? item : reply.code(404).send({ message: 'Not found' });
});
app.delete('/api/admin/daily-checklist/:id', async (request, reply) => {
const user = await requireVerifiedUser(request, reply);
if (!user) {
return;
}
const { id } = request.params as { id: string };
const deleted = await deleteDailyChecklistItem(Number(id), user.id);
return deleted ? reply.code(204).send() : reply.code(404).send({ message: 'Not found' });
});
app.get('/api/admin/config/:type', async (request, reply) => {
const user = await requireVerifiedUser(request, reply);
if (!user) {