feat: update settings management to use site_name and add batch update schema
Test / backend (push) Successful in 13s
Test / frontend (push) Successful in 33s

This commit is contained in:
LaurensBartelds committed 2026-04-27 13:06:01 +02:00
1 parent 1b5fd04040
commit 6dd87972f6
5 files changed
+44 -13

No files matched your search

+6 -5
View File
@@ -6,7 +6,7 @@ import { AppError } from '../middleware/error.js'
import * as userRepo from '../repositories/userRepo.js'
import * as resultRepo from '../repositories/resultRepo.js'
import * as settingsRepo from '../repositories/settingsRepo.js'
import { updateUserRoleSchema, updateSettingSchema, listUsersQuerySchema, userIdParamSchema } from '../validators/adminSchemas.js'
import { updateUserRoleSchema, updateSettingSchema, updateSettingsBatchSchema, listUsersQuerySchema, userIdParamSchema } from '../validators/adminSchemas.js'
import type { Request } from 'express'
const router = Router()
@@ -124,17 +124,18 @@ router.get(
router.get(
'/settings',
asyncHandler(async (_req, res) => {
res.json(settingsRepo.getAllSettings())
res.json({ settings: settingsRepo.getAllSettings() })
})
)
// PUT /api/admin/settings
router.put(
'/settings',
validateBody(updateSettingSchema),
validateBody(updateSettingsBatchSchema),
asyncHandler(async (req: Request, res) => {
const { key, value } = req.body
settingsRepo.setSetting(key, value)
const { settings } = req.body
const entries = Object.entries(settings) as Array<[string, string]>
settingsRepo.setSettingsBatch(entries)
res.json({ success: true })
})
)
+3 -3
View File
@@ -14,7 +14,7 @@ const router = Router()
const SALT_ROUNDS = 10
function getSiteTitle(): string | null {
return settingsRepo.getSetting('site_title') ?? null
return settingsRepo.getSetting('site_name') ?? null
}
// GET /api/setup/status
@@ -38,7 +38,7 @@ router.post(
// Atomic transaction prevents race conditions between concurrent setup requests
const tx = db.transaction(() => {
const title = settingsRepo.getSetting('site_title')
const title = settingsRepo.getSetting('site_name')
if (title) {
throw new AppError(400, 'Setup already completed')
}
@@ -74,7 +74,7 @@ router.post(
})
const settings: Array<[string, string]> = [
['site_title', siteTitle?.trim() || 'BrainWave'],
['site_name', siteTitle?.trim() || 'BrainWave'],
['site_language', language || 'en'],
['maintenance_mode', 'false'],
]
+26 -3
View File
@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest'
import { updateUserRoleSchema, updateSettingSchema, listUsersQuerySchema, userIdParamSchema } from './adminSchemas'
import { updateUserRoleSchema, updateSettingSchema, updateSettingsBatchSchema, listUsersQuerySchema, userIdParamSchema } from './adminSchemas'
describe('updateUserRoleSchema', () => {
it('accepts valid role change', () => {
@@ -20,7 +20,7 @@ describe('updateUserRoleSchema', () => {
describe('updateSettingSchema', () => {
it('accepts valid setting', () => {
const result = updateSettingSchema.safeParse({ key: 'site_title', value: 'BrainWave' })
const result = updateSettingSchema.safeParse({ key: 'site_name', value: 'BrainWave' })
expect(result.success).toBe(true)
})
@@ -30,7 +30,30 @@ describe('updateSettingSchema', () => {
})
it('rejects empty value', () => {
const result = updateSettingSchema.safeParse({ key: 'site_title', value: '' })
const result = updateSettingSchema.safeParse({ key: 'site_name', value: '' })
expect(result.success).toBe(false)
})
})
describe('updateSettingsBatchSchema', () => {
it('accepts valid batch', () => {
const result = updateSettingsBatchSchema.safeParse({
settings: { site_name: 'BrainWave', maintenance_mode: 'false' },
})
expect(result.success).toBe(true)
})
it('rejects invalid key in batch', () => {
const result = updateSettingsBatchSchema.safeParse({
settings: { site_name: 'BrainWave', unknown_key: 'value' },
})
expect(result.success).toBe(false)
})
it('rejects empty value in batch', () => {
const result = updateSettingsBatchSchema.safeParse({
settings: { site_name: '' },
})
expect(result.success).toBe(false)
})
})
+8 -1
View File
@@ -6,7 +6,7 @@ export const updateUserRoleSchema = z.object({
})
const ALLOWED_SETTING_KEYS = [
'site_title',
'site_name',
'site_language',
'maintenance_mode',
'maintenance_message',
@@ -28,6 +28,13 @@ export const updateSettingSchema = z.object({
value: z.string().min(1),
})
export const updateSettingsBatchSchema = z.object({
settings: z.record(z.string().min(1)).refine(
(obj) => Object.keys(obj).every((k) => ALLOWED_SETTING_KEYS.includes(k as typeof ALLOWED_SETTING_KEYS[number])),
{ message: 'One or more setting keys are not allowed' }
),
})
export const listUsersQuerySchema = z.object({
page: z.string().regex(/^\d+$/).optional().transform((v: string | undefined) => (v ? Number(v) : 1)),
search: z.string().optional(),