29 lines
1.7 KiB
TypeScript
29 lines
1.7 KiB
TypeScript
import { Hono } from "hono";
|
|
import { bodyLimit } from "hono/body-limit";
|
|
import { desc, eq } from "drizzle-orm";
|
|
import type { AppDatabase, AuthEnv, createAuth } from "../auth";
|
|
import { reminderDeliveries, reminderSettings } from "../db/schema";
|
|
import { defaultReminder, reminderInput } from "./contracts";
|
|
|
|
export function createReminderRoutes(db: AppDatabase, auth: ReturnType<typeof createAuth>, available: boolean, now: () => number) {
|
|
const app = new Hono<AuthEnv>();
|
|
app.use("*", auth.requireAuth);
|
|
app.get("/", c => {
|
|
const userId = c.get("user").id;
|
|
const prefs = db.select().from(reminderSettings).where(eq(reminderSettings.userId, userId)).get() ?? defaultReminder;
|
|
const last = db.select().from(reminderDeliveries).where(eq(reminderDeliveries.userId, userId)).orderBy(desc(reminderDeliveries.updatedAt)).get();
|
|
return c.json({ enabled: prefs.enabled, time: prefs.time, quietStart: prefs.quietStart, quietEnd: prefs.quietEnd, available,
|
|
lastDelivery: last ? { date: last.date, status: last.status === "pending" ? "uncertain" : last.status } : null });
|
|
});
|
|
app.put("/", auth.requireSameOrigin, bodyLimit({ maxSize: 2048 }), async c => {
|
|
const parsed = reminderInput.safeParse(await c.req.json().catch(() => null));
|
|
if (!parsed.success) return c.json({ error: "Choose valid reminder and quiet-hour times." }, 422);
|
|
if (parsed.data.enabled && !available) return c.json({ error: "Discord reminders are not configured on this server." }, 422);
|
|
const row = { ...parsed.data, updatedAt: now() };
|
|
db.insert(reminderSettings).values({ userId: c.get("user").id, ...row })
|
|
.onConflictDoUpdate({ target: reminderSettings.userId, set: row }).run();
|
|
return c.json(parsed.data);
|
|
});
|
|
return app;
|
|
}
|