168 lines · 6.9 KB
import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";
import { requireViewer, viewerMiddleware } from "./middleware";
import { first, run } from "~/server/db";
import { accountDb, repoDb } from "~/server/scoped-db";
import { assertBelowCap, CAPS, limitAccountWrite } from "~/server/limits";
import { requireRepoAccess } from "~/server/repos";
import { issueParticipants, loadIssue } from "~/server/issues";
import { notFoundError } from "~/server/errors";
import { loadNotificationSettings, WATCH_LEVELS } from "~/server/notification-prefs";
import { repoRef } from "~/lib/validation";
import { DIGEST_MODES, NOTIFICATION_CATEGORIES } from "~/lib/notification-categories";
import { loadCategoryPrefs, saveCategoryPref } from "~/server/notify/prefs";

const threadRef = repoRef.extend({ number: z.number().int().positive() });

export const getNotificationSettings = createServerFn({ method: "GET" })
  .middleware([viewerMiddleware])
  .handler(async ({ context }) => {
    const viewer = requireViewer(context.viewer);
    return loadNotificationSettings(viewer.id);
  });

export const updateNotificationSettings = createServerFn({ method: "POST" })
  .middleware([viewerMiddleware])
  .validator(
    z.object({
      emailParticipating: z.boolean(),
      emailWatching: z.boolean(),
      webParticipating: z.boolean(),
      webWatching: z.boolean(),
    }),
  )
  .handler(async ({ data, context }) => {
    const viewer = requireViewer(context.viewer);
    await limitAccountWrite(viewer);
    await accountDb(viewer.id).run(
      `INSERT INTO notification_settings (user_id, email_participating, email_watching, web_participating, web_watching, updated_at)
       VALUES (?, ?, ?, ?, ?, ?)
       ON CONFLICT (user_id) DO UPDATE SET email_participating = excluded.email_participating,