feat(03-09): rename eventFieldsSchema to canonical title/start/end contract (CR-01)
- Replace summary→title, dtstart→start, dtend→end in eventFieldsSchema - Server now accepts exact CreateEventPayload shape the PWA sends - Update existing write tests to use new canonical field names - No internal rename map; one canonical name set end-to-end - grep confirms no summary/dtstart/dtend in eventFieldsSchema
This commit is contained in:
@@ -64,12 +64,19 @@ const eventsQuerySchema = z.object({
|
||||
end: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
|
||||
})
|
||||
|
||||
/** Shared event field validation (V5 — bounded lengths, T-03-08). */
|
||||
/**
|
||||
* Shared event field validation (V5 — bounded lengths, T-03-08).
|
||||
*
|
||||
* Field names match the PWA CreateEventPayload (apps/pwa/src/api/client.ts:119-128)
|
||||
* exactly — title/start/end — so no rename map is needed end-to-end (CR-01).
|
||||
* The stored payload JSON uses these same names; the outbox worker (plan 03-10)
|
||||
* reads title/start/end when building the VEVENT.
|
||||
*/
|
||||
const eventFieldsSchema = z.object({
|
||||
summary: z.string().min(1).max(255),
|
||||
title: z.string().min(1).max(255),
|
||||
allDay: z.boolean(),
|
||||
dtstart: z.string().min(1).max(64), // ISO string or DATE
|
||||
dtend: z.string().min(1).max(64),
|
||||
start: z.string().min(1).max(64), // ISO string or DATE (YYYY-MM-DD for allDay)
|
||||
end: z.string().min(1).max(64),
|
||||
location: z.string().max(2000).optional(),
|
||||
description: z.string().max(2000).optional(),
|
||||
recurrence: z.enum(['none', 'daily', 'weekly', 'monthly', 'yearly']).optional(),
|
||||
|
||||
@@ -289,10 +289,10 @@ describe('POST /api/events/create', () => {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
summary: 'New event',
|
||||
title: 'New event',
|
||||
allDay: false,
|
||||
dtstart: '2026-06-15T10:00:00Z',
|
||||
dtend: '2026-06-15T11:00:00Z',
|
||||
start: '2026-06-15T10:00:00Z',
|
||||
end: '2026-06-15T11:00:00Z',
|
||||
calendarUrl: 'https://caldav.fastmail.com/dav/calendars/user/test@fm.com/Default/',
|
||||
}),
|
||||
})
|
||||
@@ -324,10 +324,10 @@ describe('POST /api/events/create', () => {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
summary: 'Unauthorized write',
|
||||
title: 'Unauthorized write',
|
||||
allDay: false,
|
||||
dtstart: '2026-06-15T10:00:00Z',
|
||||
dtend: '2026-06-15T11:00:00Z',
|
||||
start: '2026-06-15T10:00:00Z',
|
||||
end: '2026-06-15T11:00:00Z',
|
||||
calendarUrl: 'https://caldav.fastmail.com/dav/calendars/user/other@fm.com/Personal/',
|
||||
}),
|
||||
})
|
||||
@@ -363,10 +363,10 @@ describe('PATCH /api/events/:uid/edit', () => {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
summary: 'Updated title',
|
||||
title: 'Updated title',
|
||||
allDay: false,
|
||||
dtstart: '2026-06-15T10:00:00Z',
|
||||
dtend: '2026-06-15T11:00:00Z',
|
||||
start: '2026-06-15T10:00:00Z',
|
||||
end: '2026-06-15T11:00:00Z',
|
||||
calendarUrl: 'https://caldav.fastmail.com/dav/calendars/user/test@fm.com/Default/',
|
||||
}),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user