Files
stack/apps/gateway/src/preferences/preferences.controller.ts
Jason Woltje 85aeebbde2
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
feat(gateway): PreferencesService + /preferences REST + /system Valkey override (P8-011)
- PreferencesService: platform defaults, user overrides, IMMUTABLE_KEYS enforcement
- PreferencesController: GET /api/preferences, POST /api/preferences, DELETE /api/preferences/:key
- PreferencesModule: global module exporting PreferencesService and SystemOverrideService
- SystemOverrideService: Valkey-backed session-scoped system prompt override with 5-min TTL + renew
- CommandRegistryService: register /system command (socket execution)
- CommandExecutorService: handle /system command via SystemOverrideService
- AgentService: inject system override before each prompt turn, renew TTL; store userId in session
- ChatGateway: pass userId when creating agent sessions
- PreferencesService unit tests: 11 tests covering defaults, overrides, enforcement wins, immutable key errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 21:32:03 -05:00

45 lines
1.1 KiB
TypeScript

import {
Body,
Controller,
Delete,
Get,
HttpCode,
HttpStatus,
Inject,
Param,
Post,
UseGuards,
} from '@nestjs/common';
import { PreferencesService } from './preferences.service.js';
import { AuthGuard } from '../auth/auth.guard.js';
import { CurrentUser } from '../auth/current-user.decorator.js';
@Controller('api/preferences')
@UseGuards(AuthGuard)
export class PreferencesController {
constructor(@Inject(PreferencesService) private readonly preferences: PreferencesService) {}
@Get()
async show(@CurrentUser() user: { id: string }): Promise<Record<string, unknown>> {
return this.preferences.getEffective(user.id);
}
@Post()
@HttpCode(HttpStatus.OK)
async set(
@CurrentUser() user: { id: string },
@Body() body: { key: string; value: unknown },
): Promise<{ success: boolean; message: string }> {
return this.preferences.set(user.id, body.key, body.value);
}
@Delete(':key')
@HttpCode(HttpStatus.OK)
async reset(
@CurrentUser() user: { id: string },
@Param('key') key: string,
): Promise<{ success: boolean; message: string }> {
return this.preferences.reset(user.id, key);
}
}