- New views table (id, name, filters jsonb, sort_key, is_public, creator_id) - GET/POST/PATCH/DELETE /views endpoints - Register views router in server Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
import { Hono } from 'hono';
|
|
import { HTTPException } from 'hono/http-exception';
|
|
import { asc, eq } from 'drizzle-orm';
|
|
import type { Db } from '../db/index.ts';
|
|
import { views } from '../db/schema.ts';
|
|
|
|
export function createViewsRouter(db: Db): Hono {
|
|
const router = new Hono();
|
|
|
|
router.get('/', async (c) => {
|
|
const result = await db.query.views.findMany({
|
|
orderBy: asc(views.name),
|
|
});
|
|
return c.json(result);
|
|
});
|
|
|
|
router.post('/', async (c) => {
|
|
const body = await c.req.json();
|
|
const name = String(body.name ?? '').trim();
|
|
|
|
if (!name) {
|
|
throw new HTTPException(400, { message: 'name is required' });
|
|
}
|
|
|
|
const [view] = await db.insert(views).values({
|
|
name,
|
|
filters: body.filters ?? [],
|
|
sort_key: body.sort_key ?? 'updated',
|
|
columns: body.columns ?? [],
|
|
is_public: body.is_public ?? false,
|
|
creator_id: body.creator_id || null,
|
|
}).returning();
|
|
|
|
if (!view) {
|
|
throw new HTTPException(500, { message: 'Failed to create view' });
|
|
}
|
|
|
|
return c.json(view, 201);
|
|
});
|
|
|
|
router.patch('/:id', async (c) => {
|
|
const id = c.req.param('id');
|
|
const body = await c.req.json();
|
|
|
|
const existing = await db.query.views.findFirst({
|
|
where: eq(views.id, id),
|
|
});
|
|
|
|
if (!existing) {
|
|
throw new HTTPException(404, { message: 'View not found' });
|
|
}
|
|
|
|
const updateData: Partial<typeof views.$inferInsert> = {};
|
|
if (body.name !== undefined) updateData.name = String(body.name).trim();
|
|
if (body.filters !== undefined) updateData.filters = body.filters;
|
|
if (body.sort_key !== undefined) updateData.sort_key = body.sort_key;
|
|
if (body.columns !== undefined) updateData.columns = body.columns;
|
|
if (body.is_public !== undefined) updateData.is_public = body.is_public;
|
|
|
|
const [updated] = await db.update(views)
|
|
.set(updateData)
|
|
.where(eq(views.id, id))
|
|
.returning();
|
|
|
|
return c.json(updated);
|
|
});
|
|
|
|
router.delete('/:id', async (c) => {
|
|
const id = c.req.param('id');
|
|
|
|
const existing = await db.query.views.findFirst({
|
|
where: eq(views.id, id),
|
|
});
|
|
|
|
if (!existing) {
|
|
throw new HTTPException(404, { message: 'View not found' });
|
|
}
|
|
|
|
await db.delete(views).where(eq(views.id, id));
|
|
return c.json({ ok: true });
|
|
});
|
|
|
|
return router;
|
|
}
|