feat: US-008 — Checkpoint and Note tRPC procedures (CRUD)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@ import { z } from 'zod';
|
||||
import { eq, asc, inArray, and, or, like, sql } from 'drizzle-orm';
|
||||
import { alias } from 'drizzle-orm/sqlite-core';
|
||||
import { getDb } from '../db';
|
||||
import { clients, projects, tasks } from '../db/schema';
|
||||
import { clients, projects, tasks, checkpoints, notes } from '../db/schema';
|
||||
import { getStore } from '../store';
|
||||
|
||||
const t = initTRPC.create();
|
||||
@@ -295,7 +295,11 @@ const tasksRouter = router({
|
||||
const checkpointsRouter = router({
|
||||
list: publicProcedure
|
||||
.input(z.object({ projectId: z.string().optional() }).optional())
|
||||
.query(() => []),
|
||||
.query(({ input }) => {
|
||||
const where = input?.projectId !== undefined ? eq(checkpoints.projectId, input.projectId) : undefined;
|
||||
return getDb().select().from(checkpoints).where(where).orderBy(asc(checkpoints.date)).all();
|
||||
}),
|
||||
|
||||
create: publicProcedure
|
||||
.input(z.object({
|
||||
projectId: z.string(),
|
||||
@@ -304,7 +308,21 @@ const checkpointsRouter = router({
|
||||
isAiSuggested: z.number().optional(),
|
||||
isApproved: z.number().optional(),
|
||||
}))
|
||||
.mutation(() => null),
|
||||
.mutation(({ input }) => {
|
||||
const id = crypto.randomUUID();
|
||||
const now = Date.now();
|
||||
getDb().insert(checkpoints).values({
|
||||
id,
|
||||
projectId: input.projectId,
|
||||
title: input.title,
|
||||
date: input.date,
|
||||
isAiSuggested: input.isAiSuggested ?? 0,
|
||||
isApproved: input.isApproved ?? 0,
|
||||
createdAt: now,
|
||||
}).run();
|
||||
return { id };
|
||||
}),
|
||||
|
||||
update: publicProcedure
|
||||
.input(z.object({
|
||||
id: z.string(),
|
||||
@@ -312,28 +330,79 @@ const checkpointsRouter = router({
|
||||
date: z.number().optional(),
|
||||
isApproved: z.number().optional(),
|
||||
}))
|
||||
.mutation(() => null),
|
||||
.mutation(({ input }) => {
|
||||
const set: Partial<{ title: string; date: number; isApproved: number }> = {};
|
||||
if (input.title !== undefined) set.title = input.title;
|
||||
if (input.date !== undefined) set.date = input.date;
|
||||
if (input.isApproved !== undefined) set.isApproved = input.isApproved;
|
||||
if (Object.keys(set).length > 0) {
|
||||
getDb().update(checkpoints).set(set).where(eq(checkpoints.id, input.id)).run();
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
|
||||
delete: publicProcedure
|
||||
.input(z.object({ id: z.string() }))
|
||||
.mutation(() => null),
|
||||
.mutation(({ input }) => {
|
||||
getDb().delete(checkpoints).where(eq(checkpoints.id, input.id)).run();
|
||||
return { success: true as const };
|
||||
}),
|
||||
});
|
||||
|
||||
const notesRouter = router({
|
||||
list: publicProcedure
|
||||
.input(z.object({ projectId: z.string().optional() }).optional())
|
||||
.query(() => []),
|
||||
.query(({ input }) => {
|
||||
const where = input?.projectId !== undefined ? eq(notes.projectId, input.projectId) : undefined;
|
||||
return getDb()
|
||||
.select({ id: notes.id, projectId: notes.projectId, title: notes.title, createdAt: notes.createdAt, updatedAt: notes.updatedAt })
|
||||
.from(notes)
|
||||
.where(where)
|
||||
.orderBy(asc(notes.createdAt))
|
||||
.all();
|
||||
}),
|
||||
|
||||
get: publicProcedure
|
||||
.input(z.object({ id: z.string() }))
|
||||
.query(() => null),
|
||||
.query(({ input }) => {
|
||||
const result = getDb().select().from(notes).where(eq(notes.id, input.id)).all();
|
||||
return result[0] ?? null;
|
||||
}),
|
||||
|
||||
create: publicProcedure
|
||||
.input(z.object({ title: z.string(), content: z.string(), projectId: z.string().optional() }))
|
||||
.mutation(() => null),
|
||||
.mutation(({ input }) => {
|
||||
const id = crypto.randomUUID();
|
||||
const now = Date.now();
|
||||
getDb().insert(notes).values({
|
||||
id,
|
||||
title: input.title,
|
||||
content: input.content,
|
||||
projectId: input.projectId ?? null,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
}).run();
|
||||
return { id };
|
||||
}),
|
||||
|
||||
update: publicProcedure
|
||||
.input(z.object({ id: z.string(), title: z.string().optional(), content: z.string().optional() }))
|
||||
.mutation(() => null),
|
||||
.mutation(({ input }) => {
|
||||
const set: Partial<{ title: string; content: string; updatedAt: number }> = {};
|
||||
if (input.title !== undefined) set.title = input.title;
|
||||
if (input.content !== undefined) set.content = input.content;
|
||||
// Always update updatedAt
|
||||
set.updatedAt = Date.now();
|
||||
getDb().update(notes).set(set).where(eq(notes.id, input.id)).run();
|
||||
return null;
|
||||
}),
|
||||
|
||||
delete: publicProcedure
|
||||
.input(z.object({ id: z.string() }))
|
||||
.mutation(() => null),
|
||||
.mutation(({ input }) => {
|
||||
getDb().delete(notes).where(eq(notes.id, input.id)).run();
|
||||
return { success: true as const };
|
||||
}),
|
||||
});
|
||||
|
||||
const settingsRouter = router({
|
||||
|
||||
Reference in New Issue
Block a user