+server.ts RawHistoryFolder
1import { json, error } from '@sveltejs/kit';
2import type { RequestHandler } from './$types';
3import convex from '$lib/db/convex.server';
4import { DEFAULT_USER_PREFERENCES, type UserTextPreferences } from '$lib/types/text-formatting';
5import { validateSessionToken } from '$lib/api/session.server';
6import { sanitizeStyleData } from '$lib/validation/text-formatting';
7
8const isKitHttpError = (err: unknown): err is { status: number; body: unknown } => {
9 return typeof err === 'object' && err !== null && 'status' in err && 'body' in err;
10};
11
12// GET - Fetch current user's text preferences
13export const GET: RequestHandler = async ({ cookies }) => {
14 try {
15 // Get session token from cookie
16 const sessionToken = cookies.get('session');
17 if (!sessionToken) {
18 throw error(401, 'No session found');
19 }
20
21 // Validate session token
22 const { user } = await validateSessionToken(sessionToken);
23
24 if (!user) {
25 throw error(401, 'Invalid session');
26 }
27
28 // Get user's text preferences
29 const preferences = await convex.textPreferences.get(user.id);
30
31 if (!preferences) {
32 // Return defaults if no preferences exist
33 return json({
34 success: true,
35 preferences: DEFAULT_USER_PREFERENCES
36 });
37 }
38
39 // Convert Convex format to frontend format
40 const frontendPreferences: UserTextPreferences = {
41 defaultStyle: preferences.defaultStyle as UserTextPreferences['defaultStyle'],
42 allowFormatting: preferences.allowFormatting,
43 maxMessageLength: preferences.maxMessageLength
44 };
45
46 return json({
47 success: true,
48 preferences: frontendPreferences
49 });
50 } catch (err) {
51 console.error('Failed to fetch text preferences:', err);
52 if (err instanceof Response || isKitHttpError(err)) {
53 throw err;
54 }
55 throw error(500, 'Failed to fetch preferences');
56 }
57};
58
59// POST - Save current user's text preferences
60export const POST: RequestHandler = async ({ cookies, request }) => {
61 try {
62 // Get session token from cookie
63 const sessionToken = cookies.get('session');
64 if (!sessionToken) {
65 throw error(401, 'No session found');
66 }
67
68 // Validate session token
69 const { user } = await validateSessionToken(sessionToken);
70
71 if (!user) {
72 throw error(401, 'Invalid session');
73 }
74
75 // Parse request body
76 const body = await request.json();
77 const { allowFormatting, maxMessageLength } = body as {
78 allowFormatting: unknown;
79 maxMessageLength: unknown;
80 defaultStyle: unknown;
81 };
82
83 // Validate types
84 if (typeof allowFormatting !== 'boolean' || typeof maxMessageLength !== 'number') {
85 throw error(400, 'Invalid preferences data');
86 }
87
88 // Validate and sanitize style data through existing Zod schema
89 const validatedStyle = sanitizeStyleData(body.defaultStyle);
90 if (!validatedStyle) {
91 throw error(400, 'Invalid style data');
92 }
93
94 // Save preferences via Convex
95 const result = await convex.textPreferences.save(
96 user.id,
97 validatedStyle,
98 allowFormatting,
99 maxMessageLength
100 );
101
102 return json({
103 success: true,
104 id: result.id
105 });
106 } catch (err) {
107 console.error('Failed to save text preferences:', err);
108 if (err instanceof Response || isKitHttpError(err)) {
109 throw err;
110 }
111 throw error(500, 'Failed to save preferences');
112 }
113};