mirror of
https://github.com/temetro/temetro.git
synced 2026-09-04 14:55:28 +00:00
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:
@@ -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);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user