import { call, os } from "@orpc/server"; import { z } from "zod"; import { randomUUID } from "crypto"; import { createKV } from "../lib/create-kv.js"; import { assertOwner, getSessionFromCookies } from "../lib/auth.js"; import { checkAdminRateLimit, getClientIP, enforceAdminRateLimit } from "../lib/rate-limiter.js"; const TreatmentSchema = z.object({ id: z.string(), name: z.string(), description: z.string(), duration: z.number(), // duration in minutes price: z.number(), // price in cents category: z.string(), }); type Treatment = z.output; const kv = createKV("treatments"); const create = os .input(TreatmentSchema.omit({ id: true })) .handler(async ({ input, context }) => { await assertOwner(context); // Admin Rate Limiting nach erfolgreicher Owner-Prüfung await enforceAdminRateLimit(context as any); const id = randomUUID(); const treatment = { id, ...input }; await kv.setItem(id, treatment); return treatment; }); const update = os .input(TreatmentSchema) .handler(async ({ input, context }) => { await assertOwner(context); // Admin Rate Limiting await enforceAdminRateLimit(context as any); await kv.setItem(input.id, input); return input; }); const remove = os.input(z.string()).handler(async ({ input, context }) => { await assertOwner(context); // Admin Rate Limiting await enforceAdminRateLimit(context as any); await kv.removeItem(input); }); const list = os.handler(async () => { return kv.getAllItems(); }); const get = os.input(z.string()).handler(async ({ input }) => { return kv.getItem(input); }); const live = { list: os.handler(async function* ({ signal }) { yield call(list, {}, { signal }); for await (const _ of kv.subscribe()) { yield call(list, {}, { signal }); } }), }; export const router = { create, update, remove, list, get, live, };