forked from mirror/crumbs-original
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>
43 lines
1.1 KiB
TypeScript
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);
|
|
}
|