diff --git a/.veritas-kanban/telemetry/events-2026-01-28.ndjson b/.veritas-kanban/telemetry/events-2026-01-28.ndjson index 0f0c859f..8f47f081 100644 --- a/.veritas-kanban/telemetry/events-2026-01-28.ndjson +++ b/.veritas-kanban/telemetry/events-2026-01-28.ndjson @@ -388,3 +388,5 @@ {"type":"task.status_changed","taskId":"task_20260128_itHuxN","project":"veritas-kanban","status":"in-progress","previousStatus":"todo","id":"evt_NOCEuvNIHTiv","timestamp":"2026-01-28T08:20:05.575Z"} {"type":"task.status_changed","taskId":"task_20260128_Kbjd3t","project":"veritas-kanban","status":"in-progress","previousStatus":"todo","id":"evt_pboz3ar-apIo","timestamp":"2026-01-28T08:20:05.585Z"} {"type":"task.status_changed","taskId":"task_20260128_iG-ISb","project":"platform","status":"done","previousStatus":"in-progress","id":"evt_9NMBR9OcmaQV","timestamp":"2026-01-28T08:24:03.292Z"} +{"type":"task.status_changed","taskId":"task_20260128_DUyAbh","project":"veritas-kanban","status":"done","previousStatus":"in-progress","id":"evt_UfgftrtLSNBu","timestamp":"2026-01-28T08:32:47.510Z"} +{"type":"task.status_changed","taskId":"task_20260128_vYzfwx","project":"veritas-kanban","status":"done","previousStatus":"in-progress","id":"evt_SttjD2RNNe2h","timestamp":"2026-01-28T08:32:47.536Z"} diff --git a/server/.veritas-kanban/activity.json b/server/.veritas-kanban/activity.json index 8d34ffc5..8421f542 100644 --- a/server/.veritas-kanban/activity.json +++ b/server/.veritas-kanban/activity.json @@ -1,4 +1,48 @@ [ + { + "id": "activity_1769589172887_jp4y9jj7c", + "type": "comment_added", + "taskId": "task_20260128_vYzfwx", + "taskTitle": "US-1104: Task behavior settings", + "details": { + "author": "Veritas", + "preview": "Task behavior settings wired in TaskDetailPanel: d..." + }, + "timestamp": "2026-01-28T08:32:52.887Z" + }, + { + "id": "activity_1769589172877_npxiqczo8", + "type": "comment_added", + "taskId": "task_20260128_DUyAbh", + "taskTitle": "US-1103: Board & display settings", + "details": { + "author": "Veritas", + "preview": "Board & display settings complete: sprint badges o..." + }, + "timestamp": "2026-01-28T08:32:52.877Z" + }, + { + "id": "activity_1769589167537_tukrzq1ly", + "type": "status_changed", + "taskId": "task_20260128_vYzfwx", + "taskTitle": "US-1104: Task behavior settings", + "details": { + "from": "in-progress", + "status": "done" + }, + "timestamp": "2026-01-28T08:32:47.537Z" + }, + { + "id": "activity_1769589167510_sgfq2w68c", + "type": "status_changed", + "taskId": "task_20260128_DUyAbh", + "taskTitle": "US-1103: Board & display settings", + "details": { + "from": "in-progress", + "status": "done" + }, + "timestamp": "2026-01-28T08:32:47.510Z" + }, { "id": "activity_1769588643293_d36yhzq9l", "type": "status_changed", diff --git a/server/src/index.ts b/server/src/index.ts index 2027b952..b9086769 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -21,8 +21,9 @@ import telemetryRoutes from './routes/telemetry.js'; import metricsRoutes from './routes/metrics.js'; import tracesRoutes from './routes/traces.js'; import attachmentRoutes from './routes/attachments.js'; -import { settingsRoutes } from './routes/settings.js'; +import { settingsRoutes, syncSettingsToServices } from './routes/settings.js'; import { getTelemetryService } from './services/telemetry-service.js'; +import { ConfigService } from './services/config-service.js'; import { initBroadcast } from './services/broadcast-service.js'; import type { AgentOutput } from './services/agent-service.js'; @@ -60,10 +61,17 @@ app.use('/api/metrics', metricsRoutes); app.use('/api/traces', tracesRoutes); app.use('/api/settings', settingsRoutes); -// Initialize telemetry service (runs retention cleanup) -getTelemetryService().init().catch((err) => { - console.error('Failed to initialize telemetry service:', err); -}); +// Initialize telemetry service and sync with feature settings +(async () => { + try { + const configService = new ConfigService(); + const featureSettings = await configService.getFeatureSettings(); + syncSettingsToServices(featureSettings); + await getTelemetryService().init(); + } catch (err) { + console.error('Failed to initialize telemetry service:', err); + } +})(); // Create HTTP server const server = createServer(app); diff --git a/server/src/routes/settings.ts b/server/src/routes/settings.ts index f81a2436..0f7c59a8 100644 --- a/server/src/routes/settings.ts +++ b/server/src/routes/settings.ts @@ -1,9 +1,34 @@ import { Router, type Router as RouterType } from 'express'; import { ConfigService } from '../services/config-service.js'; +import { getTelemetryService } from '../services/telemetry-service.js'; +import { getAttachmentService } from '../services/attachment-service.js'; +import type { FeatureSettings } from '@veritas-kanban/shared'; const router: RouterType = Router(); const configService = new ConfigService(); +/** + * Sync feature settings to affected server-side services. + * Called on PATCH and on server startup. + */ +export function syncSettingsToServices(settings: FeatureSettings): void { + // Sync telemetry settings + const telemetry = getTelemetryService(); + telemetry.configure({ + enabled: settings.telemetry.enabled, + retention: settings.telemetry.retentionDays, + traces: settings.telemetry.enableTraces, + }); + + // Sync attachment limits + const attachments = getAttachmentService(); + attachments.setLimits({ + maxFileSize: settings.tasks.attachmentMaxFileSize, + maxFilesPerTask: settings.tasks.attachmentMaxPerTask, + maxTotalSize: settings.tasks.attachmentMaxTotalSize, + }); +} + // GET /api/settings/features — returns full feature settings with defaults merged router.get('/features', async (_req, res) => { try { @@ -23,6 +48,8 @@ router.patch('/features', async (req, res) => { return res.status(400).json({ error: 'Body must be a JSON object with feature settings' }); } const updated = await configService.updateFeatureSettings(patch); + // Sync settings to server-side services + syncSettingsToServices(updated); res.json(updated); } catch (error) { console.error('Error updating feature settings:', error); diff --git a/server/src/services/attachment-service.ts b/server/src/services/attachment-service.ts index ff4c69d4..3165e83c 100644 --- a/server/src/services/attachment-service.ts +++ b/server/src/services/attachment-service.ts @@ -61,6 +61,10 @@ export class AttachmentService { /** * Get attachment limits configuration */ + setLimits(limits: AttachmentLimits): void { + this.limits = limits; + } + getLimits(): AttachmentLimits { return this.limits; }