fix(days): align note time limit to 250 and keep toasts above modal blur (#1252)

The day-note 'time' field capped at 150 server-side while the dialog and shared schema allow 250, so 151-250 char notes 400'd with a confusing 'time must be 150...' message. Raise the controller and MCP limits to 250. Also lift the toast container above modal overlays so the error toast isn't rendered behind the modal's backdrop blur.
This commit is contained in:
Maurice
2026-06-19 17:56:41 +02:00
parent 87e8a44764
commit 17822aa9eb
3 changed files with 9 additions and 6 deletions
+3 -1
View File
@@ -102,7 +102,9 @@ export function ToastContainer() {
`}</style>
<div style={{
position: 'fixed', bottom: 24, left: '50%', transform: 'translateX(-50%)',
zIndex: 9999, display: 'flex', flexDirection: 'column-reverse', gap: 8,
// Above modal overlays (which sit around z-index 10000 with a backdrop-filter
// blur) so error toasts paint on top and stay legible instead of blurred behind.
zIndex: 100000, display: 'flex', flexDirection: 'column-reverse', gap: 8,
pointerEvents: 'none', maxWidth: 420, width: '100%', padding: '0 16px',
}}>
{toasts.map(toast => (
+2 -2
View File
@@ -230,7 +230,7 @@ export function registerDayTools(server: McpServer, userId: number, scopes: stri
tripId: z.number().int().positive(),
dayId: z.number().int().positive(),
text: z.string().min(1).max(500),
time: z.string().max(150).optional().describe('Time label (e.g. "09:00" or "Morning")'),
time: z.string().max(250).optional().describe('Time label (e.g. "09:00" or "Morning")'),
icon: z.string().optional().describe('Emoji icon for the note'),
},
annotations: TOOL_ANNOTATIONS_NON_IDEMPOTENT,
@@ -255,7 +255,7 @@ export function registerDayTools(server: McpServer, userId: number, scopes: stri
dayId: z.number().int().positive(),
noteId: z.number().int().positive(),
text: z.string().min(1).max(500).optional(),
time: z.string().max(150).nullable().optional().describe('Time label (e.g. "09:00" or "Morning"), or null to clear'),
time: z.string().max(250).nullable().optional().describe('Time label (e.g. "09:00" or "Morning"), or null to clear'),
icon: z.string().optional().describe('Emoji icon for the note'),
},
annotations: TOOL_ANNOTATIONS_WRITE,
+4 -3
View File
@@ -17,9 +17,10 @@ import { CurrentUser } from '../auth/current-user.decorator';
type DayNoteBody = { text?: string; time?: string; icon?: string; sort_order?: number };
// Mirrors the legacy validateStringLengths({ text: 500, time: 150 }) middleware,
// which runs BEFORE the trip-access check — so an over-long field 400s first.
const MAX_LENGTHS: Record<string, number> = { text: 500, time: 150 };
// Runs BEFORE the trip-access check, so an over-long field 400s first. The `time`
// cap matches the shared dayNote schema (max 250) and the note dialog's counter;
// it was 150 here, which rejected valid 151250 char notes with a confusing error.
const MAX_LENGTHS: Record<string, number> = { text: 500, time: 250 };
function validateLengths(body: Record<string, unknown>): void {
for (const [field, max] of Object.entries(MAX_LENGTHS)) {