backend: per-user settings store (/api/settings) + enable account deletion

- user_settings table (userId PK -> user, jsonb preferences) + migration
- GET/PUT /api/settings (requireAuth, user-scoped; zod-validated flat map)
- Better Auth user.deleteUser enabled so users can delete their own account

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalid Abdi
2026-06-10 20:05:34 +03:00
parent da245b8758
commit 50fbb6cd40
9 changed files with 2636 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
import { eq } from "drizzle-orm";
import { Router } from "express";
import { db } from "../db/index.js";
import { userSettings } from "../db/schema/settings.js";
import { settingsInputSchema } from "../lib/settings-validation.js";
import { requireAuth } from "../middleware/auth.js";
export const settingsRouter = Router();
// Settings are per-user (not per-clinic), so only authentication is required —
// no active organization or RBAC permission.
settingsRouter.use(requireAuth);
settingsRouter.get("/", async (req, res, next) => {
try {
const rows = await db
.select({ preferences: userSettings.preferences })
.from(userSettings)
.where(eq(userSettings.userId, req.user!.id))
.limit(1);
res.json({ preferences: rows[0]?.preferences ?? {} });
} catch (err) {
next(err);
}
});
settingsRouter.put("/", async (req, res, next) => {
try {
const { preferences } = settingsInputSchema.parse(req.body);
await db
.insert(userSettings)
.values({ userId: req.user!.id, preferences })
.onConflictDoUpdate({
target: userSettings.userId,
set: { preferences, updatedAt: new Date() },
});
res.json({ preferences });
} catch (err) {
next(err);
}
});