fix(03): WR-03 log unconditional PUT/DELETE when If-Match etag is missing

This commit is contained in:
Lucas Berger
2026-06-09 11:04:00 -04:00
parent eed178fb39
commit 5b720ffdb8
+18
View File
@@ -65,6 +65,17 @@ export async function updateCalendarEvent(
icsString: string,
etag: string | null,
): Promise<Response> {
// WR-03: a missing etag maps to NO If-Match header → an UNCONDITIONAL PUT, which
// defeats D-08 conflict detection for exactly the rows most likely to be stale (an
// event cached before an etag was captured, or one Fastmail omitted the etag for).
// We do not block the write (it would strand the user's edit), but we make the
// unconditional-write path observable so it can be diagnosed instead of silently
// overwriting a concurrent external edit with no 412.
if (etag == null || etag === '') {
console.warn(
`[write] updateCalendarObject dispatching with NO If-Match (unconditional PUT) — conflict detection disabled for url=${calendarObjectUrl}`,
)
}
return client.updateCalendarObject({
calendarObject: {
url: calendarObjectUrl,
@@ -87,6 +98,13 @@ export async function deleteCalendarEvent(
calendarObjectUrl: string,
etag: string | null,
): Promise<Response> {
// WR-03: see updateCalendarEvent — a missing etag is an unconditional DELETE that
// bypasses D-08 conflict detection. Log so the path is observable rather than silent.
if (etag == null || etag === '') {
console.warn(
`[write] deleteCalendarObject dispatching with NO If-Match (unconditional DELETE) — conflict detection disabled for url=${calendarObjectUrl}`,
)
}
return client.deleteCalendarObject({
calendarObject: {
url: calendarObjectUrl,