feat(dross): settings endpoint (avatar/accent/persona/voiceMode)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-06-09 23:50:10 +10:00
parent c83bd6a89b
commit 7a09b9f91c
3 changed files with 60 additions and 0 deletions

View File

@@ -38,6 +38,7 @@ import { router as storageRouter } from './routes/storage.js';
import { router as backupsRouter } from './routes/backups.js';
import { router as kuttRouter } from './routes/kutt.js';
import { router as themeRouter } from './routes/theme.js';
import { router as drossRouter } from './routes/dross.js';
export function mountApi(app) {
const api = Router();
@@ -73,6 +74,7 @@ export function mountApi(app) {
api.use('/links', linksRouter);
api.use('/kutt', kuttRouter);
api.use('/theme', themeRouter);
api.use('/dross', drossRouter);
api.use('/pending-changes', pendingChangesRouter);
api.use('/audit', auditRouter);
api.use('/search', searchRouter);

23
lib/api/routes/dross.js Normal file
View File

@@ -0,0 +1,23 @@
import { Router } from 'express';
import { z } from 'zod';
import { validate } from '../validate.js';
import { asyncWrap } from '../errors.js';
import { requireOwner } from '../cap.js';
import * as settings from '../../db/repos/app_settings.js';
const DEFAULT_SETTINGS = { avatar: 'soft-eye', accent: '#a86adf', persona: '', voiceMode: 'review' };
export const router = Router();
async function getCfg() { return { ...DEFAULT_SETTINGS, ...(await settings.get('dross', {})) }; }
router.get('/settings', asyncWrap(async (_req, res) => res.json(await getCfg())));
const settingsBody = z.object({
avatar: z.enum(['soft-eye', 'wisp', 'motes']),
accent: z.string().regex(/^#[0-9a-fA-F]{6}$/),
persona: z.string().max(8000),
voiceMode: z.enum(['review', 'handsfree', 'action'])
});
router.put('/settings', requireOwner, validate({ body: settingsBody }),
asyncWrap(async (req, res) => res.json(await settings.set('dross', req.body))));