Files
crumbs/src/lib/server/preferences.ts
T
Frederic CabassutandClaude Opus 4.6 93a632e78a feat: add user preferences system
Implement 4 user preferences (default note mode, default note color,
hide footer, sidebar default state) with offline-first localStorage
backed by server-side key-value storage.

- Add user_preferences table (EAV pattern with unique user_id+key index)
- Create server service with get/upsert operations
- Add GET/PUT /api/preferences endpoints
- Build Svelte 5 runes-based client store (.svelte.ts)
- Wire preferences into app layout (footer toggle, sidebar state)
- Wire default note mode/color into NoteEditor for new notes
- Add Preferences tab as first item in Settings navigation
- Add 7 unit tests and 4 E2E tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:07:19 +01:00

43 lines
1.1 KiB
TypeScript

import type { Db } from './db/index.js';
import { userPreferences } from './db/schema.js';
import { eq } from 'drizzle-orm';
/**
* Get all preferences for a user as a key-value record.
*/
export function getPreferences(db: Db, userId: number): Record<string, string> {
const rows = db
.select({ key: userPreferences.key, value: userPreferences.value })
.from(userPreferences)
.where(eq(userPreferences.userId, userId))
.all();
const result: Record<string, string> = {};
for (const row of rows) {
result[row.key] = row.value;
}
return result;
}
/**
* Upsert multiple preferences for a user.
* Uses INSERT OR REPLACE with the unique (user_id, key) index.
*/
export function upsertPreferences(
db: Db,
userId: number,
prefs: Record<string, string>
): Record<string, string> {
const now = new Date();
for (const [key, value] of Object.entries(prefs)) {
db.insert(userPreferences)
.values({ userId, key, value, updatedAt: now })
.onConflictDoUpdate({
target: [userPreferences.userId, userPreferences.key],
set: { value, updatedAt: now }
})
.run();
}
return getPreferences(db, userId);
}